diff --git a/libs/acf/util/src/lib/value.spec.ts b/libs/acf/util/src/lib/value.spec.ts
index 53157c45..f605d9fb 100644
--- a/libs/acf/util/src/lib/value.spec.ts
+++ b/libs/acf/util/src/lib/value.spec.ts
@@ -48,4 +48,17 @@ describe('getValue', () => {
window.history.replaceState({}, '', `${window.location.pathname}${originalSearch}`);
});
+
+ it('should handle multiple QUERY patterns correctly with sanitization and validation', async () => {
+ const searchParams = new URLSearchParams();
+ searchParams.set('param1', 'value1');
+ searchParams.set('param2', 'value2');
+ const originalSearch = window.location.search;
+ window.history.replaceState({}, '', `${window.location.pathname}?${searchParams.toString()}`);
+
+ const result = await Value.getValue(' and ');
+ expect(result).toBe('value1 and value2<script>alert(1)</script>');
+
+ window.history.replaceState({}, '', `${window.location.pathname}${originalSearch}`);
+ });
});
diff --git a/libs/acf/util/src/lib/value.ts b/libs/acf/util/src/lib/value.ts
index 2a8aac3e..352c3cdc 100644
--- a/libs/acf/util/src/lib/value.ts
+++ b/libs/acf/util/src/lib/value.ts
@@ -39,11 +39,25 @@ export const Value = (() => {
const getSessionCount = (value: string) => value.replaceAll('', String(window.__sessionCount));
+ const sanitizeInput = (input: string): string => {
+ const element = document.createElement('div');
+ element.innerText = input;
+ return element.innerHTML;
+ };
+
+ const validateQueryParam = (key: string, value: string): boolean => {
+ const pattern = /^[a-zA-Z0-9_-]+$/;
+ return pattern.test(key) && pattern.test(value);
+ };
+
const getQueryParam = (value: string) => {
const [, key] = value.split('::');
const searchParams = new URLSearchParams(window.location.search);
if (searchParams.has(key)) {
- value = searchParams.get(key) || key;
+ const paramValue = searchParams.get(key) || key;
+ if (validateQueryParam(key, paramValue)) {
+ value = sanitizeInput(paramValue);
+ }
}
return value;
};
@@ -51,7 +65,11 @@ export const Value = (() => {
const getMultiQueryParam = (value: string) => {
value = value.replace(VALUE_MATCHER.QUERY, (_, key) => {
const searchParams = new URLSearchParams(window.location.search);
- return searchParams.get(key) || key;
+ const paramValue = searchParams.get(key) || key;
+ if (validateQueryParam(key, paramValue)) {
+ return sanitizeInput(paramValue);
+ }
+ return key;
});
return value;
};