CVE-2018-6360 (Lua, published 2018-01-28T02:29Z)
Description: value: mpv through 0.28.0 allows remote attackers to execute arbitrary code via a crafted web site, because it reads HTML documents containing VIDEO elements, and accepts arbitrary URLs in a src attribute without a protocol whitelist in player/lua/ytdl_hook.lua. For example, an av://lavfi:ladspa=file= URL signifies that the product should call dlopen on a shared object file located at an arbitrary local pathname. The issue exists because the product does not consider that youtube-dl can provide a potentially unsafe URL.
Severity: MEDIUM (CVSS v3 base score: 8.8)
Weakness: CWE-20 \u2014 Improper Input Validation
The product receives input or data, but it does
        not validate or incorrectly validates that the input has the
        properties that are required to process the data safely and
        correctly.
Repository: https://github.com/mpv-player/mpv
Files changed:
player/lua/ytdl_hook.lua
Commit message: ytdl_hook: whitelist protocols from urls retrieved from youtube-dl

Not very clean since there's a lot of potential unsafe urls that youtube-dl
can give us, depending on whether it's a single url, split tracks,
playlists, segmented dash, etc.


Vulnerable code:
                    edl_track or track.url, "auto",
                streamurl = edl_track or track.url
    mp.set_property("stream-open-filename", streamurl:gsub("^data:", "data://", 1))
                    if not (site:find("https?://") == 1) then
                        site = "ytdl://" .. site
                    table.insert(playlist, site)
                mp.set_property("stream-open-filename", "memory://" .. table.concat(playlist, "\n"))

Fixed code:
function Set (t)
    local set = {}
    for _, v in pairs(t) do set[v] = true end
    return set
end

local safe_protos = Set {
    "http", "https", "ftp", "ftps",
    "rtmp", "rtmps", "rtmpe", "rtmpt", "rtmpts", "rtmpte",
    "data"
}

        if not url_is_safe(join_url(base, fragment)) then
            return nil
        end
local function url_is_safe(url)
    local proto = type(url) == "string" and url:match("^(.+)://") or nil
    local safe = proto and safe_protos[proto]
    if not safe then
        msg.error(("Ignoring potentially unsafe url: '%s'"):format(url))
    end
    return safe
end

        elseif not url_is_safe(mpd_url) then
            return
            local url = edl_track or track.url
            if not url_is_safe(url) then
                return
            end
                    url, "auto",
                streamurl = url
    streamurl = streamurl:gsub("^data:", "data://", 1)

    if not url_is_safe(streamurl) then
        return
    end

    mp.set_property("stream-open-filename", streamurl)
                    -- links with only youtube id as returned by --flat-playlist
                    if not site:find("://") then
                        table.insert(playlist, "ytdl://" .. site)
                    elseif url_is_safe(site) then
                        table.insert(playlist, site)
                if #playlist > 0 then
                    mp.set_property("stream-open-filename", "memory://" .. table.concat(playlist, "\n"))
                end