Content Security Policy (CSP) Header Not Set

143 views
Skip to first unread message

Brad Thomas

unread,
May 9, 2025, 3:40:04 PM5/9/25
to ZAP User Group
I published my web  application with a CSP.  The CSP that ZAP shows in the Response is not the CSP that I specified in my app.

Why is this happening?

This CSP is visible in the Response Header when I inspect the app with Edge Developer Tools.

content-security-policy
base-uri 'self'; block-all-mixed-content;default-src 'self' https://app.powerbi.com; img-src 'self'; script-src 'self' code.jquery.com; style-src 'self' https://cdn.jsdelivr.net; font-src 'self' https://cdn.jsdelivr.net data:; frame-src 'self' https://app.powerbi.com; frame-ancestors 'self' https://app.powerbi.com;upgrade-insecure-requests;connect-src 'self';
content-type
text/html; charset=utf-8

However, the Response Header in the ZAP app shows a Content-Security-Policy-Report-Only

Content-Security-Policy-Report-Only: object-src 'none'; base-uri 'self'; script-src 'self' 'nonce-xEXiOAyIgKq4X_s7TMgXJg' 'unsafe-inline' 'unsafe-eval' https://*.msauth.net https://*.msftauth.net https://*.msftauthimages.net https://*.msauthimages.net https://*.msidentity.com https://*.microsoftonline-p.com https://*.microsoftazuread-sso.com https://*.azureedge.net https://*.outlook.com https://*.office.com https://*.office365.com https://*.microsoft.com https://*.bing.com 'report-sample'; report-uri https://csp.microsoft.com/report/ESTS-UX-All

Simon Bennetts

unread,
May 13, 2025, 8:53:41 AM5/13/25
to ZAP User Group
Hiya,

Are you sure you are comparing exactly the same request and response?
Have you enabled any scripts in ZAP?
What do you see if you submit the same request with another tool like curl?

Cheers,

Simon

Brad Thomas

unread,
May 13, 2025, 4:01:16 PM5/13/25
to ZAP User Group
Simon,

Thanks for responding.
In both cases the request was the home page url.

Why would there ever be a case where the CSP would be different than the CSP I coded into my application.

The Curl samples below are indicating a redirect to login.microsoft.online because I am using Microsoft Identity Platform to authenticate the use.

Do I need to disable authentication for the purpose of the PEN test?  (I didn't have to do that last year)

I haven't enabled any scripts in Zap.

These are the headers that I specified in my app (C#, Core8, Blazor)

    app.Use(async (context, next) =>
    {
        context.Response.Headers.Append("X-Frame-Options", "SAMEORIGIN");
        context.Response.Headers.Append("X-XSS-Protection", "1; mode=block");
        context.Response.Headers.Append("X-Content-Type-Options", "nosniff");
        context.Response.Headers.Append("Arr-Disable-Session-Affinity", "True");
        context.Response.Headers.Append(
             "Content-Security-Policy",
             "base-uri 'self'; " +
             "block-all-mixed-content;" +
             "default-src 'self' https://app.powerbi.com; " +
             "img-src 'self'; " +
             "script-src 'self' code.jquery.com; " +
             "style-src 'self' https://cdn.jsdelivr.net; " +
             "font-src 'self' https://cdn.jsdelivr.net data:; " +
             "frame-src 'self' https://app.powerbi.com; " +
             "frame-ancestors 'self' https://app.powerbi.com;" +
             "upgrade-insecure-requests;" +
             "connect-src 'self';");
        await next();
    });

When you look at the response header when I inspected my deployed app - this is the CSP.
I don't understand why Zap is somehow changing the CSP.  That was not the case when I used Zap last year.  (Sorry, I can't tell you what version that was).

Taking your suggestion when I run curl on the base url ---   https://TexicanStage.azurewesites.net (Core 8)  I see that there is a redirect to login.microsoft.com.  This performing an automatic authentication with OpenIdConnect.

HTTP/1.1 302 Found
Content-Length: 0
Date: Tue, 13 May 2025 19:50:04 GMT
Location: https://login.microsoftonline.com/6999ab39-73b6-46a2-b4e4-3417366959b6/oauth2/v2.0/authorize?client_id=8ee3e4b1-f7e1-4ebd-99c1-00eca6bf4d72&redirect_uri=https%3A%2F%2Ftexicanstage.azurewebsites.net%2Fsignin-oidc&response_type=code&scope=openid%20profile%20offline_access%20user.read.all&code_challenge=P6MKmJEyROuXiHyYHGmjCJogMzVQfaf93YYA5QWu1no&code_challenge_method=S256&response_mode=form_post&nonce=638827626042371285.M2YzNmRkNzItMGViOC00MThhLWI3MjEtMzEwMWI4ZmVlNTAwNDkwMjYzYjMtM2RjMy00MDEwLTgxNmEtOGU1MjdlNjc4MGIx&client_info=1&x-client-brkrver=IDWeb.3.8.4.0&state=CfDJ8DlhTNjejZZOi4wauAoBUEopOguzFMsunh4x2c26jPPgq29Zb7miz-PDexXoJwlVMM1cXqbmwohJzXml-VydS0IYCXeNmQrNHnVeuB21jxeQyjlKTcmQpTkYEaaTU1JpQhfNbJzjWvrpv3z8oSu6bRmlNmDzGaBKeJ3ly12Ztwnyk5gY-smo7IFCxiL2lFiecrSRWQXyYHNv9bxwnreuTErOK8Xry4UQenggBmTQjD0_n_buxoxiDPsO0d5cxLuWtGF_pgrwW9zP2iaYvaUnHZGwqkefJmX2shpzhPh3e_T7FaVxkxxnnVdrCENoilieiaTWkRQUJFTH65inbNHIMVkd4bqDXgn8sVwcyzh8vVQPwDPlTQAgmvpcC44fto3U_06W_gJTc7sV_j8RuFZOXbo&x-client-SKU=ID_NET8_0&x-client-ver=8.9.0.0
Set-Cookie: .AspNetCore.OpenIdConnect.Nonce.CfDJ8DlhTNjejZZOi4wauAoBUEqE_0MG9-PQZzkjS4M682yo0cFER_Idi0JD8nvHJ_N-RKJy0oRwVeB6u_tHjgt2VCKrb8dslm-KPeAJ7F0hwrGuYPgtLLDtEvwNf5T4DZyUX8MxfL3Usgb-uQtj2sieZ9lc_VAOp89Lw_EEs1csnshtVnGIq0CAsrMVS0vYAxqtrwBaIbcWpzSUgjd_TaRsX98uAe6NgfjbdA1CFseGI4qcgtV2zG9pnDX3xYhuBaxfW33VftxPPTB8t2fTwuwiQ8I=N; expires=Tue, 13 May 2025 20:05:04 GMT; path=/signin-oidc; secure; samesite=none; httponly
Set-Cookie: .AspNetCore.Correlation.uYswPA7GSdYlX4KBs2MZH7sEJ3yJKNb3yefJM8m6MzA=N; expires=Tue, 13 May 2025 20:05:04 GMT; path=/signin-oidc; secure; samesite=none; httponly
Set-Cookie: ARRAffinity=fe902be0bc72900fb371efb0140e0e2507e560103f60612cf370880dc3e398d5;Path=/;HttpOnly;Secure;Domain=texicanstage.azurewebsites.net
Set-Cookie: ARRAffinitySameSite=fe902be0bc72900fb371efb0140e0e2507e560103f60612cf370880dc3e398d5;Path=/;HttpOnly;SameSite=None;Secure;Domain=texicanstage.azurewebsites.net
Request-Context: appId=cid-v1:278765e7-b3cd-4a86-b515-be3d9dd160fc

I ran the same curl command on my app that was developed with Core 6 and I see the same redirect but I also see the X-Frame-Option and the Content-Security-Policy.

HTTP/1.1 302 Found
Content-Length: 0
Date: Tue, 13 May 2025 19:51:45 GMT
Location: https://login.microsoftonline.com/6999ab39-73b6-46a2-b4e4-3417366959b6/oauth2/v2.0/authorize?client_id=780a57bd-943f-4750-bae0-da4567d0093a&redirect_uri=https%3A%2F%2Ftexicandemo.azurewebsites.net%2Fsignin-oidc&response_type=code&scope=openid%20profile%20offline_access&code_challenge=twWVjbRGnZ76PU04WYjDdEQqkmqUCcRAb6Xxe7gjfMM&code_challenge_method=S256&response_mode=form_post&nonce=638827627057456074.NmIxODExNzYtOTMwNS00MWZjLTliZDktMTc5NzJiZWU1YmVlODA2NjE3N2MtOTllNy00MmFhLWI1MGUtMTcwYzZlNDA0MjQ5&client_info=1&x-client-brkrver=IDWeb.2.20.0.0&state=CfDJ8OO1V8htwmtCoAopycI60gaeU7gygG_GQTmJDK1hY7xkZgES4NPs0QXEshADNlyuin8RggI2kTvS1T-u7jAU5LW94kBvnfp4PIabA5HpyRwbzs6srWuQ0Y04T_T7sZz3rEvHGbT-AYbhTsktd7wC7IEp10Upr_v67S2Cb8DrBK4Ux_pPe3kE9GpePVE_-lcUa1uO2Pk43UtdcDpWnmG6xoLnqs4iUqFX_LYh135KRRcAcRcvIEnAKRrRqWehmkOsRygH5dize8TnBZBqQwgvB26ztEt0-loYhYqmRyxZ-LacZHuzU6v6hnw1W0m8IIPxmQn7Bt0j2j-CwaMLNFh1JzWih-2d8XCnYLOgAVL7OG9vRh19reMjKeKHOCgesVAJqc659ZHmhyPo-sHz3uF2jlA&x-client-SKU=ID_NET6_0&x-client-ver=7.6.0.0
Set-Cookie: .AspNetCore.OpenIdConnect.Nonce.CfDJ8OO1V8htwmtCoAopycI60gbXtpgOE_IBX0xWoc83NejbkLtD-qcXVjxtcb10G7rbf2VMEtIsq7lI-c2jHEP2rkjwrypedVbWB_IBiN5UI5MhqAUk5RzDV7kmAMJFDLXHtJrXKDeGFmdCN2pZ2foTPhEjg7EHc8uAfL0l8XEecfTnQpwIOz1OqOjL_gNFBCzJ52wxMzGSKeSHjbGfDY5hMcVBohLtRwVNxI9vCPilGjDrlba4KkyHhbAn5lhCSEfctZZONzacdJKCMRAvjKCJmm4=N; expires=Tue, 13 May 2025 20:06:45 GMT; path=/signin-oidc; secure; samesite=none; httponly
Set-Cookie: .AspNetCore.Correlation.9vClisaGu9ycBl1fj-1sIqgHk6f4yFfXMO2ugY0QGnM=N; expires=Tue, 13 May 2025 20:06:45 GMT; path=/signin-oidc; secure; samesite=none; httponly
Strict-Transport-Security: max-age=2592000
Request-Context: appId=cid-v1:e19db470-bf96-4b63-8ebe-20f9b9a92cd2
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Arr-Disable-Session-Affinity: True
Content-Security-Policy: base-uri 'self'; block-all-mixed-content;img-src 'self'; script-src 'self' code.jquery.com; frame-ancestors 'self';upgrade-insecure-requests;connect-src 'self';

Brad Thomas

unread,
May 13, 2025, 5:31:43 PM5/13/25
to ZAP User Group
Simon,

I ran Zap on a stripped-down App that did not do anything to authenticate the user.  This time my CSP is in the Response Header as I would expect.

Do I need to create a script that performs the Authentication?  Unfortunately, I don't see one in the ZAP Community Scripts repo.
Is there an alternative besides removing the Authentication from the App I want to test?

Brad

kingthorin+zap

unread,
May 15, 2025, 10:08:14 AM5/15/25
to ZAP User Group
Chances are Microsoft has their own CSP for components [like auth] that are fully in their control. Obviously you can't make any changes to their policy and so can ignore alerts about resources you don't control. (IMHO)

For all things auth related start here: https://www.zaproxy.org/docs/authentication/

Simon Bennetts

unread,
May 20, 2025, 9:15:27 AM5/20/25
to ZAP User Group
Brad,

You can copy the relevant headers from ZAP and use them in curl so that the request is authenticated.

Re authentication - you will need to configure ZAP to handle it.
If you didnt do that last year then either your scan didnt really work or your authentication was broken :)

To get started with authentication see https://www.zaproxy.org/docs/authentication/ but be aware that we've made _lots_ of improvements recently which we still need to document.
Those docs should be "coming soon"...

Cheers,

Simon
Reply all
Reply to author
Forward
0 new messages