blob: aa6cd70f4e11ed48e38044ee35d82df8b2a9f9c8 [file] [log] [blame]
Akron354f4532021-01-21 17:29:44 +01001use Mojolicious::Lite;
2use Test::Mojo;
3use Test::More;
4
5my $t = Test::Mojo->new;
6
7plugin 'Kalamar::Plugin::CSP' => {
8 'style-src' => ['self','unsafe-inline'],
9 'script-src' => '*',
10 'img-src' => ['self', 'data:']
11};
12
13get '/' => sub {
14 shift->render(text => 'hello world');
15};
16
17my $csp = 'Content-Security-Policy';
18
19$t->get_ok('/')
20 ->status_is(200)
21 ->content_is('hello world')
22 ->header_is($csp, "img-src 'self' data:;script-src *;style-src 'self' 'unsafe-inline';")
23 ;
24
25$t->app->csp->add('img-src' => 'stats.ids-mannheim.de');
26
27$t->get_ok('/')
28 ->status_is(200)
29 ->content_is('hello world')
30 ->header_is($csp, "img-src 'self' data: stats.ids-mannheim.de;script-src *;style-src 'self' 'unsafe-inline';")
31 ;
32
33$t->get_ok('/')
34 ->status_is(200)
35 ->content_is('hello world')
36 ->header_is($csp, "img-src 'self' data: stats.ids-mannheim.de;script-src *;style-src 'self' 'unsafe-inline';")
37 ;
38
39$t->app->csp->add('img-src' => 'stats.ids-mannheim.de');
40
41$t->get_ok('/')
42 ->status_is(200)
43 ->content_is('hello world')
44 ->header_is($csp, "img-src 'self' data: stats.ids-mannheim.de;script-src *;style-src 'self' 'unsafe-inline';")
45 ;
46
47$t->app->csp->add('script-src' => '*');
48
49$t->get_ok('/')
50 ->status_is(200)
51 ->content_is('hello world')
52 ->header_is($csp, "img-src 'self' data: stats.ids-mannheim.de;script-src *;style-src 'self' 'unsafe-inline';")
53 ;
54
55
56# New
57$t = Test::Mojo->new;
58$t->app->config(
59 CSP => {
60 'style-src' => ['self','unsafe-inline'],
61 'img-src' => ['self', 'data:']
62 }
63);
64
65$t->app->plugin('Kalamar::Plugin::CSP' => {
66 'script-src' => '*',
67 'img-src' => 'self'
68});
69
70$t->app->routes->get('/n')->to(
71 cb => sub {
72 shift->render(text => 'hello world');
73 }
74);
75
76$t->get_ok('/n')
77 ->status_is(200)
78 ->content_is('hello world')
79 ->header_is($csp, "img-src 'self' data:;script-src *;style-src 'self' 'unsafe-inline';")
80 ;
81
82
Akroneb53ac32021-01-25 19:15:41 +010083$t = Test::Mojo->new(Mojolicious::Lite->new);
84$t->app->plugin('Kalamar::Plugin::CSP');
85$t->app->routes->get('/nononce')->to(
86 cb => sub {
87 shift->render(inline => 'Hallo! <%= csp_nonce_tag %>');
88 }
89);
90
91$t->get_ok('/nononce')
92 ->status_is(200)
93 ->content_is("Hallo! \n")
94 ->header_unlike($csp, qr!'nonce-.{20}'!)
95 ;
96
97$t->app->content_block(
98 'nonce_js' => {
99 inline => 'console.log("Hallo")'
100 }
101);
102
103$t->get_ok('/nononce')
104 ->status_is(200)
105 ->content_is("Hallo! <!-- inline js permitted -->\n")
106 ->header_unlike($csp, qr!'nonce-.{20}'!)
107 ;
108
109# Test with nonce:
110$t = Test::Mojo->new(Mojolicious::Lite->new);
111$t->app->config(
112 CSP => {
113 'style-src' => ['self'],
114 'img-src' => ['self', 'data:'],
115 -with_nonce => 1
116 }
117);
118
119$t->app->plugin('Kalamar::Plugin::CSP');
120
121$t->app->routes->get('/nonce')->to(
122 cb => sub {
123 shift->render(inline => 'Hallo! <%= csp_nonce_tag %>');
124 }
125);
126
127$t->get_ok('/nonce')
128 ->status_is(200)
129 ->content_like(qr'Hallo!')
130 ->content_unlike(qr'<script nonce=".{20}">')
131 ->header_like($csp, qr!^img-src 'self' data:;script-src 'nonce-.{20}';style-src 'self';!)
132 ->tx->res->to_string;
133;
134
135$t->app->content_block(
136 'nonce_js' => {
137 inline => 'console.log("Hallo")'
138 }
139);
140
141my $content = $t->get_ok('/nonce')
142 ->status_is(200)
143 ->content_like(qr'Hallo! <script nonce=".{20}">//<!\[CDATA\[\nconsole')
144 ->header_like($csp, qr!^img-src 'self' data:;script-src 'nonce-.{20}';style-src 'self';!)
145 ->tx->res->to_string;
146;
147
148$content =~ q!<script nonce="(.{20})"!;
149like($content, qr/nonce-\Q$1\E/);
150
151
Akron638fc972021-09-24 16:39:38 +0200152# Disable csp
153$t = Test::Mojo->new(Mojolicious::Lite->new);
154$t->app->plugin('Kalamar::Plugin::CSP' => {
155 '-disable' => 1
156});
157
158$t->app->routes->get('/' => sub {
159 shift->render(text => 'hello world');
160});
161
162$t->app->csp->add('script-src', '*');
163is($t->app->csp_nonce_tag,'');
164
165$t->get_ok('/')
166 ->status_is(200)
167 ->content_is('hello world')
168 ->header_is($csp, undef)
169 ;
Akroneb53ac32021-01-25 19:15:41 +0100170
Akron354f4532021-01-21 17:29:44 +0100171done_testing;
172__END__