JavaScriptâ¯eval()ã代æ¿ã§ããæ¹æ³
JavaScriptã® eval() ãå±éºãªçç±ãšã new Function() ã«ãã£ãŠå®å
šã«ä»£æ¿ããæ¹æ³ãå®çšçãªäŸãšãšãã«ã玹ä»ããŸããã»ãã¥ãªãã£ãšããã©ãŒãã³ã¹ã®äž¡æ¹ãéèŠãããã³ãã§ãïŒ
JavaScriptã䜿ã£ãŠãããšãæååãšããŠè¡šçŸãããã³ãŒããå®è¡ããªããã°ãªããªãå Žé¢ããããŸãããã®éãæåã«æãæµ®ãã¶ã®ã eval() 颿°ã§ããããããã eval() ã¯ãã»ãã¥ãªãã£ã®è匱æ§ãšããã©ãŒãã³ã¹ã®åé¡ã§æªåé«ãååšã§ãã
ãã®èšäºã§ã¯ã eval() ã®å±éºæ§ã確èªããããå®å
šãªä»£æ¿ææ®µã§ãã new Function() ãã©ã®ããã«æŽ»çšã§ããããå®çšçãªäŸãšãšãã«ã玹ä»ããŸãã
eval()ãšã¯äœãïŒ
MDN ã®ææžã«ããã°ã eval() ã¯æååã§è¡šããã JavaScript ã³ãŒããå®è¡ãã颿°ã§ããç°¡åãªäŸã䜿ã£ãŠåäœãèŠãŠã¿ãŸãããã
let a = 3;
let b = 5;
eval('a += ' + b + ' + 2');
console.log(a); // 10
äžã®ã³ãŒãã§ã¯ã eval() ãæåå 'a += 5 + 2' ãå®éã® JavaScript ã³ãŒããšããŠå®è¡ããŠããŸããäžèŠäŸ¿å©ã«èŠããŸããããã®åçŽãã®è£ã«ã¯é倧ãªåé¡ãæœãã§ããŸãã
eval()ã®ã»ãã¥ãªãã£äžã®ãªã¹ã¯
eval() ã¯åŒã³åºãå
ã®æš©éã§ã³ãŒããå®è¡ããŸããããã¯ã©ãããæå³ã§ããããïŒãããŠãŒã¶ãŒå
¥åã eval() ã§å®è¡ããŠããŸã£ãããæªæã®ããã³ãŒãããã®ãŸãŸå®è¡ãããå¯èœæ§ããããŸãã
var userContent = getUserInput(); // ãŠãŒã¶ãŒããã®å
¥å
eval(userContent); // å±éºïŒ
ããã«ãŒã "window.location = 'http://malicious-site.com'" ã®ãããªã³ãŒããå
¥åãããã©ããªãã§ããããïŒå©çšè
ã¯æªæã®ãããµã€ããžãªãã€ã¬ã¯ãããããããã£ãšæ·±å»ãªå Žåã¯æ©å¯ããŒã¿ãçãŸããå¯èœæ§ããããŸãã
ãŸã eval() ã¯åŒã³åºãããã¹ã³ãŒãïŒscopeïŒã«çŽæ¥ã¢ã¯ã»ã¹ã§ããŸããããã¯ããŒã«ã«å€æ°ãèªã¿åã£ãã倿Žã§ãããšããããšã§ãïŒ
function MyFunc() {
let secretToken = "abc123";
eval('console.log(secretToken); secretToken = "hacked";');
console.log(secretToken); // "hacked"
}
eval()ã®ããã©ãŒãã³ã¹åé¡
eval() 㯠JavaScript ã€ã³ã¿ããªã¿ãçŽæ¥åŒã³åºããããä»ã®ä»£æ¿ææ®µããé
ããªããŸããçŸä»£ã® JavaScript ãšã³ãžã³ã¯ã³ãŒããæé©åããŸããã eval() ã¯ã©ããªã³ãŒããå®è¡ããããäºãææ¡ã§ããªãããããã®æé©åã劚ããŸãã
new Function()ã§ããå®å šã«
new Function() 㯠eval() ãšäŒŒãŠãæååãã颿°ãçæããŸããããã£ãšå®å
šã§ããã©ã®ããã«äœ¿ããèŠãŠã¿ãŸãããïŒ
const add = new Function('a', 'b', 'return a + b');
console.log(add(2, 3)); // 5
æ§æã¯æ¬¡ã®éãã§ãïŒ
let func = new Function([arg1, arg2, ...argN], functionBody);
ããã§éèŠãªã®ã¯ã new Function() ã§çæããã颿°ã¯ åžžã«ã°ããŒãã«ã¹ã³ãŒã ã§å®è¡ããããšããç¹ã§ããããŒã«ã«å€æ°ã«ã¯ã¢ã¯ã»ã¹ã§ããŸããïŒ
function MyFunc() {
let b = 123;
new Function('console.log(b);')(); // ReferenceError: b is not defined
}
ãã®ãããªå¶çŽãããããã»ãã¥ãªãã£ã匷åããŸããæªæã®ããã³ãŒãã颿°å éšã®æ©å¯å€æ°ã«ã¢ã¯ã»ã¹ããã®ãæ ¹æ¬çã«é²æ¢ããããã§ãã
eval() ãš new Function() ãæ¯èŒãã
ïŒã€ã®æ¹åŒã®æ žå¿çãªéããæŽçããŸãããã
å®è¡ã³ã³ããã¹ããšã¹ã³ãŒã
eval() ã¯çŸåšã®å®è¡ã³ã³ããã¹ãã§ã³ãŒããè©äŸ¡ããŸãïŒ
function testEval() {
let x = 10;
eval('console.log(x); x = 20;');
console.log(x); // 20 â 倿°ã倿ŽãããŠãã
}
testEval();
äžæ¹ã new Function() ã¯ã°ããŒãã«ã³ã³ããã¹ãã§ã®ã¿å®è¡ãããŸãïŒ
function testFunction() {
let x = 10;
const func = new Function('console.log(typeof x);'); // "undefined"
func();
console.log(x); // 10 â 倿°ãå®å
šã«ä¿è·ãããŠãã
}
testFunction();
ã»ãã¥ãªãã£æ§
new Function() ã®éå®ãããã¹ã³ãŒãã¢ã¯ã»ã¹ã¯ãã»ãã¥ãªãã£äžå€§ããªå©ç¹ã§ããããŒã«ã«å€æ°ã«ã¢ã¯ã»ã¹ã§ããªããããããšãæªæã®ããã³ãŒããå®è¡ãããŠã被害ã®ç¯å²ãéå®ãããŸãã
å®è·µäŸã§åŠã¶
å®éã«ã©ã®ããã« eval() ã new Function() ã«çœ®ãæããããã®ã§ããããïŒ
ã·ã³ãã«ãªæ°åŒèšç®
// eval() 䜿çšïŒæšå¥šãããŸããïŒ
const result1 = eval('2 + 3 * 4');
// new Function() 䜿çšïŒæšå¥šïŒ
const calculate = new Function('return 2 + 3 * 4');
const result2 = calculate();
åç颿°ã®çæ
// ãŠãŒã¶ãŒãå
¥åãã颿°æ¬äœãã颿°ãçæãã
const functionBody = 'return x * 2';
const double = new Function('x', functionBody);
console.log(double(5)); // 10
å€éšå€æ°ãå®å šã«æž¡ã
ã°ããŒãã«å€æ°ã¯ new Function() ã§ãã¢ã¯ã»ã¹å¯èœã§ãããããå®å
šãªæ¹æ³ãšããŠã¯ãã©ã¡ãŒã¿ãŒãšããŠæç€ºçã«æž¡ãããšã§ãïŒ
const multiplier = 3;
// ãã©ã¡ãŒã¿ãŒãšããŠæç€ºçã«æž¡ã
const multiply = new Function('x', 'multiplier', 'return x * multiplier');
console.log(multiply(5, multiplier)); // 15
JSONããŒã¹ã®ä»£æ¿
峿 ŒãªJSONã§ã¯ãªããJavaScriptãªããžã§ã¯ããªãã©ã«ãããŒã¹ããããšãã«ã掻çšã§ããŸãïŒ
function looseJsonParse(obj) {
return Function('"use strict";return (' + obj + ")")();
}
const result = looseJsonParse("{a:(4-1), b:function(){}, c:new Date()}");
console.log(result.a); // 3
ã〠new Function() ã䜿ãã¹ããïŒ
new Function() ãæçšãªã·ããªãªãèŠãŠãããŸãããïŒ
åçã³ãŒãçææ
èšå®ãã¡ã€ã«ããŠãŒã¶ãŒå ¥åã«åºã¥ããŠé¢æ°ãåçã«çæããå¿ èŠããããšãã«äŸ¿å©ã§ããäŸãã°ããŠãŒã¶ãŒå®çŸ©ã®ãã£ã«ã¿ãŒããœãŒãããžãã¯ãå®è£ ãããšããªã©ã
ãµã³ãããã¯ã¹ç°å¢
ã°ããŒãã«ã¹ã³ãŒãã§ã®ã¿å®è¡ãããããããã©ã°ã€ã³ã·ã¹ãã ããŠãŒã¶ãŒã¹ã¯ãªããå®è¡ç°å¢ãæ§ç¯ããéã«é©ããŠããŸãã
ããã©ãŒãã³ã¹ãéèŠãªå Žå
ç¹°ãè¿ãå®è¡ãããã³ãŒãã§ããã°ãäžåºŠ new Function() ã§ã³ã³ãã€ã«ããŠããåå©çšããããšã§ã eval() ãæ¯ååŒã³åºããããå¹ççã§ãã
泚æäºé ãšéç
new Function() ãå®ç§ãªè§£æ±ºçã§ã¯ãããŸãããæååããã³ãŒããçæãããšããç¹ã§ã¯äŸç¶ãšããŠãªã¹ã¯ããããä¿¡é Œã§ããªãå
¥åãæ±ãå Žåã¯å³éãªæ€èšŒãå¿
èŠã§ãã
ãŸããããã€ãã®ãšããžã±ãŒã¹ã§ã¯ eval() ã new Function() ã®ã©ã¡ããé©ããªãããšããããŸããå¯èœã§ããã°ã次ã®ãããªä»£æ¿ææ®µããŸãæ€èšããŠãã ããïŒ
ãªããžã§ã¯ãã®ããããã£ã¢ã¯ã»ã¹æïŒ
// eval() 䜿çšïŒæªãäŸïŒ
const propName = 'username';
const value = eval('user.' + propName);
// ãã©ã±ãã衚èšäœ¿çšïŒè¯ãäŸïŒ
const value = user[propName];
ã€ãã³ããã³ãã©ãŒç»é²æïŒ
// ã€ã³ã©ã€ã³æååïŒæªãäŸïŒ
element.setAttribute("onclick", "handleClick()");
// ã€ãã³ããªã¹ããŒäœ¿çšïŒè¯ãäŸïŒ
element.addEventListener("click", handleClick);
ã¿ã€ããŒé¢æ°äœ¿çšæïŒ
// æååã³ãŒãïŒæªãäŸïŒ
setTimeout("console.log('Hello')", 1000);
// 颿°æž¡ãïŒè¯ãäŸïŒ
setTimeout(() => console.log('Hello'), 1000);
ããå®å šãªã³ãŒããžåããŠ
eval() ã¯äŸ¿å©ããã«èŠããŸãããã»ãã¥ãªãã£ãšããã©ãŒãã³ã¹ã®èгç¹ããé倧ãªåé¡ãåŒãèµ·ããå¯èœæ§ããããŸããnew Function() ã¯ã°ããŒãã«ã¹ã³ãŒãã®å¶çŽãéããŠãããã®ãªã¹ã¯ã倧ãã軜æžããŠããããããè¯ãä»£æ¿ææ®µã§ãã
ãã¡ãããæåã®æ¹æ³ã¯åçã³ãŒãå®è¡èªäœãé¿ããããšã§ãããããã©ãããŠãé¿ããããªãç¶æ³ã§ããã°ãnew Function() ãéžã³ãå
¥åå€ã®æ€èšŒã培åºããããšãå¿ããªãã§ãã ããã
ã»ãã¥ãªãã£ã¯åŠ¥åã§ããªãé åã§ãããã£ãäžè¡ã®ã³ãŒããã¢ããªã±ãŒã·ã§ã³å šäœã®å®å šæ§ãå·Šå³ãããšããç¹ããåžžã«å¿ã«çããªããéçºãé²ããŠãã ãã :)