1

サイトで多数の iframe バスター スクリプトをホストするように依頼されています。これにより、外部ドメインから iframe に配信された広告を、それらの外部のホスト ページに展開することができます。ホスティング プロバイダーは、これらのスクリプトのセキュリティ ホールに注意するよう警告しています。具体的には、Javascript の一部を任意の URL からサイトにロードできるようにすることで、クロスサイト スクリプティング ホールを作成するものがあると彼らは言います。

スクリプトを実装するには、サイトで HTML ページをホストします。広告プロバイダー Atlas の例を見ています。この場合、URL はhttp://domain.com/atlas/atlas_rm.htmのようになります。そのページには、外部 URL に src を含むスクリプト タグが含まれており、含まれている JS は次のとおりです。

var ARMIfbLib = function () {

    function documentWrite(htmlString) {
        document.write(htmlString);
    }

    function writeIframeBustingScript() {
        var imgSrvPath = getTlDirectoryFromQueryString(getParameterString());
        if (imgSrvPath != "") {
            var scriptURL = imgSrvPath + getScriptFileName();
            ARMIfbLib.DocumentWrite("<script language='javascript' type='text/javascript' src='" + scriptURL + "'></scr" + "ipt>");
        }
    }

    return {
        WriteIframeBustingScript: writeIframeBustingScript,
        DocumentWrite: documentWrite
    }

}();

function getValueFromDelimitedString(paramKey, delimiter, queryString) {
    if (paramKey == "imgSrv")
        return getValueFromProperties();

    var re = new RegExp(paramKey + "=" + "(.*?)" + "(" + delimiter + "|$)");
    var matchArray = queryString.match(re);
    if (matchArray == null)
        return "";
    else
        return matchArray[1];
}

function getValueFromProperties() {
    var iframename = unescape(self.name);
    if (iframename.indexOf("<form") >= 0) {
        var params = iframename.split("<input ");
        for (var i = 1; i < params.length; i++) {
            var parts = params[i].split(" ");
            for (var j = 0; j < parts.length; j++) {
                var param = parts[j].split("=");
                if (param[0].indexOf("name") >= 0 && param[1].indexOf("TL_files_path") >= 0) {
                    param = parts[j + 1].split("=");
                    if (param[0].indexOf("value") >= 0) {
                        var value = param[1].substr(1, param[1].indexOf(">"));
                        value = value.substr(value, value.lastIndexOf("/"));
                        value = value.substr(value, value.lastIndexOf("/") + 1);
                        return unescape(value);
                    }
                }
            }
        }
    }
    else if (iframename.indexOf("adparamdelim") >= 0) {
        var params = iframename.split("adparamdelim");
        for (var i = 0; i < params.length; i++) {
            var param = params[i].split("=");
            if (param[0].indexOf("TL_files_path") >= 0) {
                var value = param[1];
                value = value.substr(value, value.lastIndexOf("/"));
                value = value.substr(value, value.lastIndexOf("/") + 1);
                return value;
            }
        }
    }
    else if (/^\{.*\}$/.test(iframename)) {
        try {
            eval('var results = ' + iframename);
            var value = results.TL_files_path;
            value = value.substr(value, value.lastIndexOf("/"));
            value = value.substr(value, value.lastIndexOf("/") + 1);
            return value;
        } catch (e) {
            return "";
        }
    } else {
        var params = iframename.split("&");
        for (var i = 0; i < params.length; i++) {
            var param = params[i].split("=");
            if (param[0].indexOf("TL_files_path") >= 0) {
                var value = unescape(param[1]);
                value = value.substr(value, value.lastIndexOf("/"));
                value = value.substr(value, value.lastIndexOf("/") + 1);
                return value;
            }
        }
    }
    return "";
}

function getTlDirectoryFromQueryString(sLocation) {
    var queryVar = getValueFromDelimitedString("imgSrv", "a4edelim", sLocation);
    var temp = queryVar.substr(0, queryVar.lastIndexOf("/"));
    var tlDir = temp.substr(0, temp.lastIndexOf("/") + 1);
    return tlDir;
}

function getDocumentQueryString() {
    return window.location.search;
}

function getIframeParameterString() {
    var ret = "";
    var qs = getDocumentQueryString();
    if (qs.length > 0)
        ret = qs.substring(1);
    return ret;
}

function getScriptParameterString() {
    var ret = "";
    var scripts = document.getElementsByTagName('script');
    for (var i = 0; i < scripts.length; i++) {
        var scriptSrc = scripts[i].src;
        if (scriptSrc.toLowerCase().indexOf("newiframescript") != -1 && scriptSrc.indexOf("?") != -1) {
            ret = scriptSrc.substr(scriptSrc.indexOf("?") + 1);
            break;
        }
    }
    return ret;
}

function getParameterString() {
    var qs = getIframeParameterString();
    if (qs.length > 0 && qs.indexOf("a4edelim") > 0)
        return qs;
    return getScriptParameterString();
}

function getScriptFileName() {
    var armdelim = ",";
    var fileName = "ifb.0";
    var queryString = getParameterString();
    var parmValue = "";
    if (queryString.length > 0) {
        parmValue = getValueFromDelimitedString("armver", "a4edelim", queryString);
    }
    if (parmValue.length > 0) {
        var fileNames = parmValue.split(armdelim);
        for (var i = 0; i < fileNames.length; i++) {
            if (fileNames[i].toLowerCase().indexOf("ifb") != -1) {
                fileName = fileNames[i];
                break;
            }
        }
    }
    return fileName + ".js";
}

if (typeof(armTestMode) == "undefined") {
    ARMIfbLib.WriteIframeBustingScript();
}

私はこれが何をしているのかを理解するためにこれを研究するのに数時間を費やしましたが、さまざまな関数呼び出しに行き詰まりました。クエリ文字列パラメーターまたは iframe の名前から値を取得しているようです。おそらく、広告が含まれている iframe です。

このJSが何をしているのか誰でも理解できますか? XSS の観点からはかなり安全に見えますか?

=========================================

編集

参考までに、この懸念をプロバイダーに伝えたところ、次のような回答がありました。

  1. iframe バスター ページは、iframe 内にある場合にのみ機能します
  2. ftlocal.html ファイルのコードは、iframe のドメインが既に親ページのドメインと同じである場合にのみ機能します。そのため、いずれのコードもすでに親ページにアクセスできます。
4

1 に答える 1

1

JSスクリプトは、動的に生成されたスクリプトタグをページに作成します。

ARMIfbLib.DocumentWrite("<script language='javascript' type='text/javascript' src='" + scriptURL + "'></scr" + "ipt>");

どこから来たのかを掘り下げると、それは(クエリ文字列)にscriptURL渡されたパラメータのように見えます。window.location.search

私が見る限り、これにより、クエリ文字列で任意のスクリプトをページに渡すことができ、ページのフレーム名でドメインを設定できるように効果的に保護されていない限り、DOMXSSに対して脆弱になります。独自のドメインを使用してテストを行い、検索されたクエリ文字列変数(JSの文字列リテラル)を渡します。

于 2013-02-15T15:01:55.453 に答える