From 98f380b2549fdd3c765cdf96ad453584c606c4f8 Mon Sep 17 00:00:00 2001 From: chris48s Date: Thu, 30 May 2019 18:28:37 +0100 Subject: [PATCH] improve logo escaping (#3511) * escape logo in make-badge * 2.2.1 release notes * tighten up validation of logo param --- gh-badges/CHANGELOG.md | 9 ++++++++- gh-badges/lib/make-badge.js | 2 +- gh-badges/package.json | 2 +- lib/logos.js | 8 +++++++- lib/logos.spec.js | 8 ++++++++ 5 files changed, 25 insertions(+), 4 deletions(-) diff --git a/gh-badges/CHANGELOG.md b/gh-badges/CHANGELOG.md index 877e59cd8b..eb3dc7be20 100644 --- a/gh-badges/CHANGELOG.md +++ b/gh-badges/CHANGELOG.md @@ -1,6 +1,13 @@ # Changelog -## 2.2.0 +## 2.2.1 + +### Fixes + +- Escape logos to prevent XSS vulnerability +- Update docblock for BadgeFactory.create() + +## 2.2.0 - 2019-05-29 ### Deprecations diff --git a/gh-badges/lib/make-badge.js b/gh-badges/lib/make-badge.js index 65220991c3..3ce466f35b 100644 --- a/gh-badges/lib/make-badge.js +++ b/gh-badges/lib/make-badge.js @@ -173,7 +173,7 @@ module.exports = function makeBadge({ escapedText: text.map(escapeXml), widths: [leftWidth + 10 + logoWidth + logoPadding, rightWidth + 10], links: links.map(escapeXml), - logo, + logo: escapeXml(logo), logoPosition, logoWidth, logoPadding, diff --git a/gh-badges/package.json b/gh-badges/package.json index b83a9cb846..7ee0566661 100644 --- a/gh-badges/package.json +++ b/gh-badges/package.json @@ -1,6 +1,6 @@ { "name": "gh-badges", - "version": "2.2.0", + "version": "2.2.1", "description": "Shields.io badge library", "keywords": [ "GitHub", diff --git a/lib/logos.js b/lib/logos.js index a818d83dd5..dd639d7bff 100644 --- a/lib/logos.js +++ b/lib/logos.js @@ -1,5 +1,6 @@ 'use strict' +const Joi = require('joi') const { toSvgColor } = require('../gh-badges/lib/color') const coalesce = require('../core/base-service/coalesce') const { svg2base64 } = require('./svg-helpers') @@ -31,7 +32,12 @@ function prependPrefix(s, prefix) { } function isDataUrl(s) { - return s !== undefined && /^(data:)([^;]+);([^,]+),(.+)$/.test(s) + try { + Joi.assert(s, Joi.string().dataUri()) + return true + } catch (e) { + return false + } } // +'s are replaced with spaces when used in query params, this returns them diff --git a/lib/logos.spec.js b/lib/logos.spec.js index 37483def6a..800d22fd66 100644 --- a/lib/logos.spec.js +++ b/lib/logos.spec.js @@ -19,8 +19,16 @@ describe('Logo helpers', function() { }) test(isDataUrl, () => { + //valid input given('data:image/svg+xml;base64,PHN2ZyB4bWxu').expect(true) + + // invalid inputs forCases([given('data:foobar'), given('foobar')]).expect(false) + + // attempted XSS attack + given( + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg=="/>' + ).expect(false) }) test(prepareNamedLogo, () => {