summaryrefslogtreecommitdiffstats
path: root/bug70741.patch
blob: 1704bfb7f4ce918e784c0dab4e0f2dd967a97b9c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
Backported from 5.5 for 5.4 by Remi Collet

From 1785d2b805f64eaaacf98c14c9e13107bf085ab1 Mon Sep 17 00:00:00 2001
From: Stanislav Malyshev <stas@php.net>
Date: Mon, 28 Dec 2015 12:42:44 -0800
Subject: [PATCH] Fixed bug #70741: Session WDDX Packet Deserialization Type
 Confusion Vulnerability

---
 NEWS                         |   4 ++
 ext/wddx/tests/bug70741.phpt |  26 ++++++++
 ext/wddx/wddx.c              | 139 ++++++++++++++++++++++---------------------
 3 files changed, 101 insertions(+), 68 deletions(-)
 create mode 100644 ext/wddx/tests/bug70741.phpt

diff --git a/ext/wddx/tests/bug70741.phpt b/ext/wddx/tests/bug70741.phpt
new file mode 100644
index 0000000..9c7e09b
--- /dev/null
+++ b/ext/wddx/tests/bug70741.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Bug #70741 (Session WDDX Packet Deserialization Type Confusion Vulnerability)
+--SKIPIF--
+<?php
+if (!extension_loaded("wddx")) print "skip";
+?>
+--FILE--
+<?php
+ini_set('session.serialize_handler', 'wddx');
+session_start();
+
+$hashtable = str_repeat('A', 66);
+$wddx = "<?xml version='1.0'?>
+<wddxPacket version='1.0'>
+<header/>
+	<data>
+		<string>$hashtable</string>
+	</data>
+</wddxPacket>";
+session_decode($wddx);
+?>
+DONE
+--EXPECTF--
+
+Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s on line %d
+DONE
\ No newline at end of file
diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c
index 45beaece..8017620 100644
--- a/ext/wddx/wddx.c
+++ b/ext/wddx/wddx.c
@@ -308,7 +308,10 @@ PS_SERIALIZER_DECODE_FUNC(wddx)
 	MAKE_STD_ZVAL(retval);
 
 	if ((ret = php_wddx_deserialize_ex((char *)val, vallen, retval)) == SUCCESS) {
-
+		if (Z_TYPE_P(retval) != IS_ARRAY) {
+			zval_ptr_dtor(&retval);
+			return FAILURE;
+		}
 		for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(retval));
 			 zend_hash_get_current_data(Z_ARRVAL_P(retval), (void **) &ent) == SUCCESS;
 			 zend_hash_move_forward(Z_ARRVAL_P(retval))) {