iOS web browser with a focus on security and privacy
1//
2// URLInterceptor_Tests.m
3// Endless
4//
5// Created by joshua stein on 12/20/16.
6// Copyright © 2016 jcs. All rights reserved.
7//
8
9#import <XCTest/XCTest.h>
10
11#import "URLInterceptor.h"
12
13@interface URLInterceptor_Tests : XCTestCase
14
15@end
16
17@implementation URLInterceptor_Tests
18
19- (void)testCSPHeaderInjection
20{
21 NSString *inp = @"default-src 'self'; connect-src 'self'; font-src 'self' data:; frame-src https://twitter.com https://*.twitter.com https://*.twimg.com twitter: https://www.google.com https://5415703.fls.doubleclick.net; frame-ancestors https://*.twitter.com; img-src https://twitter.com https://*.twitter.com https://*.twimg.com https://maps.google.com https://www.google-analytics.com https://stats.g.doubleclick.net https://www.google.com https://ad.doubleclick.net data:; media-src https://*.twitter.com https://*.twimg.com https://*.cdn.vine.co; object-src 'self'; script-src 'unsafe-inline' 'unsafe-eval' https://*.twitter.com https://*.twimg.com https://www.google.com https://www.google-analytics.com https://stats.g.doubleclick.net; style-src 'unsafe-inline' https://*.twitter.com https://*.twimg.com; report-uri https://twitter.com/i/csp_report?a=O5SWEZTPOJQWY3A%3D&ro=false;";
22 NSString *outp = [URLInterceptor prependDirectivesIfExisting:@{
23 @"frame-src": @[ @"endless:", @"endless:" ],
24 @"child-src": @[ @"endless:", @"endless:" ]
25 } inCSPHeader:inp];
26 XCTAssertEqualObjects(outp, @"connect-src 'self'; default-src 'self'; font-src 'self' data:; frame-ancestors https://*.twitter.com; frame-src endless: https://twitter.com https://*.twitter.com https://*.twimg.com twitter: https://www.google.com https://5415703.fls.doubleclick.net; img-src https://twitter.com https://*.twitter.com https://*.twimg.com https://maps.google.com https://www.google-analytics.com https://stats.g.doubleclick.net https://www.google.com https://ad.doubleclick.net data:; media-src https://*.twitter.com https://*.twimg.com https://*.cdn.vine.co; object-src 'self'; report-uri https://twitter.com/i/csp_report?a=O5SWEZTPOJQWY3A%3D&ro=false; script-src 'unsafe-inline' 'unsafe-eval' https://*.twitter.com https://*.twimg.com https://www.google.com https://www.google-analytics.com https://stats.g.doubleclick.net; style-src 'unsafe-inline' https://*.twitter.com https://*.twimg.com;");
27}
28
29- (void)testCSPHeaderNoneRemoval
30{
31 /* make sure 'none' is removed and our value is used */
32 NSString *outp = [URLInterceptor prependDirectivesIfExisting:@{
33 @"frame-src": @[ @"endless:", @"endless:" ]
34 } inCSPHeader:@"blah-src 'self';frame-src 'none' ; blah2-src 'none';"];
35 XCTAssertEqualObjects(outp, @"blah-src 'self'; blah2-src 'none'; frame-src endless:;");
36}
37
38- (void)testCSPHeaderSelectiveInclusion
39{
40 /* only change directives if they existed in the original policy */
41 NSString *outp = [URLInterceptor prependDirectivesIfExisting:@{
42 @"child-src": @[ @"endlessipc:", @"endlessipc:" ],
43 @"frame-src": @[ @"endlessipc:", @"endlessipc:" ],
44 @"script-src" : @[ @"'none'", @"'none'" ]
45 } inCSPHeader:@"referrer always;"];
46 XCTAssertEqualObjects(outp, @"referrer always;");
47}
48
49- (void)testCSPHeaderSelectiveNonce
50{
51 NSDictionary *wantedDirectives = @{
52 @"child-src": @[ @"endlessipc:", @"endlessipc:" ],
53 @"default-src" : @[ @"endlessipc:", @"'nonce-blah' endlessipc:" ],
54 @"frame-src": @[ @"endlessipc:", @"endlessipc:" ],
55 @"script-src" : @[ @"", @"'nonce-blah'" ],
56 };
57
58 /* only prepend nonced values if the original directive contained '{sha256|sha384|sha512|nonce}-.*' */
59 NSString *inp = @"default-src 'self'; script-src https://cdn.example.com 'sha512-abcdefghijkl'; style-src 'unsafe-inline'";
60 NSString *outp = [URLInterceptor prependDirectivesIfExisting:wantedDirectives inCSPHeader:inp];
61 XCTAssertEqualObjects(outp, @"default-src endlessipc: 'self'; script-src 'nonce-blah' https://cdn.example.com 'sha512-abcdefghijkl'; style-src 'unsafe-inline';");
62
63 /* when it doesn't use nonces, use the non-nonced version */
64 NSString *inp2 = @"default-src 'self'; connect-src https://localhost https://*.instapaper.com https://*.stripe.com https://getpocket.com https://m.signalvnoise.com https://*.m.signalvnoise.com https://*.medium.com https://medium.com https://*.medium.com https://*.algolia.net https://cdn-static-1.medium.com https://dnqgz544uhbo8.cloudfront.net https://*.lightstep.com 'self'; font-src data: https://*.amazonaws.com https://*.medium.com https://*.gstatic.com https://dnqgz544uhbo8.cloudfront.net https://use.typekit.net https://cdn-static-1.medium.com 'self'; frame-src chromenull: https: webviewprogressproxy: medium: 'self'; img-src blob: data: https: 'self'; media-src https://*.cdn.vine.co https://d1fcbxp97j4nb2.cloudfront.net https://d262ilb51hltx0.cloudfront.net https://medium2.global.ssl.fastly.net https://*.medium.com https://gomiro.medium.com https://miro.medium.com https://pbs.twimg.com 'self'; object-src 'self'; script-src 'unsafe-eval' 'unsafe-inline' about: https: 'self'; style-src 'unsafe-inline' data: https: 'self'; report-uri https://csp.medium.com";
65 NSString *outp2 = [URLInterceptor prependDirectivesIfExisting:wantedDirectives inCSPHeader:inp2];
66 XCTAssertEqualObjects(outp2, @"connect-src https://localhost https://*.instapaper.com https://*.stripe.com https://getpocket.com https://m.signalvnoise.com https://*.m.signalvnoise.com https://*.medium.com https://medium.com https://*.medium.com https://*.algolia.net https://cdn-static-1.medium.com https://dnqgz544uhbo8.cloudfront.net https://*.lightstep.com 'self'; default-src endlessipc: 'self'; font-src data: https://*.amazonaws.com https://*.medium.com https://*.gstatic.com https://dnqgz544uhbo8.cloudfront.net https://use.typekit.net https://cdn-static-1.medium.com 'self'; frame-src endlessipc: chromenull: https: webviewprogressproxy: medium: 'self'; img-src blob: data: https: 'self'; media-src https://*.cdn.vine.co https://d1fcbxp97j4nb2.cloudfront.net https://d262ilb51hltx0.cloudfront.net https://medium2.global.ssl.fastly.net https://*.medium.com https://gomiro.medium.com https://miro.medium.com https://pbs.twimg.com 'self'; object-src 'self'; report-uri https://csp.medium.com; script-src 'unsafe-eval' 'unsafe-inline' about: https: 'self'; style-src 'unsafe-inline' data: https: 'self';");
67}
68
69@end