Page MenuHomePhabricator

0001-SECURITY-Escape-angle-brackets-numerically-in-string.patch

Authored By
Anomie
Jun 13 2017, 3:55 PM
Size
3 KB
Referenced Files
None
Subscribers
None

0001-SECURITY-Escape-angle-brackets-numerically-in-string.patch

From 53071d588f7ac20f1467fb5952e968c1f8e2bb69 Mon Sep 17 00:00:00 2001
From: Brad Jorsch <bjorsch@wikimedia.org>
Date: Tue, 13 Jun 2017 11:51:12 -0400
Subject: [PATCH] SECURITY: Escape angle brackets numerically in strings and
identifiers
This makes the sanitized output safer to embed in HTML.
Bug: T167812
Change-Id: I1c1ff660eabd7cd7d698439950d73bb68c38ad23
---
src/Objects/Token.php | 8 +++++---
tests/Objects/TokenTest.php | 4 ++++
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/src/Objects/Token.php b/src/Objects/Token.php
index 225ce1e..150d61a 100644
--- a/src/Objects/Token.php
+++ b/src/Objects/Token.php
@@ -360,13 +360,14 @@ class Token extends ComponentValue {
* CSS's input conversion rules, and so need escaping.
* - Other non-space whitespace and controls don't need escaping, but it's
* safer to do so.
+ * - Angle brackets are escaped numerically to make it safer to embed in HTML.
*
* @param string $s
* @return string
*/
private static function escapeString( $s ) {
return preg_replace_callback(
- '/[^ \P{Z}]|[\p{Cc}\p{Cf}\p{Co}\p{Cs}"\x5c]/u',
+ '/[^ \P{Z}]|[\p{Cc}\p{Cf}\p{Co}\p{Cs}"\x5c<>]/u',
[ __CLASS__, 'escapePregCallback' ],
$s
);
@@ -380,8 +381,9 @@ class Token extends ComponentValue {
private static function escapePregCallback( $m ) {
// Newlines, carriage returns, form feeds, and hex digits have to be
// escaped numerically. Other non-space whitespace and controls don't
- // have to be, but it's saner to do so.
- if ( preg_match( '/[^ \P{Z}]|[\p{Cc}\p{Cf}\p{Co}\p{Cs}0-9a-fA-F]/u', $m[0] ) ) {
+ // have to be, but it's saner to do so. Angle brackets are escaped
+ // numerically too to make it safer to embed in HTML.
+ if ( preg_match( '/[^ \P{Z}]|[\p{Cc}\p{Cf}\p{Co}\p{Cs}0-9a-fA-F<>]/u', $m[0] ) ) {
return sprintf( '\\%x ', \UtfNormal\Utils::utf8ToCodepoint( $m[0] ) );
}
return '\\' . $m[0];
diff --git a/tests/Objects/TokenTest.php b/tests/Objects/TokenTest.php
index b0f5517..414e6b0 100644
--- a/tests/Objects/TokenTest.php
+++ b/tests/Objects/TokenTest.php
@@ -286,6 +286,7 @@ class TokenTest extends \PHPUnit_Framework_TestCase {
[ new Token( Token::T_IDENT, "foo bar" ), 'foo\ bar' ],
[ new Token( Token::T_IDENT, "foo\nbar" ), 'foo\a bar' ],
[ new Token( Token::T_IDENT, "foo\x7fbar" ), 'foo\7f bar' ],
+ [ new Token( Token::T_IDENT, "<foo>" ), '\3c foo\3e ' ],
[ new Token( Token::T_FUNCTION, 'foobar' ), 'foobar(' ],
[ new Token( Token::T_FUNCTION, 'foobar(' ), 'foobar\((' ],
@@ -340,9 +341,12 @@ class TokenTest extends \PHPUnit_Framework_TestCase {
'#foo\a bar' ],
[ new Token( Token::T_HASH, [ 'value' => "foo\x7fbar", 'typeFlag' => 'unrestricted' ] ),
'#foo\7f bar' ],
+ [ new Token( Token::T_HASH, [ 'value' => "<foo>", 'typeFlag' => 'unrestricted' ] ),
+ '#\3c foo\3e ' ],
[ new Token( Token::T_STRING, 'foobar' ), '"foobar"' ],
[ new Token( Token::T_STRING, "foo\"b\\a\nr\r\f\t\x7f?" ), '"foo\"b\\\\a\a r\d \c \9 \7f ?"' ],
+ [ new Token( Token::T_STRING, "<foo>" ), '"\3c foo\3e "' ],
[ new Token( Token::T_URL, 'http://www.example.com/' ), 'url("http://www.example.com/")' ],
[ new Token( Token::T_URL, "foo\"b\\a\nr" ), 'url("foo\"b\\\\a\a r")' ],
--
2.11.0

File Metadata

Mime Type
text/x-diff
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4713824
Default Alt Text
0001-SECURITY-Escape-angle-brackets-numerically-in-string.patch (3 KB)

Event Timeline