1

ファイルまたは他のIOソースから、完全に信頼できるわけではないサードパーティから提供されるLuaテーブルが必要だとしましょう。

「{['valid'] = 10}」のような文字列としてテーブルを取得し、次のようにロードできます

externalTable = loadstring("return " .. txtTable)()

しかし、これはコードインジェクションへの違反を引き起こします。つまり: txtTable = os.execute('rm -rf /')

だから私はこのサニタイズ機能を実行しました:

function safeLoadTable(txtTable)
    txtTable = tostring(txtTable)
    if (string.find(txtTable, "(", 1, true)) 
        then return nil end
    local _start = string.find(txtTable, "{", 1, true)
    local _end = string.find(string.reverse(txtTable), "}", 1, true)
    if (_start == nil or _end == nil)
        then return nil end
    txtTable = string.sub(txtTable, _start,  #txtTable - _end + 1)
    print("cropped to ", txtTable)
    local pFunc = loadstring("return " .. txtTable)
    if (pFunc) then
        local _, aTable = pcall(pFunc)
        return aTable
    end
end

最悪の場合、nil を返す必要があります。これは、「通常の悪意のある人」に対して安全であると見なすことができます:)

4

4 に答える 4

1

安全ではないと思います。これを試して:

print(safeLoadTable [[{ foo = (function() print"yahoo" end)() } ]])

編集

またはこれ、もっと楽しみのために:

print(safeLoadTable [[{ foo = (function() print(os.getenv "PATH") end)() } ]])

os.getenvただし、それをに置き換えるという代替案は提案しませんos.execute。:-)

問題を解決するのは簡単ではありません。この場合、コード インジェクションの回避はまったく単純ではありません。これを行うときに Lua コードの一部を実行しているためですloadstring。単純な文字列マッチング手法で本当に安全なものはありません。唯一の安全な方法は、Lua テーブル構文のサブセット用のパーサーを実装し、そのパーサーを文字列で使用することです。

ところで、Lua チームでさえ、Lua 5.2 からバイトコード検証機能を削除しました。これは、バイトコードが攻撃を受けやすいことを発見したためであり、バイトコードは Lua ソース コードよりもはるかに単純な言語です。

于 2013-10-08T21:40:51.807 に答える