Skip to content

Commit

Permalink
feat(increasing the accuracy of the client-side prototype pollution m…
Browse files Browse the repository at this point in the history
…echanism): improvement

It is unlikely that a native function can be used for prototype pollution. By determining whether a
function is native, the code can avoid executing native functions that may result in unexpected
behavior or errors. The toString() method returns a string representation of a function, including
its source code, so determining whether the string representation contains '[native code]' allows
the code to determine whether it is native.
  • Loading branch information
acuciureanu committed Feb 9, 2023
1 parent 64b2ee2 commit a1cceb0
Show file tree
Hide file tree
Showing 2 changed files with 3 additions and 46 deletions.
45 changes: 0 additions & 45 deletions sandbox/index.html
Original file line number Diff line number Diff line change
@@ -1,50 +1,5 @@
<!DOCTYPE html>

<html>
<script>
const types = [Object, String, Number, Array, Function, Boolean];

const prototypesPropertiesReducer = (acc, type) => ({
...acc,
[type.name]: Object.getOwnPropertyNames(type.prototype),
});
const intersectProtoPropNameReducer = (acc, type, prev, curr) =>
prev !== undefined && curr !== undefined
? {
...acc,
[type.name]: curr[type.name].filter((protoPropName) => !prev[type.name].includes(protoPropName)),
}
: { ...acc };

const prototypePropertyNames = () => types.reduce(prototypesPropertiesReducer, {});
const intersectPropertyNames = (prev, curr) =>
types.reduce((acc, type) => intersectProtoPropNameReducer(acc, type, prev, curr), {});
</script>

<script>
const before = prototypePropertyNames();
</script>

<script id="target"></script>

<script>
const after = prototypePropertyNames();

const result = intersectPropertyNames(before, after);

const probe = () =>
Object.keys(result).reduce((acc, key) => {
for (let propKey of result[key]) {
const payload = `${key}.prototype.${propKey}`;
try {
if (typeof eval(payload) === 'function' && eval(payload).call() === window) {
acc.push(payload);
}
} catch (e) {
// Nothing to catch now.
}
}
return acc;
}, []);
</script>
</html>
4 changes: 3 additions & 1 deletion sandbox/js/check.payload.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ const probe = () =>
for (let propKey of prototypePropertyNames[key]) {
const payload = `${key}.prototype.${propKey}`;
try {
if (typeof eval(payload) === 'function' && eval(payload).call() === window) {
const propValue = eval(payload);
// Check if property is user defined and not native
if (typeof propValue === 'function' && propValue.toString().indexOf('[native code]') === -1) {
acc.push(payload);
}
} catch (e) {
Expand Down

0 comments on commit a1cceb0

Please sign in to comment.