geonetwork / core-geonetwork

GeoNetwork is a catalog application to manage spatially referenced resources. It provides powerful metadata editing and search functions as well as an interactive web map viewer. It is currently used in numerous Spatial Data Infrastructure initiatives across the world.
http://geonetwork-opensource.org/
GNU General Public License v2.0
428 stars 489 forks source link

XSS Cross Site Scripting - Reflected #2002

Open lfrz opened 7 years ago

lfrz commented 7 years ago

software component: GeoNetwork (opensource) version: 3.2.1.0 test date: 21.04.2017

concerned parameter:

• /./proxy [url parameter] • /./srv/eng/thesaurus.download [ref parameter] • /./srv/ger/info [type parameter] • /./srv/ger/q [from parameter] • /./srv/ger/q [resultType parameter] • /./srv/ger/q [to parameter] • /./srv/ger/qi [from parameter] • /./srv/ger/qi [resultType parameter] • /./srv/ger/qi [to parameter] • /./srv/ger/suggest [field parameter] • /./srv/ger/thesaurus.keyword [multiple parameter] • /./srv/ger/thesaurus.keyword [textgroupOnly parameter] • /./srv/api/0.1/tools/i18n/db [type parameter] • /./srv/api/records/22EEE036-ECC1-4168-8AFF-7515C8E83B37/related [type parameter] • /./srv/api/records/a1a731ba-55a5-4173-8883-c98fb0472b64/related [type parameter] • /./srv/api/records/d1b8e5dc-98f7-4656-82dd-1d62746f8681/related [type parameter] • /./srv/api/records/duplicate [isChildOfSource parameter] • /./srv/api/records/duplicate [isVisibleByAllGroupMembers parameter] • /./srv/api/records/duplicate [metadataType parameter] • /./srv/api/records/fc083a83-a047-4b69-b105-15507a4ba951/related [type parameter] • /./srv/api/registries/vocabularies/search [thesaurus parameter] • /./srv/api/registries/vocabularies/search [type parameter] • /./srv/ger/suggest [q parameter]

Proof-of-concept: xss1 example URL 1 exaple URL 2

josegar74 commented 7 years ago

There's a related issue opened time ago https://github.com/geonetwork/core-geonetwork/issues/1415, there's a long discussion about possible solutions, but afaik no actions done yet.

josegar74 commented 7 years ago

For the new API I'm thinking about implementing a solution using a filter like: https://dzone.com/articles/stronger-anti-cross-site

Other simple solution, that should work for ApiError is to process the values to remote scripttags with something like this:

   this.description = Util.cleanScriptTag(description);
  /**
     * Removes <script>, </scripts> tags from the provided string.
     *
     * @param text
     * @return
     */
    public static String cleanScriptTag(String text) {

        if (StringUtils.isNotEmpty(text)) {
            String scriptRegex = "<(/)?[ ]*script[^>]*>";
            Pattern pattern = Pattern.compile(scriptRegex, Pattern.CASE_INSENSITIVE);

            Matcher matcher = pattern.matcher(text);
            StringBuffer str = new StringBuffer(text.length());
            while (matcher.find()) {
                matcher.appendReplacement(str, Matcher.quoteReplacement(" "));
            }
            matcher.appendTail(str);
            text = str.toString();
        }

        return text;
    }

The 2on option solves the issues with Json errors, for example if setting an parameter with invalid value that returns this json with XSS attack:

{
  "message": "MethodArgumentTypeMismatchException",
  "code": "runtime_exception",
  "description": "Failed to convert value of type [java.lang.String] to required type [org.fao.geonet.api.records.model.related.RelatedItemType[]]; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [org.fao.geonet.api.records.model.related.RelatedItemType] for value '<script>alert('1');</script>'; nested exception is java.lang.IllegalArgumentException: No enum constant org.fao.geonet.api.records.model.related.RelatedItemType.<script>alert('1');</script>"
}

But first option seem more robust as processes parameters/headers, although not sure if a good option for 3.2.x branch in case can cause unwanted side effects. What do you think @fxprunayre ?