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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
<?php
namespace MediaWiki\Tests\Api;
use ApiCSPReport;
use ApiResult;
use MediaWiki\MainConfigNames;
use MediaWiki\Request\FauxRequest;
use MediaWikiIntegrationTestCase;
use Psr\Log\AbstractLogger;
/**
* @group API
* @group medium
* @covers \ApiCSPReport
*/
class ApiCSPReportTest extends MediaWikiIntegrationTestCase {
public function testInternalReportonly() {
$params = [
'reportonly' => '1',
'source' => 'internal',
];
$cspReport = [
'document-uri' => 'https://doc.test/path',
'referrer' => 'https://referrer.test/path',
'violated-directive' => 'connet-src',
'disposition' => 'report',
'blocked-uri' => 'https://blocked.test/path?query',
'line-number' => 4,
'column-number' => 2,
'source-file' => 'https://source.test/path?query',
];
$log = $this->doExecute( $params, $cspReport );
$this->assertEquals(
[
[
'[report-only] Received CSP report: ' .
'<https://blocked.test> blocked from being loaded on <https://doc.test/path>:4',
[
'method' => 'ApiCSPReport::execute',
'user_id' => 'logged-out',
'user-agent' => 'Test/0.0',
'source' => 'internal'
]
],
],
$log,
'logged messages'
);
}
public function testFalsePositiveOriginMatch() {
$params = [
'reportonly' => '1',
'source' => 'internal',
];
$cspReport = [
'document-uri' => 'https://doc.test/path',
'referrer' => 'https://referrer.test/path',
'violated-directive' => 'connet-src',
'disposition' => 'report',
'blocked-uri' => 'https://blocked.test/path/file?query',
'line-number' => 4,
'column-number' => 2,
'source-file' => 'https://source.test/path/file?query',
];
$this->overrideConfigValue(
MainConfigNames::CSPFalsePositiveUrls,
[ 'https://blocked.test/path/' => true ]
);
$log = $this->doExecute( $params, $cspReport );
$this->assertSame(
[],
$log,
'logged messages'
);
}
private function doExecute( array $params, array $cspReport ) {
$log = [];
$logger = $this->createMock( AbstractLogger::class );
$logger->method( 'warning' )->willReturnCallback(
static function ( $msg, $ctx ) use ( &$log ) {
unset( $ctx['csp-report'] );
$log[] = [ $msg, $ctx ];
}
);
$this->setLogger( 'csp-report-only', $logger );
$postBody = json_encode( [ 'csp-report' => $cspReport ] );
$req = $this->getMockBuilder( FauxRequest::class )
->onlyMethods( [ 'getRawInput' ] )
->setConstructorArgs( [ $params, /* $wasPosted */ true ] )
->getMock();
$req->method( 'getRawInput' )->willReturn( $postBody );
$req->setHeaders( [
'Content-Type' => 'application/csp-report',
'User-Agent' => 'Test/0.0'
] );
$api = $this->getMockBuilder( ApiCSPReport::class )
->disableOriginalConstructor()
->onlyMethods( [ 'getParameter', 'getRequest', 'getResult' ] )
->getMock();
$api->method( 'getParameter' )->willReturnCallback(
static function ( $key ) use ( $req ) {
return $req->getRawVal( $key );
}
);
$api->method( 'getRequest' )->willReturn( $req );
$api->method( 'getResult' )->willReturn( new ApiResult( false ) );
$api->execute();
return $log;
}
}
|