Generating hard to guess content URLs in Sling

In RESTful apps, it is often useful to create hard to guess URLs, as a simple privacy device.

Here’s a self-explaining example (with hardcoded parameters) of how to do that in Sling.

After installing this component, an HTTP POST to a node named ‘foo’ creates a child node with a somewhat long hex string as its name, instead of the usual simple names generated by Sling.

package foo;

import java.util.Random;

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.servlets.post.NodeNameGenerator;

/** Example that generates hard-to-guess node names in Sling,
 * for nodes added under nodes named 'foo' 
 * 
 * To test, build and install a bundle that includes this component,
 * and run
 * <pre>
 *   curl -X MKCOL http://admin:admin@localhost:4502/foo
 *   curl -F title=bar http://admin:admin@localhost:4502/foo/
 * </pre>
 * The output of the second curl call should return something like
 * <pre>
 *   Content created /foo/dd712dd234637bb9a9a3b3a10221eb1f
 * </pre>
 * Which is the path of the created node. 
 */
@Component
@Service
public class FooNodeNameGenerator implements NodeNameGenerator {
    private static final Random random = new Random(System.currentTimeMillis());
    
    /** @inheritDoc */
    public String getNodeName(
            SlingHttpServletRequest request, 
            String parentPath, 
            boolean requirePrefix, 
            NodeNameGenerator defaultNng) 
    {
        if(parentPath.endsWith("/foo")) {
            final StringBuilder name = new StringBuilder();
            for(int i=0; i < 2; i++) {
                name.append(Long.toHexString(random.nextLong()));
            }
            return name.toString();
        }
        return null;
    }
}

2 Responses to Generating hard to guess content URLs in Sling

  1. Christian Sprecher says:

    Hmm, why would you want to do that? In order to have privacy, other controls are more appropriate, e.g. authentication and authorization.

    And the created URLs will eventually be used in hyperlinks, with no resulting privacy gains.

    Of course you might want to check that the URL name itself doesn’t give away too many informations, which is an argument for such an obfuscation.

    • bdelacretaz says:

      Authentication and authorization are fine for strong security, but in some cases it’s more convenient to avoid user accounts, and just have hard to guess URLs as a simple “security by obscurity” mechanism.

      http://quicktopic.com/ uses that for example, if you create a message board it gets an URL like http://www.quicktopic.com/45/H/43dMTfPX5yLV which is impossible to guess but easy to share.

      People don’t need to create an account there to post to such a message board, they just need to know the secret URL, that you’re supposed to share privately with them. It saves the hassle of creating accounts, which is fine for secret-but-not-that-much stuff.

      The same applies to short-lived auto-expiring URLs used to give access to parts of your content for a few hours, without requiring accounts yet without being public.

      Of course, posting such an URL on a blog is not a good idea unless you’re just making an example ;-)

%d bloggers like this: