Unsafe dynamic method access¶
ID: js/unsafe-dynamic-method-access Kind: path-problem Security severity: 9.3 Severity: error Precision: high Tags: - security - external/cwe/cwe-094 Query suites: - javascript-code-scanning.qls - javascript-security-extended.qls - javascript-security-and-quality.qls
Click to see the query in the CodeQL repository
Calling a user-controlled method on certain objects can lead to invocation of unsafe functions, such as eval
or the Function
constructor. In particular, the global object contains the eval
function, and any function object contains the Function
constructor in its constructor
property.
Recommendation¶
Avoid invoking user-controlled methods on the global object or on any function object. Whitelist the permitted method names or change the type of object the methods are stored on.
Example¶
In the following example, a message from the document’s parent frame can invoke the play
or pause
method. However, it can also invoke eval
. A malicious website could embed the page in an iframe and execute arbitrary code by sending a message with the name eval
.
// API methodsfunctionplay(data){// ...}functionpause(data){// ...}window.addEventListener("message",(ev)=>{letmessage=JSON.parse(ev.data);// Let the parent frame call the 'play' or 'pause' function window[message.name](message.payload);});
Instead of storing the API methods in the global scope, put them in an API object or Map. It is also good practice to prevent invocation of inherited methods like toString
and valueOf
.
// API methodsletapi={play:function(data){// ...},pause:function(data){// ...}};window.addEventListener("message",(ev)=>{letmessage=JSON.parse(ev.data);// Let the parent frame call the 'play' or 'pause' functionif(!api.hasOwnProperty(message.name)){return;}api[message.name](message.payload);});
References¶
OWASP: Code Injection.
MDN: Global functions.
MDN: Function constructor.
Common Weakness Enumeration: CWE-94.