what-core 0.6.5 → 0.6.7
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/dist/compiler.js +59 -15
- package/dist/compiler.js.map +3 -3
- package/dist/compiler.min.js +1 -1
- package/dist/compiler.min.js.map +4 -4
- package/dist/index.js +59 -15
- package/dist/index.js.map +3 -3
- package/dist/index.min.js +5 -5
- package/dist/index.min.js.map +4 -4
- package/dist/render.js +59 -15
- package/dist/render.js.map +3 -3
- package/dist/render.min.js +2 -2
- package/dist/render.min.js.map +4 -4
- package/dist/testing.js +54 -0
- package/dist/testing.js.map +3 -3
- package/dist/testing.min.js +1 -1
- package/dist/testing.min.js.map +4 -4
- package/hooks.d.ts +25 -0
- package/package.json +3 -1
- package/src/dom.js +9 -0
- package/src/render.js +6 -20
- package/src/security.js +63 -0
package/dist/index.js
CHANGED
|
@@ -1089,6 +1089,53 @@ function transition(name, active) {
|
|
|
1089
1089
|
};
|
|
1090
1090
|
}
|
|
1091
1091
|
|
|
1092
|
+
// packages/core/src/security.js
|
|
1093
|
+
var URL_ATTRS = /* @__PURE__ */ new Set([
|
|
1094
|
+
"href",
|
|
1095
|
+
"src",
|
|
1096
|
+
"action",
|
|
1097
|
+
"formaction",
|
|
1098
|
+
"poster",
|
|
1099
|
+
"cite",
|
|
1100
|
+
"background",
|
|
1101
|
+
"xlink:href"
|
|
1102
|
+
]);
|
|
1103
|
+
var URL_LIST_ATTRS = /* @__PURE__ */ new Set(["srcset"]);
|
|
1104
|
+
function normalizeAttrName(name) {
|
|
1105
|
+
return String(name).toLowerCase();
|
|
1106
|
+
}
|
|
1107
|
+
function normalizeUrlForProtocolCheck(url) {
|
|
1108
|
+
return String(url).trim().replace(/[\s\x00-\x1f\x7f]/g, "").toLowerCase();
|
|
1109
|
+
}
|
|
1110
|
+
function isSafeUrlValue(value) {
|
|
1111
|
+
if (typeof value !== "string") return true;
|
|
1112
|
+
const normalized = normalizeUrlForProtocolCheck(value);
|
|
1113
|
+
return !(normalized.startsWith("javascript:") || normalized.startsWith("data:") || normalized.startsWith("vbscript:"));
|
|
1114
|
+
}
|
|
1115
|
+
function isSafeSrcsetValue(value) {
|
|
1116
|
+
if (typeof value !== "string") return true;
|
|
1117
|
+
return value.split(",").every((candidate) => {
|
|
1118
|
+
const url = candidate.trim().split(/\s+/, 1)[0] || "";
|
|
1119
|
+
return url === "" || isSafeUrlValue(url);
|
|
1120
|
+
});
|
|
1121
|
+
}
|
|
1122
|
+
function isUrlAttribute(name) {
|
|
1123
|
+
return URL_ATTRS.has(normalizeAttrName(name));
|
|
1124
|
+
}
|
|
1125
|
+
function isUrlListAttribute(name) {
|
|
1126
|
+
return URL_LIST_ATTRS.has(normalizeAttrName(name));
|
|
1127
|
+
}
|
|
1128
|
+
function isSafeUrlAttributeValue(name, value) {
|
|
1129
|
+
if (isUrlListAttribute(name)) return isSafeSrcsetValue(value);
|
|
1130
|
+
if (isUrlAttribute(name)) return isSafeUrlValue(value);
|
|
1131
|
+
return true;
|
|
1132
|
+
}
|
|
1133
|
+
function getDomAttributeName(name) {
|
|
1134
|
+
if (name === "className") return "class";
|
|
1135
|
+
if (name === "htmlFor") return "for";
|
|
1136
|
+
return normalizeAttrName(name) === "formaction" ? "formaction" : name;
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1092
1139
|
// packages/core/src/dom.js
|
|
1093
1140
|
var SVG_ELEMENTS = /* @__PURE__ */ new Set([
|
|
1094
1141
|
"svg",
|
|
@@ -1579,6 +1626,13 @@ function applyProps(el, newProps, oldProps, isSvg) {
|
|
|
1579
1626
|
}
|
|
1580
1627
|
}
|
|
1581
1628
|
function setProp(el, key, value, isSvg) {
|
|
1629
|
+
if (!isSafeUrlAttributeValue(key, value)) {
|
|
1630
|
+
if (typeof console !== "undefined") {
|
|
1631
|
+
console.warn(`[what] Blocked unsafe URL in "${key}" attribute: ${value}`);
|
|
1632
|
+
}
|
|
1633
|
+
el.removeAttribute(getDomAttributeName(key));
|
|
1634
|
+
return;
|
|
1635
|
+
}
|
|
1582
1636
|
if (typeof value === "function" && !(key.startsWith("on") && key.length > 2) && key !== "ref") {
|
|
1583
1637
|
if (!el._propEffects) el._propEffects = {};
|
|
1584
1638
|
if (el._propEffects[key]) {
|
|
@@ -1891,15 +1945,6 @@ function classifyError(err, context = {}) {
|
|
|
1891
1945
|
}
|
|
1892
1946
|
|
|
1893
1947
|
// packages/core/src/render.js
|
|
1894
|
-
var URL_ATTRS = /* @__PURE__ */ new Set(["href", "src", "action", "formaction", "formAction"]);
|
|
1895
|
-
function isSafeUrl(url) {
|
|
1896
|
-
if (typeof url !== "string") return true;
|
|
1897
|
-
const normalized = url.trim().replace(/[\s\x00-\x1f]/g, "").toLowerCase();
|
|
1898
|
-
if (normalized.startsWith("javascript:")) return false;
|
|
1899
|
-
if (normalized.startsWith("data:")) return false;
|
|
1900
|
-
if (normalized.startsWith("vbscript:")) return false;
|
|
1901
|
-
return true;
|
|
1902
|
-
}
|
|
1903
1948
|
var TABLE_WRAPPERS = {
|
|
1904
1949
|
tr: { depth: 2, wrap: "<table><tbody>", unwrap: "</tbody></table>" },
|
|
1905
1950
|
td: { depth: 3, wrap: "<table><tbody><tr>", unwrap: "</tr></tbody></table>" },
|
|
@@ -2590,13 +2635,12 @@ function setProp2(el, key, value) {
|
|
|
2590
2635
|
return;
|
|
2591
2636
|
}
|
|
2592
2637
|
if (key === "key") return;
|
|
2593
|
-
if (
|
|
2594
|
-
if (
|
|
2595
|
-
|
|
2596
|
-
console.warn(`[what] Blocked unsafe URL in "${key}" attribute: ${value}`);
|
|
2597
|
-
}
|
|
2598
|
-
return;
|
|
2638
|
+
if (!isSafeUrlAttributeValue(key, value)) {
|
|
2639
|
+
if (typeof console !== "undefined") {
|
|
2640
|
+
console.warn(`[what] Blocked unsafe URL in "${key}" attribute: ${value}`);
|
|
2599
2641
|
}
|
|
2642
|
+
el.removeAttribute(getDomAttributeName(key));
|
|
2643
|
+
return;
|
|
2600
2644
|
}
|
|
2601
2645
|
if (key === "class" || key === "className") {
|
|
2602
2646
|
el.className = value || "";
|