<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Tailor-Flow Blog Posts</title>
        <link>https://tailor.irm-flow.com/blog</link>
        <description>News and updates from the people behind Tailor-Flow</description>
        <lastBuildDate>Fri, 27 Mar 2026 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <copyright>Tailor-Flow</copyright>
        <item>
            <title><![CDATA[Post-Disclosure Report: FreeSewing v4.7.0 fixes several security issues in FreeSewing backend code]]></title>
            <link>https://tailor.irm-flow.com/blog/backend-vuln-202603</link>
            <guid>https://tailor.irm-flow.com/blog/backend-vuln-202603</guid>
            <pubDate>Fri, 27 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Earlier today, we have migrated our backend service to run our new]]></description>
            <content:encoded><![CDATA[<div class="mdx"><p>Earlier today, we have migrated our backend service to run our new
<a href="https://hub.docker.com/r/freesewing/backend/tags" target="_blank" rel="noopener noreferrer">@freesewing/backend<!-- -->:v4<!-- -->.7.0</a>
container image.</p>
<p>This minor release of FreeSewing (v4.7.0) is almost exclusively dedicated to
changes in our backend code (and flanking changes required to adapt
our frontend code to those backend changes).</p>
<p>As far as we know, we are the only people who run a production FreeSewing
backend, but the world is a big place, and we do make our Docker images freely
available for anyone to use. So:</p>
<p><strong>If you are running FreeSewing backend code, upgrade to v4.7.0 now.</strong></p>
<p>We’ll get to the details below, but let’s first set the stage.</p>
<h2 class="anchor anchorWithStickyNavbar_fF9Z" id="security-audit-of-the-freesewing-backend-code">Security audit of the FreeSewing backend code<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#security-audit-of-the-freesewing-backend-code" class="hash-link" aria-label="Direct link to Security audit of the FreeSewing backend code" title="Direct link to Security audit of the FreeSewing backend code" translate="no">​</a></h2>
<p>The sweeping range of changes rolled out today were triggered by a security
audit of our backend code by Alen Sarang Satheesh
(<a href="mailto:alensarangsatheesh@gmail.com" target="_blank" rel="noopener noreferrer">alensarangsatheesh@gmail.com</a>).</p>
<p>Alen is a freelance security researcher based in Kerala, India, who
volunteered their time to perform this audit.</p>
<p>Any security audit is a
particularly valuable contribution to make to an open source project. In this
case, it also allowed us to address some issues that we frankly are relieved to
see fixed, but more on that below.</p>
<p>We would like to thank Alen for their valuable contributions to FreeSewing.
We are also truly appreciative of the responsible disclosure, not to mention
the professional manner in which we were able to cooperate on mitigations.</p>
<h3 class="anchor anchorWithStickyNavbar_fF9Z" id="your-data-is-safe">Your data is safe<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#your-data-is-safe" class="hash-link" aria-label="Direct link to Your data is safe" title="Direct link to Your data is safe" translate="no">​</a></h3>
<p>Before we dive into the various things that came up in the audit, and the steps
we have taken to address those issues, I want to be clear about the impact:</p>
<p>While the audit did reveal issues that could have been abused to allow data
leakage or privilege escalation, we are unaware of any of these issues being
exploited. We are also unaware of any data being leaked, and we have – apart
from the accounts used by the security researcher themselves – not found any
account with a privilege level that was not what it should be.</p>
<p>In other words, while there were some real issues, those issues seem to have
remained dormant prior to the audit. The data of our users, and the
security of our systems, has thus not been impacted.</p>
<p>There is one caveat, and that is that this is as far as we can tell.
It is always hard to prove a negative, but we are confident no harm was done.</p>
<h3 class="anchor anchorWithStickyNavbar_fF9Z" id="we-made-mistakes-and-when-we-say-we-we-mean-joost">We made mistakes. And when we say we, we mean Joost<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#we-made-mistakes-and-when-we-say-we-we-mean-joost" class="hash-link" aria-label="Direct link to We made mistakes. And when we say we, we mean Joost" title="Direct link to We made mistakes. And when we say we, we mean Joost" translate="no">​</a></h3>
<p>As FreeSewing’s maintainer any problems are ultimately my responsibility.
However, in this particular case, the matter is much more clear-cut since our
backend code is not an area that typically attracts a lot of contributions.</p>
<p>So I (joost) take full responsibility. Not merely in a <em>I’m in charge so I’ll
take the blame</em> way, but in a much simpler <em>I wrote all the problematic code
myself</em> way.</p>
<p>That being said, I don’t think that assigning blame is very useful.
Instead, we will use this as an opportunity for growth.</p>
<p>We’re in a much better place today than we were last month. Lessons were
learned, short-term fixes were rolled out as soon as possible, mid-term
fixes were deployed earlier today, and we have already started working
on implementing long-term changes to ensure we are better prepared going
forward.</p>
<h2 class="anchor anchorWithStickyNavbar_fF9Z" id="summary-of-noticeable-changes">Summary of noticeable changes<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#summary-of-noticeable-changes" class="hash-link" aria-label="Direct link to Summary of noticeable changes" title="Direct link to Summary of noticeable changes" translate="no">​</a></h2>
<p>I will unpack the various changes with a security impact below, but for the
casual reader, I have summarized the changes that will be most noticable to
FreeSewing users below:</p>
<h3 class="anchor anchorWithStickyNavbar_fF9Z" id="migration-of-transactional-email-from-aws-to-scaleway">Migration of transactional email from AWS to Scaleway<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#migration-of-transactional-email-from-aws-to-scaleway" class="hash-link" aria-label="Direct link to Migration of transactional email from AWS to Scaleway" title="Direct link to Migration of transactional email from AWS to Scaleway" translate="no">​</a></h3>
<p>We have migrated our transactional email provider (transactional emails are
emails you receive to confirm a sign-up request, an email change, and so on)
from Amazon Web Services (AWS) to Scaleway.</p>
<p>This is part of our overarching migration from US-based tech companies to
EU-based alternatives. A migration that – in combination with the image
hosting changes outlined below – is now complete.</p>
<p>As a result, transactional emails from FreeSewing will be sent out from the
<strong><a href="mailto:no-reply@notifications.freesewing.eu" target="_blank" rel="noopener noreferrer">no-reply@notifications.freesewing.eu</a></strong> address. Feel free to allow-list
that address if you are concerned that our emails might get tangled in your
SPAM filter.</p>
<p>The <em>Reply-to</em> address will be <em><a href="mailto:support@freesewing.eu" target="_blank" rel="noopener noreferrer">support@freesewing.eu</a></em> so that you can still
simply reply to the email to reach a human being.</p>
<h3 class="anchor anchorWithStickyNavbar_fF9Z" id="migration-of-image-hosting-from-cloudflare-to-scaleway-with-bunny-cdn">Migration of image hosting from Cloudflare to Scaleway with Bunny CDN<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#migration-of-image-hosting-from-cloudflare-to-scaleway-with-bunny-cdn" class="hash-link" aria-label="Direct link to Migration of image hosting from Cloudflare to Scaleway with Bunny CDN" title="Direct link to Migration of image hosting from Cloudflare to Scaleway with Bunny CDN" translate="no">​</a></h3>
<p>The final service to migrate away from US-based tech companies was our image
hosting, which until today was handled by Cloudflare.</p>
<p>There was no drop-in replacement for Cloudflare’s Image API in the EU, as it is
a rather custom setup. So instead, we have decided to take matters into our
own hands, and host the images ourselves on our backend systems.</p>
<p>To protect our backend from the incurred bandwidth costs, we have furthermore
opted to deploy Bunny CDN in front to allow caching of these images.</p>
<h3 class="anchor anchorWithStickyNavbar_fF9Z" id="migration-to-uuids-to-identify-database-records">Migration to UUIDs to identify database records<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#migration-to-uuids-to-identify-database-records" class="hash-link" aria-label="Direct link to Migration to UUIDs to identify database records" title="Direct link to Migration to UUIDs to identify database records" translate="no">​</a></h3>
<p>We have migrated all monotonically increasing IDs to UUIDs to identify database
records, like users, patterns, and so on.</p>
<p>A <em>monotonically increasing ID</em> is a difficult way to say that the ID is an
ever-increasing number. The first user gets ID <code>1</code>, the second gets ID <code>2</code>,
the 100.000th user gets ID <code>100000</code> and so on.</p>
<p>Such numbers work fine, but they have the disadvantage that they are
predictable. This is especially relevant when you expose some data via API
endpoints. For example, if the backend returns (public) info about a user by
polling the <code>/users/[id]</code> endpoint, then one could just loop through numbers 1
to 100.000 to scrape data about 100.000 users.</p>
<p>To prevent this, we have added UUID fields and those are now required to pass
as identifier, which blocks such scraping attempts.</p>
<p>For the most part, this will be transparent to users. Except if you have
bookmarked any URLs that have a record ID in them.</p>
<h3 class="anchor anchorWithStickyNavbar_fF9Z" id="implemented-rate-limiting">Implemented rate-limiting<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#implemented-rate-limiting" class="hash-link" aria-label="Direct link to Implemented rate-limiting" title="Direct link to Implemented rate-limiting" translate="no">​</a></h3>
<p>To prevent brute-force attacks on authorization endpoints, and to prevent abuse
in general, we have implemented rate-limiting on our backend.</p>
<p>This should not impact regular users, but will guard against bots, scrapers,
as well as malicious use of the API, such as brute-force attempts to break
into accounts.</p>
<h2 class="anchor anchorWithStickyNavbar_fF9Z" id="vulnerabilities-found-in-the-audit">Vulnerabilities found in the audit<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#vulnerabilities-found-in-the-audit" class="hash-link" aria-label="Direct link to Vulnerabilities found in the audit" title="Direct link to Vulnerabilities found in the audit" translate="no">​</a></h2>
<p>The remainder of this report outlines the steps that we’ve taken in light of the responsible
disclosure of several security issues in the FreeSewing backend by independent
security researcher Alen Sarang Satheesh.</p>
<p><strong>Notes</strong>:</p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>All fixes are present in the latest v4.7.0 release</li>
<li>The most sensitive fixes were already fixed in the v4.6.0 release</li>
<li>Those sensitive fixes have also been backported to the v4.5.0 release</li>
<li>All times in this report are CET.</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_fF9Z" id="1-stored-xss-vulnerability">1. Stored XSS vulnerability<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#1-stored-xss-vulnerability" class="hash-link" aria-label="Direct link to 1. Stored XSS vulnerability" title="Direct link to 1. Stored XSS vulnerability" translate="no">​</a></h3>
<p>This was due to a lack of sanitization on usernames prior to embedding them
into an SVG. Given that an SVG image can also include Javascript, this opened
the door to XSS attacks by a malicious user through careful manipulation of
their username.</p>
<p>We initially fixed this – as an out-of-band quick fix – in:</p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li><a href="https://codeberg.org/freesewing/freesewing/commit/6b09a13d1bab3e4a0b91bf8ef40cb10a50aad62d" target="_blank" rel="noopener noreferrer">[backend] security: Sanitize username in SVG
output</a></li>
</ul>
<p>But given that the original use-case for this endpoint is no longer valid, we
later decided to remove this endpoint altogether:</p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li><a href="https://codeberg.org/freesewing/freesewing/commit/19a7c8548af18421ef43bb9058751ce548f0b4e2" target="_blank" rel="noopener noreferrer">[backend] chore: Remove user card
endpoint</a></li>
</ul>
<p><strong>Timeline</strong></p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Disclosure: Thursday, March 05, 2026 06:52</li>
<li>Fixed: Thursday, March 05, 2026 12:40</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_fF9Z" id="2-critical-idor-vulnerability-allowing-unauthorized-access-to-user-data">2. Critical IDOR Vulnerability Allowing Unauthorized Access to User Data<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#2-critical-idor-vulnerability-allowing-unauthorized-access-to-user-data" class="hash-link" aria-label="Direct link to 2. Critical IDOR Vulnerability Allowing Unauthorized Access to User Data" title="Direct link to 2. Critical IDOR Vulnerability Allowing Unauthorized Access to User Data" translate="no">​</a></h3>
<p>This was due to a bug where we did not enforce a check that the data being
accessed matched the authenticated user.
The bug was thankfully limited by the fact that this endpoint does not decrypt
data. So the returned data was only data that was not deemed sensitive enough
to be decrypted at rest in the first place.</p>
<p>Fixed in:</p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li><a href="https://codeberg.org/freesewing/freesewing/commit/0bf3e7b1bc89dabad650f0124f1d161412249783" target="_blank" rel="noopener noreferrer">[backend]: Enforce authenticated user ID check in account data
endpoint</a></li>
</ul>
<p><strong>Timeline</strong></p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Disclosure: Thursday, March 05, 2026 16:03</li>
<li>Fixed: Thursday, March 05, 2026 17:54</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_fF9Z" id="3-user-enumeration-via-userscard">3. User Enumeration via /users/<!-- -->:id<!-- -->/card<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#3-user-enumeration-via-userscard" class="hash-link" aria-label="Direct link to 3-user-enumeration-via-userscard" title="Direct link to 3-user-enumeration-via-userscard" translate="no">​</a></h3>
<p>As a short-term fix, we have removed this endpoint altogether:</p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li><a href="https://codeberg.org/freesewing/freesewing/commit/19a7c8548af18421ef43bb9058751ce548f0b4e2" target="_blank" rel="noopener noreferrer">[backend] chore: Remove user card
endpoint</a></li>
</ul>
<p><strong>Timeline</strong></p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Disclosure: Friday, March 06, 2026 03:53</li>
<li>Fixed: Saturday, March 07, 2026 16:29</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_fF9Z" id="4-confused-deputy-via-cloudflare-images-api">4. Confused Deputy via Cloudflare Images API<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#4-confused-deputy-via-cloudflare-images-api" class="hash-link" aria-label="Direct link to 4. Confused Deputy via Cloudflare Images API" title="Direct link to 4. Confused Deputy via Cloudflare Images API" translate="no">​</a></h3>
<p>This reported issue is that users can not only upload images, but also specify
a URL to fetch the image from. That in turn triggers a request to fetch the
image from that URL, a URL that is controlled by a potential attacker.</p>
<p>However, this is a feature of the Cloudflare Image API. FreeSewing does not
fetch the image, cloudflare does. And although this request is on our behalf,
it does not contain any privileged information.</p>
<p>Given that the root cause is in the Cloudflare codebase we can only implement
guardrails. As such, we have decided to prioritize our migration away from
Cloudflare, a migration that is now completed.</p>
<p>Also note that we have changed the way we manage images so that we only
accept uploads, and do not support fetching images from an URL.</p>
<p>Fixed in:</p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li><a href="https://codeberg.org/freesewing/freesewing/commit/10d1bcb2919509e663bae92c38bc20e043a1df4c" target="_blank" rel="noopener noreferrer">wip: Work on refactor of backend code</a></li>
<li><a href="https://codeberg.org/freesewing/freesewing/commit/f7df4ca6e333cd1ac84a88bb838a68a95d543010" target="_blank" rel="noopener noreferrer">[backend] chore: Handle image uploads after migration, support tests</a></li>
</ul>
<p><strong>Timeline</strong></p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Disclosure: Friday, March 06, 2026 03:53</li>
<li>Fixed: Friday, March 27, 2026 08:52</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_fF9Z" id="5-unauthenticated-privilege-escalation-to-site-administrator">5. Unauthenticated privilege escalation to site administrator<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#5-unauthenticated-privilege-escalation-to-site-administrator" class="hash-link" aria-label="Direct link to 5. Unauthenticated privilege escalation to site administrator" title="Direct link to 5. Unauthenticated privilege escalation to site administrator" translate="no">​</a></h3>
<p>This reported issue exploits the special exemptions carved out for unit tests in the
code base. To trigger the exploit, it leverages an operator precedence bug in
the code that is used to test whether a particular request is part of a unit
test. Once the system is tricked into believing it is a test, it then goes on
to exploit some of the logic that only applies to the unit tests:</p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Allowing users to sign up with any role</li>
<li>Forgoing the need for email confirmation</li>
</ul>
<p>When you string this all together, the end result is that an attacker can
create an admin account by manipulating the request to the signup endpoint.</p>
<p>This one is real bad, although it does have the advantage that it allows us to
check for unexpected accounts with an admin role in the database.
We found 8 of them, all created close to each other, and we confirmed that they
were all created by the researcher who reported the issue.</p>
<p>We initially fixed this – as a production hot-fix – by making the isTest()
method always return false.</p>
<p>We then proceeded to remove all unit-test specific code paths from the code base:</p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li><a href="https://codeberg.org/freesewing/freesewing/commit/2a6c317d05f94cd04035a415133b3e21e34f8112" target="_blank" rel="noopener noreferrer">[backend] chore: Remove all unit-test code
paths</a></li>
</ul>
<p>Today, we no longer have any special code paths for unit tests.</p>
<p><strong>Timeline</strong></p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Disclosure: Friday, March 06, 2026 15:55</li>
<li>Fixed: Friday, March 06, 2026 16:28</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_fF9Z" id="6-wildcard-cors-configuration">6. Wildcard CORS configuration<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#6-wildcard-cors-configuration" class="hash-link" aria-label="Direct link to 6. Wildcard CORS configuration" title="Direct link to 6. Wildcard CORS configuration" translate="no">​</a></h3>
<p>The FreeSewing backend accepts cross-origin resource sharing (CORS) requests
from any site.</p>
<p>This is by design. The FreeSewing backend API is a public, open API that
explicitly supports third-party integrations.</p>
<p>The risks of liberal CORS headers are predominantly tied to browser-managed
credentials – such as cookies, basic authentication or TLS client certificates
– as they are automatically included in requests.
But the FreeSewing backend relies on JWT bearer tokens, which need to be
explicitly set.</p>
<p>As this CORS configuration is by design and stems from our commitment to
openness, we do not want to change it.</p>
<p>However, while we were addressing the various issues in this report, we
have decided to lock down CORS as a cautionary measure. Even if doing so
broke user’s development environments, as well as community-lead initiatives
that publish alternative FreeSewing frontends with early-access designs.</p>
<p>Now that all issues are resolved, we have gone back to be an open API that
can be used by anyone.</p>
<p><strong>Timeline</strong></p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Disclosure: Friday, March 06, 2026 03:53</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_fF9Z" id="7-jwt-misconfiguration">7. JWT Misconfiguration<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#7-jwt-misconfiguration" class="hash-link" aria-label="Direct link to 7. JWT Misconfiguration" title="Direct link to 7. JWT Misconfiguration" translate="no">​</a></h3>
<p>This reported issue bundles two different points:</p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Information Disclosure</li>
<li>Excessive Token Expiry</li>
</ul>
<p>The information disclosure report points out that the inclusion of
<code>http://localhost:3000</code> in the token leaks information about the internet
configuration. While that does not grant any access as-such, it provides
<em>valuable reconnaissance data</em>.</p>
<p>We’d like to point out that as an open source project with a commitment to
transparency, this information is available in our repository for anyone who
takes an interest in how things work under the hood.</p>
<p>As for the <em>excessive token expiry</em>, the current expiration is 28 days.
Shortening it, especially significantly shortening it, would impose a real
inconvenience cost on all of our regular users for little gain in security
posture. An attacker gaining access to a token can do damage in minutes. No
amount of shortening the length of the token is an effective strategy to guard
against that.</p>
<p>There are of course the issues that are inherent in the choice for JWT,
in particular the inability to revoke them. As such, there is certainly
room for improvement here, and as such we have added <a href="https://codeberg.org/freesewing/freesewing/issues/778" target="_blank" rel="noopener noreferrer">the implementation of
refresh token rotation to our
todo-list</a> so that we
can use short-lived tokens without sacrificing our user’s convenience.</p>
<p>As this would require a good bit of engineering, we have added it as
a todo, but we have not completed (or even started) that work at this time.</p>
<p><strong>Timeline</strong></p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Disclosure: Friday, March 06, 2026 03:53</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_fF9Z" id="8-magic-link-account-takeover-via-token-leakage">8. Magic link account takeover via token leakage<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#8-magic-link-account-takeover-via-token-leakage" class="hash-link" aria-label="Direct link to 8. Magic link account takeover via token leakage" title="Direct link to 8. Magic link account takeover via token leakage" translate="no">​</a></h3>
<p>FreeSewing offers a ‘magic link’ sign-in mechanism. Since all the information
to sign-in if included in the URL, this allows anyone who has access to the URL
to sign in as the user in question.</p>
<p>This is not a surprise as-such, that’s the way it’s supposed to work.
It is also worth pointing out that once-consumed, these URLs will no longer
function.</p>
<p>The report suggests to implement strict referrer-policy headers to avoid the URL
<em>leaking</em> during pageload in the referrer header when loading third-party
resources.</p>
<p>While that does provide some limits to the URL leaking out, it does not address
other places where the URL can leak, such as intermediate proxies and access
logs.</p>
<p>As such, we feel the better approach here is to move away from having all
information contained in the URL, and instead require a flanking one-time code
that we would include in the email. We had initially <a href="https://codeberg.org/freesewing/freesewing/issues/779" target="_blank" rel="noopener noreferrer">added this more
in-depth defense to our
todo-list</a>. However,
we have since implemented it, and it is part of the v4.7.0 release.</p>
<p>Fixed in:</p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li><a href="https://codeberg.org/freesewing/freesewing/commit/10d1bcb2919509e663bae92c38bc20e043a1df4c" target="_blank" rel="noopener noreferrer">wip: Work on refactor of backend code</a></li>
</ul>
<p><strong>Timeline</strong></p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Disclosure: Friday, March 06, 2026 03:53</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_fF9Z" id="9-sensitive-data-over-exposure">9. Sensitive Data Over-Exposure<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#9-sensitive-data-over-exposure" class="hash-link" aria-label="Direct link to 9. Sensitive Data Over-Exposure" title="Direct link to 9. Sensitive Data Over-Exposure" translate="no">​</a></h3>
<p>The endpoint returning user’s account data includes data that – according to
the report – should not be shared with the user. Specifically:</p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>ehash: An <em>unsalted</em> hash of the user’s current email address</li>
<li>ihash: An <em>unsalted</em> hash of the user’s initial email address</li>
<li>intial: The user’s initial email address</li>
<li>mfaEnabled: Whether or not MFA is enabled on the account</li>
<li>passwordType: The underlying type of password – to support migrating old accounts</li>
</ul>
<p>We have removed ehash, ihash, intitial, and passwordType from the returned data.
We did not remove mfaEnabled as we need it to let the user know whether they
have MFA enabled or not.</p>
<p>As the report mentions that ehash and ihash are the <em>unsalted</em> hash, we feel
we need to clarify their use.</p>
<p>As we practice encryption-at-rest, we cannot do things that
one would take for granted, like finding a user based on their email address,
as that data is encrypted.</p>
<p>This is where ehash comes in. It is a hash of the email address, which allows
us to search for a user based on (a hash of) their email address. While it is
true that this allows an attacker with access to the account data to confirm
the email address, an attacker with access to the account data already has the
email address, so this seems like a moot point.</p>
<p>The ihash field serves the same purpose as the ehash field, but for the
‘initial’ field. This field holds the email that the account was initially
created with. The report flags this as a risk, saying that users who want to
change their email address to a <em>burner address</em> will still have their initial
email in their account data, thus undermining their anonymity.</p>
<p>While that is the case, if you want an anonymous account, you should create one
with a burner email address, and not turn a nominative account into an
anonymous one. In addition, the reason we keep the initial/ihash fields and do
not allow users to change them is to protect against account take-over and
resolve disputes about account ownership. In practical terms, when an attacker
succeeds in taking over an account and change their email address, the initial
field allows us to know what email address was used to initially create the
account.</p>
<p><strong>Timeline</strong></p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Disclosure: Friday, March 06, 2026 03:53</li>
<li>Fixed: Saturday, March 07, 2026 16:29</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_fF9Z" id="10-no-rate-limiting-on-any-endpoint">10. No rate-limiting on any endpoint<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#10-no-rate-limiting-on-any-endpoint" class="hash-link" aria-label="Direct link to 10. No rate-limiting on any endpoint" title="Direct link to 10. No rate-limiting on any endpoint" translate="no">​</a></h3>
<p>The FreeSewing backend does not implement rate-limiting.</p>
<p>We have not implemented rate limiting because we have not observed abuse
patterns that would necessitate this. Still, we recognize it is good advice.</p>
<p>We had initially <a href="https://codeberg.org/freesewing/freesewing/issues/782" target="_blank" rel="noopener noreferrer">added rate limiting to our todo
list</a>.
But we have since implemented it and it is part of the v4.7.0 release.</p>
<p>Fixed in:</p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li><a href="https://codeberg.org/freesewing/freesewing/commit/490002cede8e3a3a84c62f102cdb24a76285e435" target="_blank" rel="noopener noreferrer">[backend] chore: Hardening and rate-limiting</a></li>
</ul>
<p><strong>Timeline</strong></p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Disclosure: Friday, March 06, 2026 03:53</li>
<li>Fixed: Friday, March 27, 2026 08:52</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_fF9Z" id="11-encryption-key-reused-as-jwt-secret">11. Encryption key reused as JWT secret<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#11-encryption-key-reused-as-jwt-secret" class="hash-link" aria-label="Direct link to 11. Encryption key reused as JWT secret" title="Direct link to 11. Encryption key reused as JWT secret" translate="no">​</a></h3>
<p>The same key is used for AES encryption and JWT signing.
A compromise of the key would compromise both encryption and authentication
tokens.</p>
<p>A compromise of FreeSewing backend encryption would be a significant incident.
It seems difficult to imagine a scenario where the encryption key would be
compromised but the JWT signing key would somehow not be. As such, this risk
feels theoretic.</p>
<p>Nevertheless, we have implemented the suggested change and created a different
key for JWT signing.</p>
<p>Fixed in:</p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>
<p><a href="https://codeberg.org/freesewing/freesewing/commit/490002cede8e3a3a84c62f102cdb24a76285e435" target="_blank" rel="noopener noreferrer">[backend] chore: Hardening and rate-limiting</a>
<strong>Timeline</strong></p>
</li>
<li>
<p>Disclosure: Friday, March 06, 2026 03:53</p>
</li>
<li>
<p>Fixed: Friday, March 27, 2026 08:52</p>
</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_fF9Z" id="12-missing-common-security-headers">12. Missing common security headers<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#12-missing-common-security-headers" class="hash-link" aria-label="Direct link to 12. Missing common security headers" title="Direct link to 12. Missing common security headers" translate="no">​</a></h3>
<p>The following headers are listed in the report as missing:</p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Strict-Transport-Security (HSTS)</li>
<li>Content-Security-Policy (CSP)</li>
<li>X-Content-Type-Options</li>
<li>X-Frame-Options</li>
<li>Permissions-Policy</li>
</ul>
<p>Most of these headers are relevant in the context of an HTML page.
As a REST API the returns <code>application/json</code> several of these are
not relevant.</p>
<p>The ones that are:</p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>X-Content-Type-Options: This has minimal practical impact for an API that
always returns JSON, but adding it is also not a problem. So we will.</li>
<li>Strict-Transport-Security (HSTS): This enforces TLS. Note that we already
enforce TLS server-side by redirecting all HTTP requests to HTTPS. However,
as HSTS impacts the client side, it would be an improvement to add it. That
being said, adding this to the backend code would also impact the developer
experience as running the backend API in development mode on localhost would
also require a TLS certificate. So, rather than add this to the backend code,
we will add these headers at the reverse proxy level.</li>
</ul>
<p>We have added these headers on our reverse proxy.</p>
<p><strong>Timeline</strong></p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Disclosure: Friday, March 06, 2026 03:53</li>
<li>Fixed: Sunday, March 08, 2026 09:22</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_fF9Z" id="13-account-modification-without-re-authentication">13. Account modification without re-authentication<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#13-account-modification-without-re-authentication" class="hash-link" aria-label="Direct link to 13. Account modification without re-authentication" title="Direct link to 13. Account modification without re-authentication" translate="no">​</a></h3>
<p>Once logged in, users can change account settings such as email, username, bio,
and password without re-entering their password.</p>
<p>Note that changing MFA settings does require re-authentication, and email
changes do require email confirmation. What account properties require
re-authentication is a choice to be made. We do not feel that re-authentication
is required to change one’s bio or username.</p>
<p>Requiring the password to change one’s password would be a problem as we do
not create a password for FreeSewing users when they sign up, instead relying
on a <em>magic link</em> and confirmation code.</p>
<p>Users <em>can</em> set a password if they do choose, but asking for a (non-existing)
password at this time would break that.</p>
<p>Still, we take note of the remark. Support for passkeys is on our
roadmap, so we will re-visit this matter at that time.</p>
<p><strong>Timeline</strong></p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Disclosure: Friday, March 06, 2026 03:53</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_fF9Z" id="14-no-csrf-protection">14. No CSRF protection<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#14-no-csrf-protection" class="hash-link" aria-label="Direct link to 14. No CSRF protection" title="Direct link to 14. No CSRF protection" translate="no">​</a></h3>
<p>CSRF (cross-site request forgery) tokens are a mitigation for cookie-based
session authentication, where the browser automatically sends the
authentication with the request.</p>
<p>As our backend uses JWT bearer tokens, it sidesteps CSRF entirely.
As such, CSRF protection is not relevant in our case.</p>
<p><strong>Timeline</strong></p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Disclosure: Friday, March 06, 2026 03:53</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_fF9Z" id="15-universal-input-sanitization-failure">15. Universal input sanitization failure<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#15-universal-input-sanitization-failure" class="hash-link" aria-label="Direct link to 15. Universal input sanitization failure" title="Direct link to 15. Universal input sanitization failure" translate="no">​</a></h3>
<p>User provided data is stored without sanitation.</p>
<p>This is about data such as usernames, bio, titles of bookmarks and so on.</p>
<p>Note that this data is properly escaped to handle SQL-injection and is escaped
in FreeSewing’s React-based frontend. As such, the issue is predominantly a
a risk for future or non-official API clients.</p>
<p>Still, we should not let a footgun like this linger and we will take this
remark into account for future refactoring of our backend code – an effort we
have already started, having recently removed the Prisma dependency in favor of
native NodeJS sqlite bindings.</p>
<p><strong>Timeline</strong></p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Disclosure: Friday, March 06, 2026 03:53</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_fF9Z" id="16-sequentialpredictable-user-ids">16. Sequential/Predictable user IDs<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#16-sequentialpredictable-user-ids" class="hash-link" aria-label="Direct link to 16. Sequential/Predictable user IDs" title="Direct link to 16. Sequential/Predictable user IDs" translate="no">​</a></h3>
<p>FreeSewing uses numeric account IDs which allows account enumeration.</p>
<p>As a short-term fix, we have removed the profile access endpoint:</p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li><a href="https://codeberg.org/freesewing/freesewing/commit/f8b2e388c7bd38a0a7a72c452b09bcbefcc495b8" target="_blank" rel="noopener noreferrer">[backend] fix: Disable anonymous profile data
endpoint</a></li>
</ul>
<p>As a more in-depth defence, we have migrated to UUIDv4 as record identifiers.
As this required changes in many different parts of the codebase,
we have opted to forego a list of relevant commits as it would be too long.</p>
<p><strong>Timeline</strong></p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Disclosure: Friday, March 06, 2026 03:53</li>
<li>Fixed: Friday, March 27, 2026 08:52</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_fF9Z" id="17-account-spoofing-via-record-cloning">17. Account spoofing via record cloning<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#17-account-spoofing-via-record-cloning" class="hash-link" aria-label="Direct link to 17. Account spoofing via record cloning" title="Direct link to 17. Account spoofing via record cloning" translate="no">​</a></h3>
<p>A bug in the cloning logic for patterns, measurements sets, and curated
measurements sets failed to re-assign ownership of the data to the user
initiated the clone operation. This caused data to be stored in the user who
originally owned the data, rather than the user who initiated the clone.</p>
<p>Fixed in:</p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li><a href="https://codeberg.org/freesewing/freesewing/commit/f85b1602abc2df462d9ac2ae604d2961647a1d44" target="_blank" rel="noopener noreferrer">[backend] chore: Port patterns to UUIDs</a></li>
</ul>
<p><strong>Timeline</strong></p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Disclosure: Sunday, March 08, 2026 16:18</li>
<li>Fixed: Sunday, March 08, 2026 16:23</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_fF9Z" id="18-authorization-bypass-vulnerability-due-to-insecure-oidc-session-handling">18. Authorization Bypass Vulnerability due to insecure OIDC session handling<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#18-authorization-bypass-vulnerability-due-to-insecure-oidc-session-handling" class="hash-link" aria-label="Direct link to 18. Authorization Bypass Vulnerability due to insecure OIDC session handling" title="Direct link to 18. Authorization Bypass Vulnerability due to insecure OIDC session handling" translate="no">​</a></h3>
<p>Due to an incorrect handling of the OIDC state, it was possible for an OIDC
flow initiated by user A to be completed by user B.
This opens the door to tricking users to complete an OIDC flow they did not
initiate.</p>
<p>The OIDC flow is (only) used to authenticate users on the FreeSewing forum, as
such the scope was limited to the forum.</p>
<p>Fixed in:</p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li><a href="https://codeberg.org/freesewing/freesewing/commit/39185bc470b7c5d1457173705cfa230cd7229ef1" target="_blank" rel="noopener noreferrer">[backend] security: Refactor OIDC implementation</a></li>
</ul>
<p><strong>Timeline</strong></p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Disclosure: Monday, March 09, 2026 05:53</li>
<li>Fixed: Monday, March 09, 2026 07:26</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_fF9Z" id="19-no-upper-bound-on-api-key-expiry">19. No upper bound on API key expiry<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#19-no-upper-bound-on-api-key-expiry" class="hash-link" aria-label="Direct link to 19. No upper bound on API key expiry" title="Direct link to 19. No upper bound on API key expiry" translate="no">​</a></h3>
<p>A bug in the lookup for the maximum expiry of user-created API keys allowed
users to create API keys that expire so far in the future they are de-facto
never expiring.</p>
<p>This was a minor issue, caused by a typo in the configuration lookup for the
maximum expiry.</p>
<p>Fixed in:</p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li><a href="https://codeberg.org/freesewing/freesewing/commit/91fe00e6c1728dcd0cbf63ccec5c2e90bd1b0a3b" target="_blank" rel="noopener noreferrer">[backend] fix: Incorrect config lookup for api key max expiry</a></li>
</ul>
<p><strong>Timeline</strong></p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Disclosure: Tuesday, March 10, 2026 17:59</li>
<li>Fixed: Wednesday, March 11, 2026 08:19</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_fF9Z" id="summary">Summary<a href="https://tailor.irm-flow.com/blog/backend-vuln-202603#summary" class="hash-link" aria-label="Direct link to Summary" title="Direct link to Summary" translate="no">​</a></h2>
<p>The security research performed by Alen Sarang Satheesh revealed a range of
security issues in the FreeSewing backend code, including a particularly
dangerous admin account creation bug, as well as a cross-account data access
bug.</p>
<p>Other issues were less problematic, and some were not particularly relevant to
our specific setup. But overall, the research was extremely valuable.</p>
<p>We have implemented fixes for the most urgent matters as soon as possible,
and have worked over the last three weeks to implement those fixes
that required a more substantial change in approach.
We have also implemented the various recommendations insofar as they were
relevant.</p>
<p>While we have strived to do all this with as little disruption as possible
to our users, the last couple of weeks we have had an increased error rate
due to the temporary fixes we had put in place prioritizing security over
functionality or user experience.</p>
<p>We would like to thank Alen once again for their excellent work, and we
would also like to thank our users for their continued trust in FreeSewing.</p>
<p>If you’ve read this far, you will have realized that we are not perfect.
But we do our best, and you can count on us to be honest and open
when we get it wrong.</p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[FreeSewing 4.6 brings Crux, the climbing pants]]></title>
            <link>https://tailor.irm-flow.com/blog/v4-6-0-crux</link>
            <guid>https://tailor.irm-flow.com/blog/v4-6-0-crux</guid>
            <pubDate>Sun, 08 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[We have just released FreeSewing v4.6, which comes with a new design (crux)]]></description>
            <content:encoded><![CDATA[<div class="mdx"><p>We have just released FreeSewing v4.6, which comes with a new design (crux)
and a new plugin (plugin-transform), as well as a bunch of other incremental
improvements. Check <a href="https://codeberg.org/freesewing/freesewing/src/branch/develop/CHANGELOG.md" target="_blank" rel="noopener noreferrer">our CHANGELOG</a> for all details, or read on for
the highlights.</p>
<h2 class="anchor anchorWithStickyNavbar_fF9Z" id="crux-climbing-pants">Crux Climbing pants<a href="https://tailor.irm-flow.com/blog/v4-6-0-crux#crux-climbing-pants" class="hash-link" aria-label="Direct link to Crux Climbing pants" title="Direct link to Crux Climbing pants" translate="no">​</a></h2>
<p>Wouter signed for this design, the <a href="https://tailor.irm-flow.com/designs/crux/">Crux Climbing pants</a>.
He writes:</p>
<blockquote>
<p>I’ve been wanting to make pants that I can use while hiking or climbing.
Because all the other pants I wear I make myself. Just for some reason, I
have not made this type of pants. And it’s been bothering me that I still
have to go to the store to buy them.</p>
<p>I used cornelius as a base, and then quickly started to tweak to something
that works well for the new task. Since I have quite some hiking pants, and
have seen numerous ones being offered, I tried to incorporate some of the
features I see in commerical ones.</p>
<p>There are different pocket options, the ability to have the pockes be on the
inside or outside, cargo or patch, etc.</p>
<p>An option to make articulated knees is included, as are different hem and
waistband options.</p>
<p>These work well with medium/light bottomweight woven fabric with a slight
stretch along the weft. But you can make them with any fabric option you
prefer.</p>
<p>Wouter</p>
</blockquote>
<div class="theme-admonition theme-admonition-tip admonition_IZjC alert alert--success"><div class="admonitionHeading_uVvU"><span class="admonitionIcon_HiR3"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>Learn more</div><div class="admonitionContent_bl22"><ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Discover this design at <a href="https://tailor.irm-flow.com/designs/crux/">/designs/crux</a>.</li>
<li>Or <a href="https://tailor.irm-flow.com/editor/#s=%7B%22design%22%3A%22crux%22%2C%22view%22%3A%22measurements%22%7D">discover Crux in the pattern editor</a></li>
</ul></div></div>
<h2 class="anchor anchorWithStickyNavbar_fF9Z" id="the-new-transform-plugin">The new transform plugin<a href="https://tailor.irm-flow.com/blog/v4-6-0-crux#the-new-transform-plugin" class="hash-link" aria-label="Direct link to The new transform plugin" title="Direct link to The new transform plugin" translate="no">​</a></h2>
<p>We also have a new plugin, named plugin-transform that brings <a href="http://localhost:3000/reference/macros/transform/" target="_blank" rel="noopener noreferrer">the <code>transform</code>
macro</a>.</p>
<p>It allows you to apply a <em>transform</em> – so either scale, rotate, or translate
– to one or more points or paths. Similar to what you can do in CSS or SVG.</p>
<h2 class="anchor anchorWithStickyNavbar_fF9Z" id="backend-changes">Backend changes<a href="https://tailor.irm-flow.com/blog/v4-6-0-crux#backend-changes" class="hash-link" aria-label="Direct link to Backend changes" title="Direct link to Backend changes" translate="no">​</a></h2>
<p>This release also includes some changes to our backend, including some changes
that will cause <em>some breakage</em>. This is part of an ongoing effort and we will
have more to share on this in the near future.</p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Announcing the FreeSewing Library]]></title>
            <link>https://tailor.irm-flow.com/blog/v4-5-0-library</link>
            <guid>https://tailor.irm-flow.com/blog/v4-5-0-library</guid>
            <pubDate>Sun, 22 Feb 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[We have just released FreeSewing v4.5. It's a big release with a plenty of]]></description>
            <content:encoded><![CDATA[<div class="mdx"><p>We have just released FreeSewing v4.5. It’s a big release with a plenty of
under-the-hood changes.</p>
<p>As usual, <a href="https://codeberg.org/freesewing/freesewing/src/branch/develop/CHANGELOG.md#4-5-0-2026-02-21" target="_blank" rel="noopener noreferrer">our changelog</a> has all the details of what went in this release.
Here, we’ll focus on the main item: The FreeSewing Library.</p>
<h2 class="anchor anchorWithStickyNavbar_fF9Z" id="the-freesewing-library">The FreeSewing Library<a href="https://tailor.irm-flow.com/blog/v4-5-0-library#the-freesewing-library" class="hash-link" aria-label="Direct link to The FreeSewing Library" title="Direct link to The FreeSewing Library" translate="no">​</a></h2>
<p>Ever since the release of version 3 of FreeSewing, we’ve supported the ability
to freely combine different parts from existing designs as part of a new design.</p>
<p>It was – and remains – a good idea and a feature we absolutely want to support.
But over time, we’ve seen that in practice, this can sometimes lead to problems:</p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>It takes careful design to ensure a part is created that can stand on its own
without making assumptions about the design it is used in</li>
<li>Pulling in a part from a design as a dependency often brings along a bunch of
stuff of that design we are not interested in</li>
</ul>
<p>People have also been extracting parts from designs that were never intended to
be used outside of that design. This often required <em>a bit of a hack</em> to make
it work, which saddles us with technical debt and code that is difficult to
maintain.</p>
<p>So this created tension between the set of features we are committed to support,
and the way those features sometimes were used which caused concerns about
maintainability.</p>
<p>So, after some discussion on the matter, we’ve decided the create <em>the
FreeSewing Library</em>. It is <em>just another design</em> named
<a href="https://tailor.irm-flow.com/designs/library/">Library</a> but it’s <em>raison d’être</em> is not as a stand-alone
design, but rather as a <a href="https://tailor.irm-flow.com/designs/library/" title="Library" class="tw:text-secondary tw:hover:underline tw:hover:cursor-pointer tw:underline tw:decoration-dashed tw:hover:decoration-3 tw:hover:decoration-solid tw:hover:pointer-help">Library</a> for commonly used parts that are explicitly
created to be re-used in other designs.</p>
<h2 class="anchor anchorWithStickyNavbar_fF9Z" id="how-does-it-work">How does it work?<a href="https://tailor.irm-flow.com/blog/v4-5-0-library#how-does-it-work" class="hash-link" aria-label="Direct link to How does it work?" title="Direct link to How does it work?" translate="no">​</a></h2>
<p>This works just the same as any other inheritance that we’ve been using before.
It’s really just a matter of creating a growing body of ready to be reused parts
which people can use.</p>
<p>That being said, we’ve made a bunch of changes under the hood to make sure this
works in a way that is elegant. Such as allowing to reuse a part more than once
with different settings, or the ability to scope design options to a specific part,
rather than to the entire pattern.</p>
<h2 class="anchor anchorWithStickyNavbar_fF9Z" id="inheritance-is-here-to-stay">Inheritance is here to stay<a href="https://tailor.irm-flow.com/blog/v4-5-0-library#inheritance-is-here-to-stay" class="hash-link" aria-label="Direct link to Inheritance is here to stay" title="Direct link to Inheritance is here to stay" translate="no">​</a></h2>
<p>This does not mean that it is now <em>bad</em> to inherit parts from designs that are
not the library. In particular, extending blocks into more fully featured patterns
is not going anywhere.</p>
<p>What we wanted to avoid is a growing number of ad-hoc dependencies that some
designers were creating, which makes it really hard to maintain the software.
The people who maintain our foundational blocks are typically seasoned
FreeSewing contributors, which is a good thing as every change to these blocks
has ripple effect that impact many other designs.</p>
<p>By perhaps somewhat overeagerly re-using parts from various designs that were
never intended for that, other designs (and designers) are now also faced with
the delicate balance of maintaining not merely a design, but rather a library
that is used by other designs.</p>
<p>So, we figured we would instead formalize this and create a proper library.
The message we want to send to designers is:</p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Inherit from our blocks, it’s what they are there for</li>
<li>Reuse what’s in our library as much as you want</li>
<li>Reach out to us before reusing parts from other designs</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_fF9Z" id="whats-in-the-library">What’s in the library<a href="https://tailor.irm-flow.com/blog/v4-5-0-library#whats-in-the-library" class="hash-link" aria-label="Direct link to What’s in the library" title="Direct link to What’s in the library" translate="no">​</a></h2>
<p>We wanted to take this one step at a time. So for now, the library holds:</p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>A <code>rectangle</code> part. This is what we initially used to test-drive our solution.</li>
<li>A <code>sleeve</code> part. This is the sleeve that was originally in the Brian block.</li>
<li>A <code>two-part-sleeve</code> part. This is a combo of the two-part sleeve that was originally in the Bent block.</li>
<li>A <code>topsleeve</code> part. This is the top part of the two-part sleeve.</li>
<li>A <code>undersleeve</code> part. This is the under part of the two-part sleeve.</li>
</ul>
<p>This is a <em>modest</em> start, as there’s obviously plenty of other things that
would make a lot of sense in the library, such as collars, or cuffs, pockets,
waistbands, and so on.</p>
<p>However, we wanted to start small and iron out any kinks before further
extending the use of the library. You’ll also notice that merely by moving the
various sleeves to the library, we already had to overhaul two foundational
blocks, so it’s not like this was a small change.</p>
<p>Going forward, we will be looking to move more common parts into the library,
with the ultimate goal that nobody should need to reinvent the wheel.</p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[FreeSewing 4.4 brings Sophie, a slip dress design]]></title>
            <link>https://tailor.irm-flow.com/blog/v4-4-0-sophie</link>
            <guid>https://tailor.irm-flow.com/blog/v4-4-0-sophie</guid>
            <pubDate>Thu, 06 Nov 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[FreeSewing v4.4 has been released, and with it comes a new design: Sophie.]]></description>
            <content:encoded><![CDATA[<div class="mdx"><p>FreeSewing v4.4 has been released, and with it comes a new design: Sophie.</p>
<h2 class="anchor anchorWithStickyNavbar_fF9Z" id="sophie-slip-dress">Sophie Slip Dress<a href="https://tailor.irm-flow.com/blog/v4-4-0-sophie#sophie-slip-dress" class="hash-link" aria-label="Direct link to Sophie Slip Dress" title="Direct link to Sophie Slip Dress" translate="no">​</a></h2>
<p>Sophie is <em>a FreeSewing pattern for a slip dress</em> designed and coded by
JennaBarbara. Her <a href="https://codeberg.org/freesewing/freesewing/pulls/606" target="_blank" rel="noopener noreferrer">first ever open source
contribution</a> <!-- -->🎉<!-- -->.</p>
<p>Here’s what she had to say about it:</p>
<blockquote>
<p>I like making and wearing slip dresses. They’re easy to put together, can be
suitable for various levels of formality (from pyjamas to formalwear), and
can be made from many different fabrics.</p>
<p>I decided I wanted to try drafting a slip using the Freesewing developer
tools instead of paper, and the Sophie design was the result.</p>
</blockquote>
<div class="theme-admonition theme-admonition-tip admonition_IZjC alert alert--success"><div class="admonitionHeading_uVvU"><span class="admonitionIcon_HiR3"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>Learn more</div><div class="admonitionContent_bl22"><ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Discover this design at <a href="https://tailor.irm-flow.com/designs/sophie/">/designs/sophie</a>.</li>
<li>Or <a href="https://tailor.irm-flow.com/editor/#s=%7B%22design%22%3A%22sophie%22%2C%22view%22%3A%22measurements%22%7D">discover Sophie in the pattern editor</a></li>
</ul></div></div></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[FreeSewing 4.3 adds our new Percy design]]></title>
            <link>https://tailor.irm-flow.com/blog/v4-3-0-percy</link>
            <guid>https://tailor.irm-flow.com/blog/v4-3-0-percy</guid>
            <pubDate>Tue, 30 Sep 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[FreeSewing v4.3 has been released, and with it comes a new design: Percy.]]></description>
            <content:encoded><![CDATA[<div class="mdx"><p>FreeSewing v4.3 has been released, and with it comes a new design: Percy.</p>
<h2 class="anchor anchorWithStickyNavbar_fF9Z" id="percy-puffy-pants">Percy Puffy Pants<a href="https://tailor.irm-flow.com/blog/v4-3-0-percy#percy-puffy-pants" class="hash-link" aria-label="Direct link to Percy Puffy Pants" title="Direct link to Percy Puffy Pants" translate="no">​</a></h2>
<p>Percy is <em>a FreeSewing pattern for fall-front puffy shorts</em> designed by Gawain who had the following to say about it:</p>
<blockquote>
<p>I wanted a pair of shorts that had a fall front with a double row of buttons, a front pleat, and a flared
bottom edge gathered down into a cuff. So I made one!</p>
<p>The front construction is a simplified, not-especially-accurate rendition of the fall front breeches
common in the late 1700s and early 1800s. Most modern interpretations of this style have ornamental
buttons and an elastic waistband or a hidden side zipper, but I wanted these ones to be real.</p>
<p>This pattern can be short or long, flared or unflared, and cuffed or uncuffed, so you can produce
quite a wide variety of different pants. Only the fall front construction and the pockets are non-optional.</p>
</blockquote>
<div class="theme-admonition theme-admonition-tip admonition_IZjC alert alert--success"><div class="admonitionHeading_uVvU"><span class="admonitionIcon_HiR3"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>Learn more</div><div class="admonitionContent_bl22"><ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Discover this design at <a href="https://tailor.irm-flow.com/designs/percy/">/designs/percy</a>.</li>
<li>Or <a href="https://tailor.irm-flow.com/editor/#s=%7B%22design%22%3A%22percy%22%2C%22view%22%3A%22measurements%22%7D">discover Percy in the pattern editor</a></li>
</ul></div></div></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[FreeSewing 4.2 adds four new designs: the Devon and Jett jackets, and the Sarah and Sunny skirts]]></title>
            <link>https://tailor.irm-flow.com/blog/announcing-devon-jett-sarah-sunny</link>
            <guid>https://tailor.irm-flow.com/blog/announcing-devon-jett-sarah-sunny</guid>
            <pubDate>Sat, 16 Aug 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[FreeSewing v4.2 is out, and it brings four new designs: Devon is a denim]]></description>
            <content:encoded><![CDATA[<div class="mdx"><p>FreeSewing v4.2 is out, and it brings four new designs: <a href="https://tailor.irm-flow.com/designs/devon/" title="Devon" class="tw:text-secondary tw:hover:underline tw:hover:cursor-pointer tw:underline tw:decoration-dashed tw:hover:decoration-3 tw:hover:decoration-solid tw:hover:pointer-help">Devon</a> is a denim
jacket, <a href="https://tailor.irm-flow.com/designs/jett/" title="Jett jacket" class="tw:text-secondary tw:hover:underline tw:hover:cursor-pointer tw:underline tw:decoration-dashed tw:hover:decoration-3 tw:hover:decoration-solid tw:hover:pointer-help">Jett jacket</a> is a bomber jacket, <a href="https://tailor.irm-flow.com/designs/sarah/" title="Sarah Skirt Block" class="tw:text-secondary tw:hover:underline tw:hover:cursor-pointer tw:underline tw:decoration-dashed tw:hover:decoration-3 tw:hover:decoration-solid tw:hover:pointer-help">Sarah Skirt Block</a> is a basic skirt block, and <a href="https://tailor.irm-flow.com/designs/sunny/" title="Sunny" class="tw:text-secondary tw:hover:underline tw:hover:cursor-pointer tw:underline tw:decoration-dashed tw:hover:decoration-3 tw:hover:decoration-solid tw:hover:pointer-help">Sunny</a>
is an 18th century split side skirt.</p>
<h2 class="anchor anchorWithStickyNavbar_fF9Z" id="devon-denim-jacket">Devon Denim Jacket<a href="https://tailor.irm-flow.com/blog/announcing-devon-jett-sarah-sunny#devon-denim-jacket" class="hash-link" aria-label="Direct link to Devon Denim Jacket" title="Direct link to Devon Denim Jacket" translate="no">​</a></h2>
<p>Desinged by <a href="https://tailor.irm-flow.com/users/?id=132">Wouter</a> – his 14th FreeSewing design for those
keeping count – <a href="https://tailor.irm-flow.com/designs/devon/" title="Devon" class="tw:text-secondary tw:hover:underline tw:hover:cursor-pointer tw:underline tw:decoration-dashed tw:hover:decoration-3 tw:hover:decoration-solid tw:hover:pointer-help">Devon</a> is denim jacket pattern. Obviously, you can make it in
other fabrics too, when we say <em>denim jacket</em> here, it’s more about the style
of the garment.</p>
<p>Wouter has the following to say about it:</p>
<blockquote>
<p><em>I Designed Devon because I had a nice denim jacket that I wanted to make available to others.</em></p>
<p><em>Devon is based on the Bent body block. Being a jacket, it has a considerable amount of ease added.</em></p>
<p><em>The design is inspired by denim jackets my partner has, and some patterns I’ve seen. Most denim jackets do not have set in sleeves, but since this is based on Bent, it does. It makes top stitching the armscye a little more challenging.</em></p>
</blockquote>
<div class="theme-admonition theme-admonition-tip admonition_IZjC alert alert--success"><div class="admonitionHeading_uVvU"><span class="admonitionIcon_HiR3"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>Learn more</div><div class="admonitionContent_bl22"><ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Discover this design at <a href="https://tailor.irm-flow.com/designs/devon/">/designs/devon</a>.</li>
<li>Or <a href="https://tailor.irm-flow.com/editor/#s=%7B%22design%22%3A%22devon%22%2C%22view%22%3A%22measurements%22%7D">discover Devon in the pattern editor</a></li>
</ul></div></div>
<h2 class="anchor anchorWithStickyNavbar_fF9Z" id="jett-bomber-jacket">Jett (Bomber) Jacket<a href="https://tailor.irm-flow.com/blog/announcing-devon-jett-sarah-sunny#jett-bomber-jacket" class="hash-link" aria-label="Direct link to Jett (Bomber) Jacket" title="Direct link to Jett (Bomber) Jacket" translate="no">​</a></h2>
<p>Next up is <a href="https://tailor.irm-flow.com/designs/jett/" title="Jett jacket" class="tw:text-secondary tw:hover:underline tw:hover:cursor-pointer tw:underline tw:decoration-dashed tw:hover:decoration-3 tw:hover:decoration-solid tw:hover:pointer-help">Jett jacket</a>, another jacket pattern in a timeless style, this time the
so-called <em>bomber jacket</em>, or depending on the choice of fabrics and styles, it
can also be a <em>varsity</em> aka <em>letterman</em> jacket.</p>
<p>Jett was designed and coded by <a href="https://tailor.irm-flow.com/users?id=92248">Gawain CCBR</a>, they had the following to say about it:</p>
<blockquote>
<p><em>It’s highly recommended to take another jacket you like and compare the
shoulder-to-shoulder and waist- to-armpit measurements against it before you
start cutting.</em></p>
<p><em>This pattern is intended to fit the widest possible range of bodies, so it
comes with a couple optional adjustments under the Fit options.</em></p>
<p><em>The bust dart/full bust adjustment is intended for people with breasts. There
are two implementations available, one based on horizontal and vertical shifts,
one based on rotations like a full bust adjustment for a paper pattern. The
rotation-based one is better and you should probably use it.</em></p>
<p><em>The full belly adjustment operates under the assumption that the waist
measurement is taken around the fullest part of your belly. If the fullest part
of your belly is below the place you took the waist measurement, don’t worry
about changing the rest of the vertical measurements to account for it - Jett
makes the adjustment all the way down to the hem.</em></p>
<p><em>The full belly adjustment only takes effect if your waist measurement + the
given waist ease is wider than the ease the pattern is already generating
around your stomach. If you turn it on, but don’t see anything change, it’s
because the pattern has enough ease that you don’t need the adjustment.</em></p>
</blockquote>
<div class="theme-admonition theme-admonition-tip admonition_IZjC alert alert--success"><div class="admonitionHeading_uVvU"><span class="admonitionIcon_HiR3"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>Learn more</div><div class="admonitionContent_bl22"><ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Discover this design at <a href="https://tailor.irm-flow.com/designs/jett/">/designs/jett</a>.</li>
<li>Or <a href="https://tailor.irm-flow.com/editor/#s=%7B%22design%22%3A%22jett%22%2C%22view%22%3A%22measurements%22%7D">discover Jett in the pattern editor</a></li>
</ul></div></div>
<h2 class="anchor anchorWithStickyNavbar_fF9Z" id="sarah-skirt-block">Sarah Skirt block<a href="https://tailor.irm-flow.com/blog/announcing-devon-jett-sarah-sunny#sarah-skirt-block" class="hash-link" aria-label="Direct link to Sarah Skirt block" title="Direct link to Sarah Skirt block" translate="no">​</a></h2>
<p>Sarah is a skirt block based on the Aldrich drafting method. It was contributed by <a href="https://tailor.irm-flow.com/users?id=139073">tduehr</a>, the first design by their hand, but not the last (not event the last of this blog post).</p>
<p>Here’s what they had to say about it:</p>
<blockquote>
<p><em>Sarah is the natural waist skirt block from W. Aldrich’s <em>Metric Pattern
Cutting for Women’s Wear, 6th Edition</em>.</em></p>
<p><em>Blocks like this are used as the basic shape of garment designs. This can
be sewn as is for a pencil skirt. Though, there are more options available in
the <a href="https://tailor.irm-flow.com/designs/penelope/" title="Penelope pencil skirt" class="tw:text-secondary tw:hover:underline tw:hover:cursor-pointer tw:underline tw:decoration-dashed tw:hover:decoration-3 tw:hover:decoration-solid tw:hover:pointer-help">Penelope pencil skirt</a>.</em></p>
<p>*This is the first pattern I drafted for myself in different
software as part of a collective attempt to learn CAD pattern drafting at my
local maker space. (it’s the first in the book… probably not a coincidence).
Several of the dimensions being <em>magic</em> and the curves being <em>what ever looks
good</em> frustrated me intensely because they wouldn’t scale and the software
does not contain a constraint solver to make up for that.</p>
</blockquote>
<div class="theme-admonition theme-admonition-tip admonition_IZjC alert alert--success"><div class="admonitionHeading_uVvU"><span class="admonitionIcon_HiR3"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>Learn more</div><div class="admonitionContent_bl22"><ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Discover this design at <a href="https://tailor.irm-flow.com/designs/sarah/">/designs/sarah</a>.</li>
<li>Or <a href="https://tailor.irm-flow.com/editor/#s=%7B%22design%22%3A%22sarah%22%2C%22view%22%3A%22measurements%22%7D">discover Sarah in the pattern editor</a></li>
</ul></div></div>
<h2 class="anchor anchorWithStickyNavbar_fF9Z" id="sunny-skirt">Sunny Skirt<a href="https://tailor.irm-flow.com/blog/announcing-devon-jett-sarah-sunny#sunny-skirt" class="hash-link" aria-label="Direct link to Sunny Skirt" title="Direct link to Sunny Skirt" translate="no">​</a></h2>
<p>And finally (we’re going alphabetic here), we have a new skirt design named <a href="https://tailor.irm-flow.com/designs/sunny/" title="Sunny" class="tw:text-secondary tw:hover:underline tw:hover:cursor-pointer tw:underline tw:decoration-dashed tw:hover:decoration-3 tw:hover:decoration-solid tw:hover:pointer-help">Sunny</a>.
This is a design that was discussed on our Discord server.
The design is credited to <a href="https://freesewing.org/users?id=28514" target="_blank" rel="noopener noreferrer">halbmoki</a> whereas
<a href="https://tailor.irm-flow.com/users?id=139073">tduehr</a> wrote the code for it, in that casual <em>I could, so I did</em> fashion:</p>
<blockquote>
<p><em>Sunny is an 18th century split side skirt. This came up in Discord and I
thought it would be easy to code, so I did. This type of skirt was usually
used as a petticoat. It can also be used as a skirt on its own. The side
splits allow access for a pocket like Lucy.</em></p>
</blockquote>
<div class="theme-admonition theme-admonition-tip admonition_IZjC alert alert--success"><div class="admonitionHeading_uVvU"><span class="admonitionIcon_HiR3"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>Learn more</div><div class="admonitionContent_bl22"><ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Discover this design at <a href="https://tailor.irm-flow.com/designs/sunny/">/designs/sunny</a>.</li>
<li>Or <a href="https://tailor.irm-flow.com/editor/#s=%7B%22design%22%3A%22sunny%22%2C%22view%22%3A%22measurements%22%7D">discover Sunny in the pattern editor</a></li>
</ul></div></div></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[FreeSewing 4.1 brings the Sabrina Sports Bra]]></title>
            <link>https://tailor.irm-flow.com/blog/announcing-sabrina</link>
            <guid>https://tailor.irm-flow.com/blog/announcing-sabrina</guid>
            <pubDate>Sun, 29 Jun 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[We have just released FreeSewing v4.1, and by now you may be aware that a minor version bump typically means we have a new design.]]></description>
            <content:encoded><![CDATA[<div class="mdx"><p>We have just released FreeSewing v4.1, and by now you may be aware that a minor version bump typically means we have a new design.
And that’s exactly what’s going on here, the <a href="https://tailor.irm-flow.com/designs/sabrina/" title="Sabrina" class="tw:text-secondary tw:hover:underline tw:hover:cursor-pointer tw:underline tw:decoration-dashed tw:hover:decoration-3 tw:hover:decoration-solid tw:hover:pointer-help">Sabrina</a> sports bra pattern is brand new.</p>
<h2 class="anchor anchorWithStickyNavbar_fF9Z" id="sabrina-sports-bra">Sabrina Sports Bra<a href="https://tailor.irm-flow.com/blog/announcing-sabrina#sabrina-sports-bra" class="hash-link" aria-label="Direct link to Sabrina Sports Bra" title="Direct link to Sabrina Sports Bra" translate="no">​</a></h2>
<p>As Sabrina was designed &amp; developed by Jonathan, so I’ll let him talk about it:</p>
<blockquote>
<p>This update introduces Sabrina, a simple pull-on sports bra.</p>
<p>I designed Sabrina as a sports bra pattern. It provides light to medium support, but please note that the fit and compression depend heavily on the fabric used. The default ease is on the low/comfortable side. If you need or prefer more compression, consider increasing the stretch to 20% or more and using a fabric with a higher compression rating.</p>
<p>Sabrina is technically unisex. I made some prototypes using my own (male) body measurements and I like wearing them when I go running. They reduce chafing and chest bounce and provide comfortable compression.</p>
<p>Sabrina was developed from Breanna-based prototypes, but the actual construction is independent and straightforward. Essentially, it’s a rectangle with holes for the arms and head, plus a few darts to shape it to your body and reduce excess fabric. You can view the construction by enabling the ‘Base’ part in the Core settings under ‘Only Include Selected Pattern Parts’.</p>
<p>If you have previously made patterns with curved seams and stretchy fabric such as Shin or Bruce, you should find this bra straightforward to make.</p>
<p>I hope you find this pattern helpful.</p>
<p>Jonathan</p>
</blockquote>
<h2 class="anchor anchorWithStickyNavbar_fF9Z" id="other-changes">Other changes<a href="https://tailor.irm-flow.com/blog/announcing-sabrina#other-changes" class="hash-link" aria-label="Direct link to Other changes" title="Direct link to Other changes" translate="no">​</a></h2>
<p>For a full list of changes, you can (as always) check the
<a href="https://codeberg.org/freesewing/freesewing/src/branch/develop/CHANGELOG.md" target="_blank" rel="noopener noreferrer">CHANGELOG</a>,
but here are some highlights:</p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>Fixed a broken link in the welcome flow (oops!)</li>
<li>We’ve added support for the ARCH D and ARCH E paper sizes</li>
<li>We now support preview of the absolute value of snapped percentage options</li>
<li>Fixed some translations issues in <a href="https://tailor.irm-flow.com/designs/octoplushy/" title="Octoplushy the octopus" class="tw:text-secondary tw:hover:underline tw:hover:cursor-pointer tw:underline tw:decoration-dashed tw:hover:decoration-3 tw:hover:decoration-solid tw:hover:pointer-help">Octoplushy the octopus</a></li>
<li>A whole bunch of improvements and fixes in <a href="https://tailor.irm-flow.com/editor">the editor</a></li>
</ul>
<p>However, as we run our website on the very latest changes, these have been
introduced over the last couple of weeks, rather than since today.</p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Announcing the FreeSewing Forum]]></title>
            <link>https://tailor.irm-flow.com/blog/announcing-forum</link>
            <guid>https://tailor.irm-flow.com/blog/announcing-forum</guid>
            <pubDate>Tue, 01 Apr 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[We have launched the official FreeSewing forum at]]></description>
            <content:encoded><![CDATA[<div class="mdx"><p>We have launched the official FreeSewing forum at
<a href="https://forum.freesewing.eu/" target="_blank" rel="noopener noreferrer">forum.freesewing.eu</a>.</p>
<p>The idea that a <em>good old forum</em> would arguably be a better for for the
FreeSewing community than the social network of the day is not new, it’s
something that has always held true.</p>
<p>However, we were always reluctant to take on the additional burden of
operating/maintaining/managing/moderating such a forum, because, well there’s
only 24 hours in a day.</p>
<p>However, given the efforts we are making to keep our user’s data out of the
reach of the US administration, it felt like the time was right to do it.</p>
<p>And so we did. The official FreeSewing forum lives at
<a href="https://forum.freesewing.eu/" target="_blank" rel="noopener noreferrer">forum.freesewing.eu</a> and you can (and should)
use your FreeSewing account for authentication.</p>
<p>It’s a bit empty still, so don’t be shy and come say hello.</p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Announcing FreeSewing v4]]></title>
            <link>https://tailor.irm-flow.com/blog/announcing-v4</link>
            <guid>https://tailor.irm-flow.com/blog/announcing-v4</guid>
            <pubDate>Tue, 01 Apr 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[FreeSewing version 4 was released today, and we have migrated to our new]]></description>
            <content:encoded><![CDATA[<div class="mdx"><p>FreeSewing version 4 was released today, and we have migrated to our new
website too.</p>
<p>This new major version of FreeSewing, version 4, has been in the works for a
while, and I <em>really</em> wanted to get it out the door before sending out our
Spring edition newsletter, so that’s exactly what I did.</p>
<p>As this is a major version, there are breaking changes, but we’ve really kept
it to a minimum. There’s only one real breaking change:</p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>FreeSewing now requires NodeJS 20 or newer</li>
</ul>
<p>In other words, we’ve dropped support for NodeJS 18, which will reach
end of life at the end of next month.</p>
<p>A lot of work went into this new major release, especially in the realm of our
frontend code, where we made a huge effort to make it more maintainable.
This is the kind of thing that mostly happens under the hood, but will allow
us to increase the project’s volatility and shorten our (non-major) release
cycle.</p>
<p>What this means is that everything’s changed, and nothing has changed.
I’ve compared it to your favorite restaurant moving across the street. It’s a
different building, different kitchen, different everything. But your favorite
waitress is still there serving that same food you’ve know and love.</p>
<p>That, in a nutshell, is FreeSewing v4.</p>
<h2 class="anchor anchorWithStickyNavbar_fF9Z" id="-bye-bye-vercelnextjs">👋 Bye bye Vercel/NextJS<a href="https://tailor.irm-flow.com/blog/announcing-v4#-bye-bye-vercelnextjs" class="hash-link" aria-label="Direct link to 👋 Bye bye Vercel/NextJS" title="Direct link to 👋 Bye bye Vercel/NextJS" translate="no">​</a></h2>
<p>We have been using NextJS for several years now for the FreeSewing frontends.
However, as I mentioned in an earlier edition of this newsletter, Vercel (the
company behind NextJS) has revoked their sponsorship. This was nothing against
FreeSewing, they’ve revoked all open source plans, but without their
sponsorships, the cost of hosting our websites on Vercel is rather steep, and
it was not sustainable for us to stay with them.</p>
<p>Furthermore, Vercel is also increasingly tying NextJS to their hosted offering,
making it harder to <em>just go elsewhere</em>.</p>
<p>Since documentation is a critical (and large) part of both our website for
makers and developers, we’ve decided to migrate to Docusaurus, which is highly
optimized for documentation, but flexible enough that we can still do all the
more advanced stuff that we need.</p>
<p>To improve maintainability and facilitate code reuse between our websites and
new studio, we’ve abstracted all of our frontend logic into various components
in our new <code>@freesewing/react</code> package which now underpins all our frontends.</p>
<p>This was a huge effort, and we are lagging behind with developer documentation,
which is something which we’ll work on going forward.</p>
<p>Apart from that, I’m certain there will be some rough edges, but things
<em>should just work</em> and if not, make sure to let us know.</p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Putting some distance between our users and the new US administration]]></title>
            <link>https://tailor.irm-flow.com/blog/us-and-eu</link>
            <guid>https://tailor.irm-flow.com/blog/us-and-eu</guid>
            <pubDate>Tue, 01 Apr 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[With everything that is going on right now — _gestures vaguely in the]]></description>
            <content:encoded><![CDATA[<div class="mdx"><p>With everything that is going on right now — <em>gestures vaguely in the
direction of the current US administration</em> — it’s tempting to throw up our
hands in despair, spend our days doomscrolling, or just check out somehow.</p>
<p>Unfortunately, that’s not going to cut it for we are way into uncharted
territory here.</p>
<p>To put some distance between our users and the new US administration,
we have moved everything that is potentially sensitive to brand
new infrastructure in Europe, using European companies, rather than US-based
companies. Specifically:</p>
<ul class="tw:list tw:list-inside tw:list-disc tw:ml-2">
<li>We’ve moved our backend systems from DigitalOcean in the US to Scaleway in Germany</li>
<li>We’ve moved our software repositories from GitHub in the US to Codeberg in Germany</li>
<li>We’ve moved our transactional email service from AWS in the US to Scaleway in Germany (ongoing)</li>
<li>We have put a de-facto freeze on our Instagram account, and recommend you
follow our accounts on <a href="https://freesewing.social/" target="_blank" rel="noopener noreferrer">freesewing.social</a>, our
Mastodon instance hosted in Germany.</li>
<li>We have re-visited our choice to use Discord as the de-facto place for the
FreeSewing community, and have instead decided that here too we would step
both to safeguard the data of our users, as well as embrace the open web. So
we’ve created a forum for the FreeSewing community (more on that below).</li>
<li>While freesewing.org will continue to work as expected, we will henceforth
use freesewing.eu as our main domain name.</li>
</ul>
<p>All of these changes are already active, although some need some time to
percolate to completion.</p>
<p>None of this will impact you as a user of the site. So, you may find this
overkill. But people trust us with their data, and we feel a moral
obligation to safeguard that data even from a potential adversarial
administration in the US.</p></div>]]></content:encoded>
        </item>
    </channel>
</rss>