Here is what I mean with an example under Mac OS X (The same thing will work under Linux): lorens-mac:tmp lcahlander$ ls -al total 8 drwxrwxrwt 9 root wheel 306 Aug 27 12:40 . drwxr-xr-x@ 6 root wheel 204 Dec 10 2009 .. -rw-r--r-- 1 lcahlander wheel 0 Aug 27 11:35 .yjp_ide51928 srwxr-xr-x 1 lcahlander wheel 0 Aug 26 23:15 icssuis501 drwx------ 3 lcahlander wheel 102 Aug 26 23:14 launch-Lk9wGt drwx------ 3 lcahlander wheel 102 Aug 26 23:14 launch-qXSOwK drwx------ 3 lcahlander wheel 102 Aug 26 23:14 launch-y3HLPq drwx------ 3 lcahlander wheel 102 Aug 26 23:14 launchd-131.SHiPK0 -rwx------ 1 root wheel 36 Aug 27 12:40 noread.txt lorens-mac:tmp lcahlander$ who am i lcahlander ttys000 Aug 27 12:39 lorens-mac:tmp lcahlander$ cat noread.txt cat: noread.txt: Permission denied lorens-mac:tmp lcahlander$ You can see that I am not running as root. The listing of the contents of /tmp shows all of the metadata about the contents of /tmp, but I do not have read access to /tmp/noread.txt which is evident when I try to cat the file. On Aug 27, 2010, at 12:28 PM, Loren Cahlander wrote: > When I was thinking through this problem (some of it during sleeping), I was thinking that this original statement was wrong. If the user has read access to a collection, then he/she can see the listing of the collections and resources within the collection. The problem that the WebDAV client was encountering was accessing the creation date, last modified date and the size of the resource when the user does not have read access to the resource. This is wrong. If the user has read access to the parent collection and not to the resource being listed, then the user should have access to the creation date, last modified date and the size of the resource but no to the contents of the resource. > > > In org.exist.xmldb.LocalXMLResource: > > The following: > > public Date getCreationTime() throws XMLDBException { > DBBroker broker = null; > try { > broker = pool.get(user); > DocumentImpl document = getDocument(broker, Lock.NO_LOCK); > if (!document.getPermissions().validate(user, Permission.READ)) > throw new XMLDBException(ErrorCodes.PERMISSION_DENIED, > "permission denied to read resource"); > return new Date(document.getMetadata().getCreated()); > } catch (EXistException e) { > throw new XMLDBException(ErrorCodes.UNKNOWN_ERROR, e.getMessage(), > e); > } finally { > pool.release(broker); > } > } > > public Date getLastModificationTime() throws XMLDBException { > DBBroker broker = null; > try { > broker = pool.get(user); > DocumentImpl document = getDocument(broker, Lock.NO_LOCK); > if (!document.getPermissions().validate(user, Permission.READ)) > throw new XMLDBException(ErrorCodes.PERMISSION_DENIED, > "permission denied to read resource"); > return new Date(document.getMetadata().getLastModified()); > } catch (EXistException e) { > throw new XMLDBException(ErrorCodes.UNKNOWN_ERROR, e.getMessage(), > e); > } finally { > pool.release(broker); > } > } > > /* (non-Javadoc) > * @see org.exist.xmldb.EXistResource#getContentLength() > */ > public int getContentLength() throws XMLDBException { > DBBroker broker = null; > try { > broker = pool.get(user); > DocumentImpl document = getDocument(broker, Lock.NO_LOCK); > if (!document.getPermissions().validate(user, Permission.READ)) > throw new XMLDBException(ErrorCodes.PERMISSION_DENIED, > "permission denied to read resource"); > return document.getContentLength(); > } catch (EXistException e) { > throw new XMLDBException(ErrorCodes.UNKNOWN_ERROR, e.getMessage(), > e); > } finally { > pool.release(broker); > } > } > > To: > > > public Date getCreationTime() throws XMLDBException { > DBBroker broker = null; > try { > LocalCollection parent = (LocalCollection)getParentCollection(); > if (!parent.getCollection().getPermissions().validate(user, Permission.READ)) { > throw new XMLDBException(ErrorCodes.PERMISSION_DENIED, "permission denied to read resource"); > > } > broker = pool.get(user); > DocumentImpl document = getDocument(broker, Lock.NO_LOCK); > return new Date(document.getMetadata().getCreated()); > } catch (EXistException e) { > throw new XMLDBException(ErrorCodes.UNKNOWN_ERROR, e.getMessage(), > e); > } finally { > pool.release(broker); > } > } > > public Date getLastModificationTime() throws XMLDBException { > DBBroker broker = null; > try { > LocalCollection parent = (LocalCollection)getParentCollection(); > if (!parent.getCollection().getPermissions().validate(user, Permission.READ)) { > throw new XMLDBException(ErrorCodes.PERMISSION_DENIED, "permission denied to read resource"); > > } > broker = pool.get(user); > DocumentImpl document = getDocument(broker, Lock.NO_LOCK); > return new Date(document.getMetadata().getLastModified()); > } catch (EXistException e) { > throw new XMLDBException(ErrorCodes.UNKNOWN_ERROR, e.getMessage(), > e); > } finally { > pool.release(broker); > } > } > > /* (non-Javadoc) > * @see org.exist.xmldb.EXistResource#getContentLength() > */ > public int getContentLength() throws XMLDBException { > DBBroker broker = null; > try { > LocalCollection parent = (LocalCollection)getParentCollection(); > if (!parent.getCollection().getPermissions().validate(user, Permission.READ)) { > throw new XMLDBException(ErrorCodes.PERMISSION_DENIED, "permission denied to read resource"); > > } > broker = pool.get(user); > DocumentImpl document = getDocument(broker, Lock.NO_LOCK); > return document.getContentLength(); > } catch (EXistException e) { > throw new XMLDBException(ErrorCodes.UNKNOWN_ERROR, e.getMessage(), > e); > } finally { > pool.release(broker); > } > } > > The same problem exists in org.exist.xmldb.LocalBinaryResource. If I get the community buy in, then I will go ahead and make this change to these two source files. > > This would match our documentation on permissions: > > http://exist-db.org/security.html#permissions > > > Loren > > > > > > > On Aug 26, 2010, at 04:34 PM, Loren Cahlander wrote: > >> Hello folks, >> >> I found a security hole in the XMLDB function module while trying to lock down the WebDAV access so that guest cannot see the database contents. I removed the rwu from other/world on all resources (rwurwu---) and am getting the following while trying to see http://localhost:8080/exist/webdav/db/cms as guest: >> >> >> >> org.exist.xquery.XPathException: Failed to retrieve creation date: permission denied to read resource [at line 56, column 36] >> In function: >> f:format-dateTime(xs:dateTime) [56:18:jar:file:/home/exist/exist/exist-optional.jar!/org/exist/http/webdav/methods/collection.xq] >> f:display-child-resources(xs:string) [96:14:jar:file:/home/exist/exist/exist-optional.jar!/org/exist/http/webdav/methods/collection.xq] >> >> >> The content of the function in collection.xq is: >> >> declare function f:display-child-resources($collection as xs:string) >> as element()* { >> for $child in xdb:get-child-resources($collection) >> order by $child >> return >> <tr> >> <td><a target="_new" href="{$uri}/{$child}">{$child}</a></td> >> <td class="perm">{xdb:permissions-to-string(xdb:get-permissions($collection, $child))}</td> >> <td>{xdb:get-owner($collection, $child)}</td> >> <td>{xdb:get-group($collection, $child)}</td> >> <td>{f:format-dateTime(xdb:created($collection, $child))}</td> >> <td>{f:format-dateTime(xdb:last-modified($collection, $child))}</td> >> <td>{fn:ceiling(xdb:size($collection, $child) div 1024)}</td> >> </tr> >> }; >> >> The xdb:get-child-resources($collection) should only return the resources that the current user has read access to. Here is the content of the method in org.exist.xquery.functions.xmldb.XMLDBGetChildResources >> >> public Sequence evalWithCollection(Collection collection, Sequence[] args, Sequence contextSequence) >> throws XPathException { >> ValueSequence result = new ValueSequence(); >> try { >> String[] collections = collection.listResources(); >> for(int i = 0; i < collections.length; i++) { >> //TODO: Add validating read permission against the current user >> result.add(new StringValue(collections[i])); >> } >> return result; >> } catch (XMLDBException e) { >> throw new XPathException(this, "Failed to retrieve child resources", e); >> } >> } >> >> org.exist.xquery.functions.xmldb.XMLDBGetChildCollections has the same issue: >> >> public Sequence evalWithCollection(Collection collection, Sequence[] args, Sequence contextSequence) >> throws XPathException { >> >> ValueSequence result = new ValueSequence(); >> try { >> String[] collections = collection.listChildCollections(); >> for(int i = 0; i < collections.length; i++) { >> //TODO: Add validating read permission against the current user >> result.add(new StringValue(collections[i])); >> } >> return result; >> } catch (XMLDBException e) { >> throw new XPathException(this, "Failed to retrieve child collections", e); >> } >> } >> > |