security hardening

This commit is contained in:
Gerhard Scheikl
2026-05-31 09:35:31 +02:00
parent d7d437a871
commit 01b4734477
31 changed files with 1234 additions and 238 deletions
+14 -1
View File
@@ -9,10 +9,12 @@ import {
normaliseIban,
} from "../services/invoice/validation";
import { STORED_LOGO_SENTINEL } from "../services/invoice/logoCache.constants";
import { validateMerchantHttpsUrl } from "../services/invoice/safeFetch.server";
import {
deleteStoredLogo,
storeUploadedLogo,
} from "../services/invoice/logoCache.server";
import { encryptField } from "../services/crypto/fieldCrypto.server";
import { RichTextEditor } from "../components/RichTextEditor";
import {
DEFAULT_EMAIL_BODY_DE,
@@ -122,6 +124,13 @@ export const action = async ({ request }: ActionFunctionArgs) => {
select: { logoUrl: true },
});
const submittedLogoUrl = str("logoUrl");
// Validate any merchant-supplied external logo URL at the trust boundary:
// require a syntactically valid https URL whose host is a domain name, not
// an IP literal (SSRF defence-in-depth; safeFetch is the runtime backstop).
if (submittedLogoUrl && submittedLogoUrl !== STORED_LOGO_SENTINEL) {
const urlError = validateMerchantHttpsUrl(submittedLogoUrl);
if (urlError) errors.logo = urlError;
}
const removeLogo = bool("removeLogo");
const logoFile = form.get("logoFile");
const hasUpload =
@@ -154,13 +163,17 @@ export const action = async ({ request }: ActionFunctionArgs) => {
const submittedSmtpPassword = str("smtpPassword");
let nextSmtpPassword: string;
if (submittedSmtpPassword === SMTP_PASSWORD_SENTINEL) {
// Unchanged: keep the stored value as-is (already encrypted at rest).
const current = await db.shopSettings.findUnique({
where: { shopDomain: session.shop },
select: { smtpPassword: true },
});
nextSmtpPassword = current?.smtpPassword ?? "";
} else {
nextSmtpPassword = submittedSmtpPassword;
// New password (including "" to clear). Encrypt non-empty values at rest.
nextSmtpPassword = submittedSmtpPassword
? encryptField(submittedSmtpPassword)
: "";
}
const data = {