jspaemhtl

Cross site scripting protection turned off


I came across this snippet of code in the demo We.Retail AEM project:

<template 
  data-sly-template.include="${@ categories='Client Library categories', mode='optional: JS or CSS, case-insensitve'}"
  data-sly-use.clientlib="${'libs.granite.sightly.templates.ClientLibUseObject' @ categories=categories, mode=mode}">
    ${clientlib.include @ context='unsafe'}
</template>

Can anyone help me understand what the purpose of turning XSS protection off would be in this context?

Thanks in advance!


Solution

  • HTL has inbuilt XSS protection.

    When you use context = 'unsafe', it disables escaping and XSS protection completely. Once 'XSS' protection is disabled your site may be vulnerable to cross site scripting. This is one of the reasons why HTL is preferred over traditional JSP.


    Having said this, there are times when none of the other contexts provided by HTL will suit your needs and using unsafe context would be the last resort. The snippet you've posted is one such example. You are passing arguments(categories and mode) to a java class (ClientLibUseObject.java) which initializes BINDINGS_CATEGORIES and BINDINGS_MODE and then the include method is called which writes these parameters to com.adobe.granite.ui.clientlibs.HtmlLibraryManager object.

    HtmlLibraryManager provides methods which includes js/css files stored in the repository and resolves categories and dependencies. In the list of contexts available, there is nothing there which satisfies this use case, hence they've used unsafe.

    public class ClientLibUseObject implements Use {
    
        private static final String BINDINGS_CATEGORIES = "categories";
        private static final String BINDINGS_MODE = "mode";
    
        private HtmlLibraryManager htmlLibraryManager = null;
        private String[] categories;
        private String mode;
        private SlingHttpServletRequest request;
        private PrintWriter out;
        private Logger log;
    
        public void init(Bindings bindings) {
            Object categoriesObject = bindings.get(BINDINGS_CATEGORIES);
            log = (Logger) bindings.get(SlingBindings.LOG);
            if (categoriesObject != null) {
                if (categoriesObject instanceof Object[]) {
                    Object[] categoriesArray = (Object[]) categoriesObject;
                    categories = new String[categoriesArray.length];
                    int i = 0;
                    for (Object o : categoriesArray) {
                        if (o instanceof String) {
                            categories[i++] = ((String) o).trim();
                        }
                    }
                } else if (categoriesObject instanceof String) {
                    categories = ((String) categoriesObject).split(",");
                    int i = 0;
                    for (String c : categories) {
                        categories[i++] = c.trim();
                    }
                }
                if (categories != null && categories.length > 0) {
                    mode = (String) bindings.get(BINDINGS_MODE);
                    request = (SlingHttpServletRequest) bindings.get(SlingBindings.REQUEST);
                    SlingScriptHelper sling = (SlingScriptHelper) bindings.get(SlingBindings.SLING);
                    htmlLibraryManager = sling.getService(HtmlLibraryManager.class);
                }
            }
        }
    
        public String include() {
            StringWriter sw = new StringWriter();
            try {
                if (categories == null || categories.length == 0)  {
                    log.error("'categories' option might be missing from the invocation of the /libs/granite/sightly/templates/clientlib.html" +
                            "client libraries template library. Please provide a CSV list or an array of categories to include.");
                } else {
                    PrintWriter out = new PrintWriter(sw);
                    if ("js".equalsIgnoreCase(mode)) {
                        htmlLibraryManager.writeJsInclude(request, out, categories);
                    } else if ("css".equalsIgnoreCase(mode)) {
                        htmlLibraryManager.writeCssInclude(request, out, categories);
                    } else {
                        htmlLibraryManager.writeIncludes(request, out, categories);
                    }
                }
            } catch (IOException e) {
                log.error("Failed to include client libraries {}", categories);
            }
            return sw.toString();
        }
    }
    

    List of available display contexts.

    More about XSS and different ways XSS can be used to attack sites here