~ubuntu-branches/ubuntu/natty/moin/natty-updates

« back to all changes in this revision

Viewing changes to .pc/CVE-2012-4404.patch/MoinMoin/security/_tests/test_security.py

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2012-10-10 10:20:46 UTC
  • Revision ID: package-import@ubuntu.com-20121010102046-qkpd3oxwo96ch8dl
Tags: 1.9.3-1ubuntu1.11.04.1
* SECURITY UPDATE: cross-site scripting issue in reStructuredText parser
  - debian/patches/CVE-2011-1058.patch: remove javascript support in
    MoinMoin/parser/text_rst.py.
  - CVE-2011-1058
* SECURITY UPDATE: incorrect permissions due to broken virtual group
  names handling
  - debian/patches/CVE-2012-4404.patch: fix group test in
    MoinMoin/security/__init__.py, added test in
    MoinMoin/security/_tests/test_security.py.
  - CVE-2012-4404

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: iso-8859-1 -*-
 
2
"""
 
3
    MoinMoin - MoinMoin.security Tests
 
4
 
 
5
    TODO: when refactoring this, do not use "iter" (is a builtin)
 
6
 
 
7
    @copyright: 2003-2004 by Juergen Hermann <jh@web.de>,
 
8
                2007 by MoinMoin:ReimarBauer,
 
9
                2007 by MoinMoin:ThomasWaldmann
 
10
    @license: GNU GPL, see COPYING for details.
 
11
"""
 
12
 
 
13
import py
 
14
 
 
15
from MoinMoin import security
 
16
acliter = security.ACLStringIterator
 
17
AccessControlList = security.AccessControlList
 
18
 
 
19
from MoinMoin.PageEditor import PageEditor
 
20
from MoinMoin.user import User
 
21
 
 
22
from MoinMoin._tests import become_trusted, create_page, nuke_page
 
23
 
 
24
class TestACLStringIterator(object):
 
25
 
 
26
    def testEmpty(self):
 
27
        """ security: empty acl string raise StopIteration """
 
28
        iter = acliter(self.request.cfg.acl_rights_valid, '')
 
29
        py.test.raises(StopIteration, iter.next)
 
30
 
 
31
    def testWhiteSpace(self):
 
32
        """ security: white space acl string raise StopIteration """
 
33
        iter = acliter(self.request.cfg.acl_rights_valid, '       ')
 
34
        py.test.raises(StopIteration, iter.next)
 
35
 
 
36
    def testDefault(self):
 
37
        """ security: default meta acl """
 
38
        iter = acliter(self.request.cfg.acl_rights_valid, 'Default Default')
 
39
        for mod, entries, rights in iter:
 
40
            assert entries == ['Default']
 
41
            assert rights == []
 
42
 
 
43
    def testEmptyRights(self):
 
44
        """ security: empty rights """
 
45
        iter = acliter(self.request.cfg.acl_rights_valid, 'WikiName:')
 
46
        mod, entries, rights = iter.next()
 
47
        assert entries == ['WikiName']
 
48
        assert rights == []
 
49
 
 
50
    def testSingleWikiNameSingleWrite(self):
 
51
        """ security: single wiki name, single right """
 
52
        iter = acliter(self.request.cfg.acl_rights_valid, 'WikiName:read')
 
53
        mod, entries, rights = iter.next()
 
54
        assert entries == ['WikiName']
 
55
        assert rights == ['read']
 
56
 
 
57
    def testMultipleWikiNameAndRights(self):
 
58
        """ security: multiple wiki names and rights """
 
59
        iter = acliter(self.request.cfg.acl_rights_valid, 'UserOne,UserTwo:read,write')
 
60
        mod, entries, rights = iter.next()
 
61
        assert entries == ['UserOne', 'UserTwo']
 
62
        assert rights == ['read', 'write']
 
63
 
 
64
    def testMultipleWikiNameAndRightsSpaces(self):
 
65
        """ security: multiple names with spaces """
 
66
        iter = acliter(self.request.cfg.acl_rights_valid, 'user one,user two:read')
 
67
        mod, entries, rights = iter.next()
 
68
        assert entries == ['user one', 'user two']
 
69
        assert rights == ['read']
 
70
 
 
71
    def testMultipleEntries(self):
 
72
        """ security: multiple entries """
 
73
        iter = acliter(self.request.cfg.acl_rights_valid, 'UserOne:read,write UserTwo:read All:')
 
74
        mod, entries, rights = iter.next()
 
75
        assert entries == ['UserOne']
 
76
        assert rights == ['read', 'write']
 
77
        mod, entries, rights = iter.next()
 
78
        assert entries == ['UserTwo']
 
79
        assert rights == ['read']
 
80
        mod, entries, rights = iter.next()
 
81
        assert entries == ['All']
 
82
        assert rights == []
 
83
 
 
84
    def testNameWithSpaces(self):
 
85
        """ security: single name with spaces """
 
86
        iter = acliter(self.request.cfg.acl_rights_valid, 'user one:read')
 
87
        mod, entries, rights = iter.next()
 
88
        assert entries == ['user one']
 
89
        assert rights == ['read']
 
90
 
 
91
    def testMultipleEntriesWithSpaces(self):
 
92
        """ security: multiple entries with spaces """
 
93
        iter = acliter(self.request.cfg.acl_rights_valid, 'user one:read,write user two:read')
 
94
        mod, entries, rights = iter.next()
 
95
        assert entries == ['user one']
 
96
        assert rights == ['read', 'write']
 
97
        mod, entries, rights = iter.next()
 
98
        assert entries == ['user two']
 
99
        assert rights == ['read']
 
100
 
 
101
    def testMixedNames(self):
 
102
        """ security: mixed wiki names and names with spaces """
 
103
        iter = acliter(self.request.cfg.acl_rights_valid, 'UserOne,user two:read,write user three,UserFour:read')
 
104
        mod, entries, rights = iter.next()
 
105
        assert entries == ['UserOne', 'user two']
 
106
        assert rights == ['read', 'write']
 
107
        mod, entries, rights = iter.next()
 
108
        assert entries == ['user three', 'UserFour']
 
109
        assert rights == ['read']
 
110
 
 
111
    def testModifier(self):
 
112
        """ security: acl modifiers """
 
113
        iter = acliter(self.request.cfg.acl_rights_valid, '+UserOne:read -UserTwo:')
 
114
        mod, entries, rights = iter.next()
 
115
        assert mod == '+'
 
116
        assert entries == ['UserOne']
 
117
        assert rights == ['read']
 
118
        mod, entries, rights = iter.next()
 
119
        assert mod == '-'
 
120
        assert entries == ['UserTwo']
 
121
        assert rights == []
 
122
 
 
123
    def testIgnoreInvalidACL(self):
 
124
        """ security: ignore invalid acl
 
125
 
 
126
        The last part of this acl can not be parsed. If it ends with :
 
127
        then it will be parsed as one name with spaces.
 
128
        """
 
129
        iter = acliter(self.request.cfg.acl_rights_valid, 'UserOne:read user two is ignored')
 
130
        mod, entries, rights = iter.next()
 
131
        assert entries == ['UserOne']
 
132
        assert rights == ['read']
 
133
        py.test.raises(StopIteration, iter.next)
 
134
 
 
135
    def testEmptyNamesWithRight(self):
 
136
        """ security: empty names with rights
 
137
 
 
138
        The documents does not talk about this case, may() should ignore
 
139
        the rights because there is no entry.
 
140
        """
 
141
        iter = acliter(self.request.cfg.acl_rights_valid, 'UserOne:read :read All:')
 
142
        mod, entries, rights = iter.next()
 
143
        assert entries == ['UserOne']
 
144
        assert rights == ['read']
 
145
        mod, entries, rights = iter.next()
 
146
        assert entries == []
 
147
        assert rights == ['read']
 
148
        mod, entries, rights = iter.next()
 
149
        assert entries == ['All']
 
150
        assert rights == []
 
151
 
 
152
    def testIgnodeInvalidRights(self):
 
153
        """ security: ignore rights not in acl_rights_valid """
 
154
        iter = acliter(self.request.cfg.acl_rights_valid, 'UserOne:read,sing,write,drink,sleep')
 
155
        mod, entries, rights = iter.next()
 
156
        assert rights == ['read', 'write']
 
157
 
 
158
    def testBadGuy(self):
 
159
        """ security: bad guy may not allowed anything
 
160
 
 
161
        This test was failing on the apply acl rights test.
 
162
        """
 
163
        iter = acliter(self.request.cfg.acl_rights_valid, 'UserOne:read,write BadGuy: All:read')
 
164
        mod, entries, rights = iter.next()
 
165
        mod, entries, rights = iter.next()
 
166
        assert entries == ['BadGuy']
 
167
        assert rights == []
 
168
 
 
169
    def testAllowExtraWhitespace(self):
 
170
        """ security: allow extra white space between entries """
 
171
        iter = acliter(self.request.cfg.acl_rights_valid, 'UserOne,user two:read,write   user three,UserFour:read  All:')
 
172
        mod, entries, rights = iter.next()
 
173
        assert  entries == ['UserOne', 'user two']
 
174
        assert rights == ['read', 'write']
 
175
        mod, entries, rights = iter.next()
 
176
        assert entries == ['user three', 'UserFour']
 
177
        assert rights == ['read']
 
178
        mod, entries, rights = iter.next()
 
179
        assert entries == ['All']
 
180
        assert rights == []
 
181
 
 
182
 
 
183
class TestAcl(object):
 
184
    """ security: testing access control list
 
185
 
 
186
    TO DO: test unknown user?
 
187
    """
 
188
    def setup_method(self, method):
 
189
        # Backup user
 
190
        self.savedUser = self.request.user.name
 
191
 
 
192
    def teardown_method(self, method):
 
193
        # Restore user
 
194
        self.request.user.name = self.savedUser
 
195
 
 
196
    def testApplyACLByUser(self):
 
197
        """ security: applying acl by user name"""
 
198
        # This acl string...
 
199
        acl_rights = [
 
200
            "-MinusGuy:read "
 
201
            "+MinusGuy:read "
 
202
            "+PlusGuy:read "
 
203
            "-PlusGuy:read "
 
204
            "Admin1,Admin2:read,write,delete,revert,admin  "
 
205
            "Admin3:read,write,admin  "
 
206
            "JoeDoe:read,write  "
 
207
            "name with spaces,another one:read,write  "
 
208
            "CamelCase,extended name:read,write  "
 
209
            "BadGuy:  "
 
210
            "All:read  "
 
211
            ]
 
212
        acl = security.AccessControlList(self.request.cfg, acl_rights)
 
213
 
 
214
        # Should apply these rights:
 
215
        users = (
 
216
            # user,                 rights
 
217
            # CamelCase names
 
218
            ('Admin1', ('read', 'write', 'admin', 'revert', 'delete')),
 
219
            ('Admin2', ('read', 'write', 'admin', 'revert', 'delete')),
 
220
            ('Admin3', ('read', 'write', 'admin')),
 
221
            ('JoeDoe', ('read', 'write')),
 
222
            ('SomeGuy', ('read', )),
 
223
            # Extended names or mix of extended and CamelCase
 
224
            ('name with spaces', ('read', 'write', )),
 
225
            ('another one', ('read', 'write', )),
 
226
            ('CamelCase', ('read', 'write', )),
 
227
            ('extended name', ('read', 'write', )),
 
228
            # Blocking bad guys
 
229
            ('BadGuy', ()),
 
230
            # All other users - every one not mentioned in the acl lines
 
231
            ('All', ('read', )),
 
232
            ('Anonymous', ('read', )),
 
233
            # we check whether ACL processing stops for a user/right match
 
234
            # with ACL modifiers
 
235
            ('MinusGuy', ()),
 
236
            ('PlusGuy', ('read', )),
 
237
            )
 
238
 
 
239
        # Check rights
 
240
        for user, may in users:
 
241
            mayNot = [right for right in self.request.cfg.acl_rights_valid
 
242
                      if right not in may]
 
243
            # User should have these rights...
 
244
            for right in may:
 
245
                assert acl.may(self.request, user, right)
 
246
            # But NOT these:
 
247
            for right in mayNot:
 
248
                assert not acl.may(self.request, user, right)
 
249
 
 
250
 
 
251
class TestPageAcls(object):
 
252
    """ security: real-life access control list on pages testing
 
253
    """
 
254
    mainpage_name = u'AclTestMainPage'
 
255
    subpage_name = u'AclTestMainPage/SubPage'
 
256
    item_rwforall = u'EveryoneMayReadWriteMe'
 
257
    subitem_4boss = u'EveryoneMayReadWriteMe/OnlyTheBossMayWMe'
 
258
    pages = [
 
259
        # pagename, content
 
260
        (mainpage_name, u"#acl JoeDoe:\n#acl JaneDoe:read,write\nFoo!"),
 
261
        (subpage_name, u"FooFoo!"),
 
262
        (item_rwforall, u"#acl All:read,write\nMay be read from and written to by anyone"),
 
263
        (subitem_4boss, u"#acl JoeDoe:read,write\nOnly JoeDoe (the boss) may write"),
 
264
    ]
 
265
 
 
266
    from MoinMoin._tests import wikiconfig
 
267
    class Config(wikiconfig.Config):
 
268
        acl_rights_before = u"WikiAdmin:admin,read,write,delete,revert"
 
269
        acl_rights_default = u"All:read,write"
 
270
        acl_rights_after = u"All:read"
 
271
        acl_hierarchic = False
 
272
 
 
273
    def setup_class(self):
 
274
        # Backup user
 
275
        self.savedUser = self.request.user.name
 
276
        self.request.user = User(self.request, auth_username=u'WikiAdmin')
 
277
        self.request.user.valid = True
 
278
 
 
279
        for page_name, page_content in self.pages:
 
280
            create_page(self.request, page_name, page_content)
 
281
 
 
282
    def teardown_class(self):
 
283
        # Restore user
 
284
        self.request.user.name = self.savedUser
 
285
 
 
286
        for page_name, dummy in self.pages:
 
287
            nuke_page(self.request, page_name)
 
288
 
 
289
    def testPageACLs(self):
 
290
        """ security: test page acls """
 
291
        tests = [
 
292
            # hierarchic, pagename, username, expected_rights
 
293
            (False, self.mainpage_name, u'WikiAdmin', ['read', 'write', 'admin', 'revert', 'delete']),
 
294
            (True,  self.mainpage_name, u'WikiAdmin', ['read', 'write', 'admin', 'revert', 'delete']),
 
295
            (False, self.mainpage_name, u'AnyUser', ['read']), # by after acl
 
296
            (True,  self.mainpage_name, u'AnyUser', ['read']), # by after acl
 
297
            (False, self.mainpage_name, u'JaneDoe', ['read', 'write']), # by page acl
 
298
            (True,  self.mainpage_name, u'JaneDoe', ['read', 'write']), # by page acl
 
299
            (False, self.mainpage_name, u'JoeDoe', []), # by page acl
 
300
            (True,  self.mainpage_name, u'JoeDoe', []), # by page acl
 
301
            (False, self.subpage_name, u'WikiAdmin', ['read', 'write', 'admin', 'revert', 'delete']),
 
302
            (True,  self.subpage_name, u'WikiAdmin', ['read', 'write', 'admin', 'revert', 'delete']),
 
303
            (False, self.subpage_name, u'AnyUser', ['read', 'write']), # by default acl
 
304
            (True,  self.subpage_name, u'AnyUser', ['read']), # by after acl
 
305
            (False, self.subpage_name, u'JoeDoe', ['read', 'write']), # by default acl
 
306
            (True,  self.subpage_name, u'JoeDoe', []), # by inherited acl from main page
 
307
            (False, self.subpage_name, u'JaneDoe', ['read', 'write']), # by default acl
 
308
            (True,  self.subpage_name, u'JaneDoe', ['read', 'write']), # by inherited acl from main page
 
309
            (True,  self.subitem_4boss, u'AnyUser', ['read']), # by after acl
 
310
            (True,  self.subitem_4boss, u'JoeDoe', ['read', 'write']), # by item acl
 
311
        ]
 
312
 
 
313
        for hierarchic, pagename, username, may in tests:
 
314
            u = User(self.request, auth_username=username)
 
315
            u.valid = True
 
316
 
 
317
            def _have_right(u, right, pagename, hierarchic):
 
318
                self.request.cfg.acl_hierarchic = hierarchic
 
319
                can_access = u.may.__getattr__(right)(pagename)
 
320
                if can_access:
 
321
                    print "page %s: %s test if %s may %s (success)" % (
 
322
                        pagename, ['normal', 'hierarchic'][hierarchic], username, right)
 
323
                else:
 
324
                    print "page %s: %s test if %s may %s (failure)" % (
 
325
                        pagename, ['normal', 'hierarchic'][hierarchic], username, right)
 
326
                assert can_access
 
327
 
 
328
            # User should have these rights...
 
329
            for right in may:
 
330
                yield _have_right, u, right, pagename, hierarchic
 
331
 
 
332
            def _not_have_right(u, right, pagename, hierarchic):
 
333
                self.request.cfg.acl_hierarchic = hierarchic
 
334
                can_access = u.may.__getattr__(right)(pagename)
 
335
                if can_access:
 
336
                    print "page %s: %s test if %s may not %s (failure)" % (
 
337
                        pagename, ['normal', 'hierarchic'][hierarchic], username, right)
 
338
                else:
 
339
                    print "page %s: %s test if %s may not %s (success)" % (
 
340
                        pagename, ['normal', 'hierarchic'][hierarchic], username, right)
 
341
                assert not can_access
 
342
 
 
343
            # User should NOT have these rights:
 
344
            mayNot = [right for right in self.request.cfg.acl_rights_valid
 
345
                      if right not in may]
 
346
            for right in mayNot:
 
347
                yield _not_have_right, u, right, pagename, hierarchic
 
348
 
 
349
coverage_modules = ['MoinMoin.security']