luci-base: escape path strings and field parameter

Prevent various XSS vectors by not interpolating field and path values
verbatim into script and html contexts.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
Jo-Philipp Wich 2018-04-07 11:43:44 +02:00
parent 83a59dc0f7
commit 5c31937a0f

View file

@ -22,9 +22,9 @@
<script type="text/javascript"> <script type="text/javascript">
function callback(path) { function callback(path) {
if( window.opener ) { if( window.opener ) {
var input = window.opener.document.getElementById('<%=luci.http.formvalue('field')%>'); var input = window.opener.document.getElementById(decodeURIComponent('<%=luci.http.urlencode(luci.http.formvalue('field'))%>'));
if( input ) { if( input ) {
input.value = path; input.value = decodeURIComponent(path);
window.close(); window.close();
} }
} }
@ -48,33 +48,44 @@
end end
end end
local filepath = table.concat( path, '/' ) local filestat = nixio.fs.stat(table.concat(path, '/'))
local filestat = nixio.fs.stat( filepath ) local baseurl = { 'admin', 'filebrowser' }
local baseurl = luci.dispatcher.build_url('admin', 'filebrowser')
if filestat and filestat.type == "reg" then if filestat and filestat.type == "reg" then
table.remove( path, #path ) path[#path] = ''
filepath = table.concat( path, '/' ) .. '/' elseif not (filestat and filestat.type == "dir") then
elseif not ( filestat and filestat.type == "dir" ) then path = { '', '' }
path = { '' }
filepath = '/'
else else
filepath = filepath .. '/' path[#path+1] = ''
end end
local entries = nixio.util.consume((nixio.fs.dir(filepath))) filepath = table.concat(path, '/')
local entries = {}
local _, e
for _, e in luci.util.vspairs(nixio.util.consume((nixio.fs.dir(filepath)))) do
local p = filepath .. e
local s = nixio.fs.stat(p)
if s then
entries[#entries+1] = {
name = e,
path = p,
type = s.type
}
end
end
-%> -%>
<div id="path"> <div id="path">
Location: Location:
<% for i, dir in ipairs(path) do %> <% for i, dir in ipairs(path) do %>
<% if i == 1 then %> <% if i == 1 then %>
<a href="<%=baseurl%>?field=<%=field%>">(root)</a> <a href="<%=url(unpack(baseurl))%>?field=<%=luci.http.urlencode(field)%>">(root)</a>
<% elseif next(path, i) then %> <% elseif next(path, i) then %>
<% baseurl = baseurl .. '/' .. dir %> <% baseurl[#baseurl+1] = luci.http.urlencode(dir) %>
/ <a href="<%=baseurl%>?field=<%=field%>"><%=dir%></a> / <a href="<%=url(unpack(baseurl))%>?field=<%=luci.http.urlencode(field)%>"><%=pcdata(dir)%></a>
<% else %> <% else %>
<% baseurl = baseurl .. '/' .. dir %> <% baseurl[#baseurl+1] = luci.http.urlencode(dir) %>
/ <%=dir%> / <%=pcdata(dir)%>
<% end %> <% end %>
<% end %> <% end %>
</div> </div>
@ -83,23 +94,17 @@
<div id="listing"> <div id="listing">
<ul> <ul>
<% for _, e in luci.util.vspairs(entries) do <% for _, e in ipairs(entries) do if e.type == 'dir' then -%>
local stat = nixio.fs.stat(filepath..e)
if stat and stat.type == 'dir' then
-%>
<li class="dir"> <li class="dir">
<img src="<%=resource%>/cbi/folder.gif" alt="<%:Directory%>" /> <img src="<%=resource%>/cbi/folder.gif" alt="<%:Directory%>" />
<a href="<%=baseurl%>/<%=e%>?field=<%=field%>"><%=e%>/</a> <a href="<%=url(unpack(baseurl))%>/<%=luci.http.urlencode(e.name)%>?field=<%=luci.http.urlencode(field)%>"><%=pcdata(e.name)%>/</a>
</li> </li>
<% end end -%> <% end end -%>
<% for _, e in luci.util.vspairs(entries) do <% for _, e in ipairs(entries) do if e.type ~= 'dir' then -%>
local stat = nixio.fs.stat(filepath..e)
if stat and stat.type ~= 'dir' then
-%>
<li class="file"> <li class="file">
<img src="<%=resource%>/cbi/file.gif" alt="<%:File%>" /> <img src="<%=resource%>/cbi/file.gif" alt="<%:File%>" />
<a href="#" onclick="callback('<%=filepath..e%>')"><%=e%></a> <a href="#" onclick="callback('<%=luci.http.urlencode(e.path)%>')"><%=pcdata(e.name)%></a>
</li> </li>
<% end end -%> <% end end -%>
</ul> </ul>