Skip to content

CSP: Improve validation message for security.csp.directives when script-src or style-src are used #16663

@HannesOberreiter

Description

@HannesOberreiter

Astro Info

Astro                    v6.3.1
Vite                     v7.3.3
Node                     v22.21.1
System                   macOS (arm64)
Package Manager          npm
Output                   static
Adapter                  none

If this issue only occurs in one browser, which browser is a problem?

No response

Describe the Bug

When script-src or style-src are added to security.csp.directives, Astro shows a generic union validation warning:

! security.csp: Did not match union.                                                                                                                                           
> Expected type boolean | { directives.1; directives.3 }                                                                                                                     
> Received { "directives": [ "default-src 'self'", "script-src 'self' https://example.com", "style-src 'self' https://example.com" ] }                                       

I understand that script-src and style-src intentionally do not belong in security.csp.directives, because Astro manages these via security.csp.scriptDirective and security.csp.styleDirective.

The issue is only that the current warning is difficult to understand. It looks like a type/schema problem and does not explain which directive is invalid or where it should be configured instead.

Minimal reproduction

import { defineConfig } from 'astro/config';                                                                                                                                   
                                                                                                                                                                                  
export default defineConfig({                                                                                                                                                  
     security: {                                                                                                                                                                  
       csp: {                                                                                                                                                                     
         directives: [                                                                                                                                                            
           "default-src 'self'",                                                                                                                                                  
           "script-src 'self' https://example.com",                                                                                                                               
           "style-src 'self' https://example.com",                                                                                                                                
         ],                                                                                                                                                                       
       },                                                                                                                                                                         
     },                                                                                                                                                                           
});                                                                                                                                                                  

What's the expected result?

Astro should explain what directives are allowed in the error message.

Maybe one could change and bubble up the zod error message:

if (!ALLOWED_DIRECTIVES.some((allowed) => value.startsWith(allowed))) {
  ctx.addIssue({
    code: 'custom', 
    message: `Unsupported CSP directive. Allowed directives: ${ALLOWED_DIRECTIVES.join(', ')}`,                                                                              
  });                                                                                                                                                                        
}

Link to Minimal Reproducible Example

--

Participation

  • I am willing to submit a pull request for this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    - P2: nice to haveNot breaking anything but nice to have (priority)pkg: astroRelated to the core `astro` package (scope)

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions