Skip to main content

Posts

Showing posts from June, 2023

Error running script in docker container

I’m working on getting an Azure DevOps build agent running in a docker container. An error I got while trying to get this done was the following: exec ./start.sh: no such file or directory Here is the corresponding (simplified) docker file: Nothing special... Where is the fault? The problem turns out to be the start.sh file itself. I originally created it using Notepad what resulted in Windows-style line endings(CRLF).  Instead this should be Linux-style line endings(LF). There are multiple tools out there that supports this (like Notepad++) but you can also do this through VSCode. At the bottom of the editor you can find the currently used line endings style. If you click on it you can change it:

Improve the security of your GraphQL API’s - Part 5–Introspection

As a GraphQL API gives you a lot of extra power and possibilities, it also introduces some new attack vectors. Nothing prevents the user of your (web) application to open the developer console and start creating and sending other queries to your GraphQL backend. By using the authentication token already available, he/she can call your API. So without further mitigations a user can create and run any query he/she can think of. Luckily there are multiple ways to control this attack vector. I already talked about Assigning a complexity budget . Limiting the query depth . Adding authorization Persisted queries In this last post I focus on a small but important attack vector; introspection. What is introspection? GraphQL has a built-in introspection system that allows you to ask a GraphQL schema for information. This is one of the things that makes GraphQL so powerful and enables rich tooling integration. If you against the following query against your GraphQL AP...

Improve the security of your GraphQL API’s - Part 4–Persisted queries

As a GraphQL API gives you a lot of extra power and possibilities, it also introduces some new attack vectors. Nothing prevents the user of your (web) application to open the developer console and start creating and sending other queries to your GraphQL backend. By using the authentication token already available, he/she can call your API. So without further mitigations a user can create and run any query he/she can think of. Luckily there are multiple ways to control this attack vector. I already talked about Assigning a complexity budget . Limiting the query depth . Adding authorization In this post I want to focus on a specific feature supported by most GraphQL api’s: persisted queries.  When using persisted queries, a client only sends a query identifier (and optionally variables) to the server instead of the full query text. This approach provides several benefits, such as reducing bandwidth usage, makes caching a lot easier and allows extra optimizations o...

Improve the security of your GraphQL API’s - Part 3–Authorization

As a GraphQL API gives you a lot of extra power and possibilities, it also introduces some new attack vectors. Nothing prevents the user of your (web) application to open the developer console and start creating and sending other queries to your GraphQL backend. By using the authentication token already available, he/she can call your API. So without further mitigations a user can create and run any query he/she can think of. Luckily there are multiple ways to control this attack vector. I already talked about Assigning a complexity budget . Limiting the query depth . Today I will focus on authorization. Remark: I expect that you already have a kind of authentication built into your GraphQL API. So I'll ignore that part. Doing an authorization check for a REST API is easy. As every REST call maps to a specific invocation requesting specific data, you have all the information you need to check if a user is allowed to fetch a specific set of data. In ASP.NET Core...

Improve the security of your GraphQL API’s - Part 2–Depth checks

As a GraphQL API gives you a lot of extra power and possibilities, it also introduces some new attack vectors. Nothing prevents the user of your (web) application to open the developer console and start creating and sending other queries to your GraphQL backend. By using the authentication token already available, he/she can call your API. So without further mitigations a user can create and run any query he/she can think of. Luckily there are multiple ways to control this attack vector. In a first post I introduced the concept of a complexity budget . Today we have a look at query depth. What is query depth? The depth is the number of nesting levels of the query. The following query has a depth of 3: By setting a query depth, you can protect yourself against cycles in your graph leading to infinite recursive queries: How to limit the query depth? To limit the query depth, we need to update our GraphQL server configuration and set a MaxExecutionDepthRule:

Improve the security of your GraphQL API’s - Part 1 - Complexity budget

As a GraphQL API gives you a lot of extra power and possibilities, it also introduces some new attack vectors. For example, you have build some client applications consuming your GraphQL API. These applications are using a range of queries that you carefully created to implement the client functionality. These queries are well tested, optimized and don't stretch your datasource too much. But nothing prevents the user of your (web) application to open the developer console and start creating and sending other queries to your GraphQL backend. By using the authentication token already available, he/she can call your API. So without further mitigations a user can create and run any query he/she can think of. Luckily there are multiple ways to control this attack vector. In this blog series I want to share some ways on how you can improve the security of your GraphQL API's. In first post I'll focus on the concept of a complexity budget. A single GraphQL query can poten...

fsharpConf 2023

If you are an F# developer or if you are interested to learn about it, I have good news for you. fsharpConf 2023 is almost there! On June 26, you get a whole day of free online content by world-class F# experts. I’m especially looking forward to this one:   Nostalgia!

Understanding the DDD Whirlpool Process for Effective Domain Modeling

In the world of software development, aligning the software solution with the real-world problem it aims to solve is crucial for success. One powerful approach to achieving this alignment is Domain-Driven Design (DDD). At the heart of DDD lies the DDD Whirlpool process , a collaborative and iterative approach that enables teams to model the core domain effectively. The goal of the whirlpool process is to describe a way on how to iterate on the design of your domain model. The gist of this approach is to keep challenging the model.  Start by harvesting a few reference scenarios(through Event Storming or any other technique you like). Use these scenarios to create multiple possible models and quickly iterate over them. Once you end up with a workable model, you can start prototyping your model in code. Introduce another scenario into the mix and see how it impacts your current model. Keep repeating this process during the full development lifecycle.

Comments are a design tool

One of the controversial topics among developers is about writing code comments. I see a lot of developers no longer writing any kind of comments inside their codebase (with the exception of ‘TODO’ comments that can be found in almost every codebase). Side note: If any comments are found in the codebase they are typically generated afterwards, and I think with the introduction of AI in the developers toolbox, this will not get any better. These type of comments don’t add a lot value as they just emphasize the obvious and repeat the information already found in the code. When I ask developers why they don’t write any comments, the typically answer is Code should be self-explaining. And although I agree with the statement above not all information about the code could be expressed through the code alone. Another excuse I hear a lot is that developers see it as a code smell because code that needs comments is probably badly written and could be refactored to something more ...

GraphQL Code Generator–Avoid generating types that are not needed

If you are using GraphQL in your frontend(or even backend) applications I hope you are not creating all the types yourself. Thanks to the built-in schema introspection functionality, tooling can do all the heavy-lifting for you. For frontend apps I typically use the GraphQL Code Generator created and maintained by The Guild . I don’t want to use this post to explain how to use the GraphQL Code Generator; there are multiple guides available. For example here is the one for Angular. Instead I want to focus on how you can manipulate the code generation. By default, the GraphQL Code Generator will generate types for your complete schema AND specific operation types based on the provided GraphQL queries/mutations/subscriptions. How does this looks like? Here is the codegen.ts file we are using: And here is on the GraphQL query files we are using: If we execute the codegeneration, we get types for the full schema: AND types for the specific operation: Generate only ope...

Github Copilot Learning Path

I don't think I need to spend time to convince you that Github Copilot is a useful addition to your developer toolbox. The numbers speak for themselves: 46% of new code is now written by AI 55% faster overall developer productivity 74% of developers feel more focused on satisfying work So the remaining question is how to get started? The answer can be found in the brand-new GitHub Copilot Fundamentals Learning Path . The path is split into two parts: " Introduction to GitHub Copilot " and " Introduction to GitHub Copilot for Business ". In this learning path, you'll: Gain a comprehensive understanding of the distinctions between GitHub Copilot for Individuals, GitHub Copilot for Business, and GitHub Copilot X. Explore various use cases for GitHub Copilot for Business, including real-life examples showcasing how customers have leveraged it to boost their productivity. Receive step-by-step instructions on e...

WCF–WSDL not available on HTTPS

In our move to improve security in our api landscape, we configured a global redirect rule in IIS to redirect calls to HTTPS. An unforeseen consequence was that for our (old) WCF services, the WSDL endpoints were no longer accessible. When someone clicks on the WSDL link, a redirect happens but on the https endpoint no metadata is available. To fix it, I had to update the WCF configuration to explicitly enable the metadata endpoint on HTTPS:

HotChocolate–GraphQL Caching

Caching in GraphQL can be quite challenging. Due to the flexible and dynamic nature of GraphQL queries, caching can become very complex, especially when dealing with mutations or queries with different variables or arguments. Cache invalidation becomes crucial to ensure that clients receive up-to-date data when it changes on the server. This is an area where REST api’s shine. Due to the static nature of the endpoints, caching can be based on the HTTP specification. In HotChocolate caching can be done at the entity level. Therefore you need to add the HotChocolate.Caching nuget package: dotnet add package HotChocolate.Caching We also have to update the GraphQL configuration: Now we can set a [CacheControl] attribute on our queries: Or if you are using a code first approach: If we now run our query, a cache control header is emitted in the response that can be used by the browser or a CDN to cache the data accordingly:  

AsyncAPI–ASP.NET Core integration

AsyncAPI is an open source initiative with as goal to document event-driven architectures in a similar that OpenAPI documents REST APIs. If you want to get a good introduction chec k out my previous posts about AsyncAPI: AsyncApi–Share your message contracts in a language agnostic manner - Part 1 AsyncApi–Share your message contracts in a language agnostic manner - Part 2 Today I want to talk about that allows you to integrate an AsyncAPI more easily into your ASP.NET Core application; Neuroglia AsyncAPI . Let me walk you through a small example I created. First add the following nuget package to your ASP.NET Core project: Neuroglia.AsyncApi.AspNetCore.UI Now we can register the necessary configuration: Notice in the code above that I’m referring to an OrdersController class. This ASP.NET core controller publishes an event to create a new order: The library scans the provided class to find specific attributes to build up the AsyncAPI s...

How to detect heap allocations

A few weeks ago I talked about static anonymous functions and how they can help to limit the number of heap allocations when using lambdas. A colleague contacted me after this post with the question how to detect those allocations. Great question! Let me share you some ways on how to do this. Let me first give you a general answer and let’s then dive in 2 specific tools. To discover excessive allocations when using lambdas you can use any memory profiler tool and look for allocations of *__DisplayClass* or various variants of Action* and Func* . With this information, you already know what to look for. Visual Studio Performance profiler A first option to help you is the Performance Profiler in Visual Studio. Change the Build type to Release . Now go to Debug –> Performance Profiler… There are multiple profiling targets available, but we want to use the .NET Object Allocation tracking option so select this check box. Click the Start button to run...

Reduce heap allocations by using static anonymous functions

As a C# developer you got used to apply anonymous functions everywhere. Everytime you write a LINQ statement or use a lamdbda expression , you are creating an anonymous function. But what you maybe are not aware of is that anonymous functions have a performance impact and don’t come cheap : Overhead of a delegate invocation (very very small, but it does exist). 2 heap allocations if a lambda captures local variable or argument of enclosing method (one for closure instance and another one for a delegate itself). 1 heap allocation if a lambda captures an enclosing instance state (just a delegate allocation). 0 heap allocations only if a lambda does not capture anything or captures a static state. One way to limit the number of allocations is through local functions but today I want to focus on another option; using static anonymous functions . Let’s use a really simple example where static anonymous functions can help: In the example above we capture the va...

GitHub Secure Code Game

Being able to write secure code is a must have for every software developer today. As this requires different skills and a different mindset anything that can help you as a developer to get better at it is welcome! Let me introduce you the Secure Code Game from GitHub Security Lab. This hands-on secure coding training is the perfect way to sharpen your secure-coding abilities. Through the game, you need to investigate intentionally vulnerable code and find and fix the problem within it. You can clone and run the game locally or run it instantly through GitHub Codespaces. Pro tip: Use an application security testing tool like CodeQL to find all of the vulnerabilities in later stages of the game and receive helpful hints on where those problems are and how to fix them. To get started with the Secure Code Game within GitHub Skills, click here .