@adobe/spacecat-shared-data-access 4.15.0 → 4.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/package.json +1 -1
- package/src/models/site/config.js +35 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## [@adobe/spacecat-shared-data-access-v4.15.1](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v4.15.0...@adobe/spacecat-shared-data-access-v4.15.1) (2026-07-29)
|
|
2
|
+
|
|
3
|
+
### Bug Fixes
|
|
4
|
+
|
|
5
|
+
* validate cdnlogsFilter key against a column allowlist in site config ([#1851](https://github.com/adobe/spacecat-shared/issues/1851)) ([46a0408](https://github.com/adobe/spacecat-shared/commit/46a0408b852fa6f6483fc2ad81c3ce1a8d0c615d)), closes [adobe/spacecat-audit-worker#2826](https://github.com/adobe/spacecat-audit-worker/issues/2826)
|
|
6
|
+
|
|
1
7
|
## [@adobe/spacecat-shared-data-access-v4.15.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v4.14.0...@adobe/spacecat-shared-data-access-v4.15.0) (2026-07-29)
|
|
2
8
|
|
|
3
9
|
### Features
|
package/package.json
CHANGED
|
@@ -70,6 +70,30 @@ const RESERVED_SCRAPER_HEADER_NAMES = new Set([
|
|
|
70
70
|
|
|
71
71
|
const LLMO_TAG_PATTERN = /^(market|product|topic):\s?.+/;
|
|
72
72
|
const AWS_REGION_PATTERN = /^[a-z]{2}(?:-[a-z]+)+-\d+$/i;
|
|
73
|
+
|
|
74
|
+
// Columns on the CDN log tables that a cdnlogsFilter entry is allowed to target.
|
|
75
|
+
// `key` is interpolated (unquoted) into Athena SQL by the audit worker's
|
|
76
|
+
// buildSiteFilters(), so it MUST be constrained to this allowlist to prevent SQL
|
|
77
|
+
// injection (VULN-37491). Keep in sync with ALLOWED_FILTER_KEYS in
|
|
78
|
+
// spacecat-audit-worker/src/utils/cdn-utils.js.
|
|
79
|
+
export const CDN_LOGS_FILTER_KEYS = [
|
|
80
|
+
'url',
|
|
81
|
+
'host',
|
|
82
|
+
'x_forwarded_host',
|
|
83
|
+
'user_agent',
|
|
84
|
+
'referer',
|
|
85
|
+
'cdn_provider',
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
const CDN_LOGS_FILTER_SCHEMA = Joi.array().items(
|
|
89
|
+
Joi.object({
|
|
90
|
+
// Athena folds column identifiers to lowercase; normalize before matching
|
|
91
|
+
// the allowlist so a stored 'X_forwarded_host' is accepted as the same column.
|
|
92
|
+
key: Joi.string().lowercase().valid(...CDN_LOGS_FILTER_KEYS).required(),
|
|
93
|
+
value: Joi.array().items(Joi.string()).required(),
|
|
94
|
+
type: Joi.string().valid('include', 'exclude').optional(),
|
|
95
|
+
}),
|
|
96
|
+
);
|
|
73
97
|
const LLMO_TAG = Joi.alternatives()
|
|
74
98
|
.try(
|
|
75
99
|
// Tag market, product, topic like this: "market: ch", "product: firefly", "topic: copyright"
|
|
@@ -351,13 +375,7 @@ export const configSchema = Joi.object({
|
|
|
351
375
|
}),
|
|
352
376
|
).optional(),
|
|
353
377
|
tags: Joi.array().items(Joi.string()).optional(),
|
|
354
|
-
cdnlogsFilter:
|
|
355
|
-
Joi.object({
|
|
356
|
-
key: Joi.string().required(),
|
|
357
|
-
value: Joi.array().items(Joi.string()).required(),
|
|
358
|
-
type: Joi.string().valid('include', 'exclude').optional(),
|
|
359
|
-
}),
|
|
360
|
-
).optional(),
|
|
378
|
+
cdnlogsFilter: CDN_LOGS_FILTER_SCHEMA.optional(),
|
|
361
379
|
countryCodeIgnoreList: Joi.array().items(
|
|
362
380
|
Joi.string().length(2),
|
|
363
381
|
).optional(),
|
|
@@ -842,8 +860,17 @@ export const Config = (data = {}) => {
|
|
|
842
860
|
};
|
|
843
861
|
|
|
844
862
|
self.updateLlmoCdnlogsFilter = (cdnlogsFilter) => {
|
|
863
|
+
// Reject invalid filter keys at write time (VULN-37491): `key` is
|
|
864
|
+
// interpolated into Athena SQL downstream, so anything off the allowlist
|
|
865
|
+
// must never be persisted. Validate only the filter here to avoid coupling
|
|
866
|
+
// to unrelated required fields elsewhere in the config.
|
|
867
|
+
const { error, value } = CDN_LOGS_FILTER_SCHEMA.validate(cdnlogsFilter);
|
|
868
|
+
if (error) {
|
|
869
|
+
throw new Error(`CDN logs filter validation error: ${error.message}`, { cause: error });
|
|
870
|
+
}
|
|
871
|
+
|
|
845
872
|
state.llmo = state.llmo || {};
|
|
846
|
-
state.llmo.cdnlogsFilter =
|
|
873
|
+
state.llmo.cdnlogsFilter = value;
|
|
847
874
|
};
|
|
848
875
|
|
|
849
876
|
self.updateLlmoCountryCodeIgnoreList = (countryCodeIgnoreList) => {
|