Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Owin connect-src not working as expected #63

Closed
matteo-mosca opened this issue Jul 10, 2015 · 12 comments
Closed

Owin connect-src not working as expected #63

matteo-mosca opened this issue Jul 10, 2015 · 12 comments
Assignees

Comments

@matteo-mosca
Copy link

I am using the owin middleware like this:

app.UseCsp(config =>
        {
            config
                .DefaultSources(c => c.None())
                .ConnectSources(c => c.Self())
                .FontSources(c => c.Self())
                .ImageSources(c => c.Self())
                .ScriptSources(c => c.Self())
                .StyleSources(c => c.Self());
        });

Still, websocket connections from self are refused:

Refused to connect to 'ws://localhost:41698/signalr/connect?transport=webSockets&clientProtocol=1.5&connectionToken=OPTrgor3M3NOmxP%2B4WF0jpKPRmKaS2zHtIXxSnWHv7EIXGmmBcv8jC1eq1yKUrege55GHJU6uQARKaEbzvFIl%2BmxEC3Oc68qlEei6EEIbkwBcTXVPFPF%2Fng83pv%2F66Wp&connectionData=%5B%7B%22name%22%3A%22systemhub%22%7D%5D&tid=6' because it violates the following Content Security Policy directive: "connect-src 'self'".

I have found no way to configure with CustomSources() to tell him to allow "ws://" + Self.

Thanks.

@klings
Copy link
Member

klings commented Jul 12, 2015

Yes, it's probably refused because 'self' is same scheme/host/port. Have you tried adding ws://localhost:41698 as a custom source?

@matteo-mosca
Copy link
Author

This works:

.ConnectSources(c => c.Self().CustomSources("ws://localhost:41698"))

Although it's no good because I have to hardcode the url, if someone else checks out the repository from Git and uses a different port on IIS express it won't work. I couldn't find a way to avoid hardcoding it in Startup.cs though since I don't have context information to get the host name.

@klings
Copy link
Member

klings commented Jul 13, 2015

Yes, there's currently no way to do that automagically. A workaround for the localhost scenario would be to configure it with a wildcard port like so:

.ConnectSources(c => c.Self().CustomSources("ws://localhost:*"))

I'll leave this issue open and have another look at it for an upcoming release, we can probably handle this particular case in a more elegant manner.

@matteo-mosca
Copy link
Author

I thank you for your time. If I find a solution I'll be sure to send in a pull request.

@klings klings self-assigned this Sep 26, 2015
@klings klings added this to the 4.2.0 milestone Sep 26, 2015
@klings
Copy link
Member

klings commented Oct 3, 2015

This particular scenario will be considered for the next iteration (3) of CSP, it might mandate a change in browser behaviour. I've opened an issue for it: w3c/webappsec#489.
AFAIK they'll get to work on CSP 3 pretty soon, so I'll hold of any changes until I see where the discussion lands.

@klings klings removed this from the 4.2.0 milestone Oct 3, 2015
@klings
Copy link
Member

klings commented Oct 7, 2015

The CSP issue was just moved to another repo: w3c/webappsec-csp#7

@RehanSaeed
Copy link
Contributor

This has been a real pain. Browser Link also causes this problem. I have had to add pre-processor directives and localhost:* to get around this:

filters.Add(
    new CspConnectSrcAttribute()
    {
#if DEBUG
        // Allow Browser Link to work in debug mode only.
        CustomSources = "localhost:*",
#endif
        // Allow all AJAX and Web Sockets calls from the same domain.
         Self = true
    });

filters.Add(
    new CspImgSrcAttribute()
    {
#if DEBUG
        // Allow Browser Link to work in debug mode only.
        CustomSources = "data:",
#endif
        // Allow images from the same domain.
        Self = true
    });

filters.Add(
    new CspScriptSrcAttribute()
    {
        // Allow scripts from the CDN's.
        CustomSources = string.Join(
            " ",
#if DEBUG
            // Allow Browser Link to work in debug mode only.
            "localhost:*",
#endif
            ContentDeliveryNetwork.Google.Domain,
            ContentDeliveryNetwork.Microsoft.Domain),
        // Allow scripts from the same domain.
        Self = true
    });

I've raised this issue on ASP.NET 5 here. Mads Kristensen has been assigned to fix this.

@klings
Copy link
Member

klings commented Oct 14, 2015

Yes, I see the browserlink pain. Hopefully they'll move the inline stuff to a separate file at least. It is an option to introduce an "allowSameHostWs" configuration option, but that would introduce som unwanted complexity. If the CSP gods decide to not do any adjustments to the semantics of connect-src 'self', I'll definitely add it. If they decide otherwise, well then I'll just wait until the problem disappears by itself. :)

Doing different configs for different environments is a pain when using the attributes. I would suggest using two different configs, either through web.config, or per environment Owin startup classes. That should ease some of the pain.

@RehanSaeed
Copy link
Contributor

Agreed, lets hope they fix it.

ASP.NET 5 fixes the multiple environments problem. You no longer need to rely on web.config file transforms, so you could remove the ugly pre-processor directives and do something more civilized like this:

if (environment.IsDevelopment())
{
    // Add CSP filters to get around browser link here.
}

@klings
Copy link
Member

klings commented Nov 3, 2015

So, they've decided to alter CSP and allow same host/port web sockets when you declare the 'self' source. We'll just wait them out.

@klings klings closed this as completed Nov 3, 2015
@naeemsarfraz
Copy link

@RehanSaeed is the ContentDeliveryNetwork.Microsoft.Domain a construct you created yourself or one you can access from a library? What's the value of it?

@RehanSaeed
Copy link
Contributor

They are just constants, sorry I should have made that clear:

    public static class ContentDeliveryNetwork
    {
        public static class Google
        {
            public const string Domain = "ajax.googleapis.com";
            public const string JQueryUrl = "//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js";
        }

        public static class MaxCdn
        {
            public const string Domain = "maxcdn.bootstrapcdn.com";
            public const string FontAwesomeUrl = "//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css";
        }

        public static class Microsoft
        {
            public const string Domain = "ajax.aspnetcdn.com";
            public const string JQueryValidateUrl = "//ajax.aspnetcdn.com/ajax/jquery.validate/1.14.0/jquery.validate.min.js";
            public const string JQueryValidateUnobtrusiveUrl = "//ajax.aspnetcdn.com/ajax/mvc/5.2.3/jquery.validate.unobtrusive.min.js";
            public const string ModernizrUrl = "//ajax.aspnetcdn.com/ajax/modernizr/modernizr-2.8.3.js";
            public const string BootstrapUrl = "//ajax.aspnetcdn.com/ajax/bootstrap/3.3.5/bootstrap.min.js";
        }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants