Fossil SCM
When rendering the default header via TH1, allow the default Content-Security-Policy content to be overridden via the 'default_csp' variable.
Commit
0fe4c7d97377e56a8665d678a869bde98a2386dec6dfd6c82ff9884d03eb9caf
Parent
cf6682b1e15c638…
2 files changed
+9
-5
+3
+9
-5
| --- src/style.c | ||
| +++ src/style.c | ||
| @@ -389,14 +389,11 @@ | ||
| 389 | 389 | */ |
| 390 | 390 | static char zDfltHeader[] = |
| 391 | 391 | @ <html> |
| 392 | 392 | @ <head> |
| 393 | 393 | @ <base href="$baseurl/$current_page" /> |
| 394 | -@ <meta http-equiv="Content-Security-Policy" \ | |
| 395 | -@ content="default-src 'self' data: ; \ | |
| 396 | -@ script-src 'self' 'nonce-$<nonce>' ;\ | |
| 397 | -@ style-src 'self' 'unsafe-inline'" /> | |
| 394 | +@ <meta http-equiv="Content-Security-Policy" content="$default_csp" /> | |
| 398 | 395 | @ <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| 399 | 396 | @ <title>$<project_name>: $<title></title> |
| 400 | 397 | @ <link rel="alternate" type="application/rss+xml" title="RSS Feed" \ |
| 401 | 398 | @ href="$home/timeline.rss" /> |
| 402 | 399 | @ <link rel="stylesheet" href="$stylesheet_url" type="text/css" \ |
| @@ -407,16 +404,23 @@ | ||
| 407 | 404 | |
| 408 | 405 | /* |
| 409 | 406 | ** Initialize all the default TH1 variables |
| 410 | 407 | */ |
| 411 | 408 | static void style_init_th1_vars(const char *zTitle){ |
| 412 | - Th_Store("nonce", style_nonce()); | |
| 409 | + const char *zNonce = style_nonce(); | |
| 410 | + char *zDfltCsp = sqlite3_mprintf("default-src 'self' data: ; " | |
| 411 | + "script-src 'self' 'nonce-%s' ; " | |
| 412 | + "style-src 'self' 'unsafe-inline'", | |
| 413 | + zNonce); | |
| 414 | + Th_Store("nonce", zNonce); | |
| 413 | 415 | Th_Store("project_name", db_get("project-name","Unnamed Fossil Project")); |
| 414 | 416 | Th_Store("project_description", db_get("project-description","")); |
| 415 | 417 | if( zTitle ) Th_Store("title", zTitle); |
| 416 | 418 | Th_Store("baseurl", g.zBaseURL); |
| 417 | 419 | Th_Store("secureurl", fossil_wants_https(1)? g.zHttpsURL: g.zBaseURL); |
| 420 | + Th_Store("default_csp", zDfltCsp); | |
| 421 | + sqlite3_free(zDfltCsp); | |
| 418 | 422 | Th_Store("home", g.zTop); |
| 419 | 423 | Th_Store("index_page", db_get("index-page","/home")); |
| 420 | 424 | if( local_zCurrentPage==0 ) style_set_current_page("%T", g.zPath); |
| 421 | 425 | Th_Store("current_page", local_zCurrentPage); |
| 422 | 426 | Th_Store("csrf_token", g.zCsrfToken); |
| 423 | 427 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -389,14 +389,11 @@ | |
| 389 | */ |
| 390 | static char zDfltHeader[] = |
| 391 | @ <html> |
| 392 | @ <head> |
| 393 | @ <base href="$baseurl/$current_page" /> |
| 394 | @ <meta http-equiv="Content-Security-Policy" \ |
| 395 | @ content="default-src 'self' data: ; \ |
| 396 | @ script-src 'self' 'nonce-$<nonce>' ;\ |
| 397 | @ style-src 'self' 'unsafe-inline'" /> |
| 398 | @ <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| 399 | @ <title>$<project_name>: $<title></title> |
| 400 | @ <link rel="alternate" type="application/rss+xml" title="RSS Feed" \ |
| 401 | @ href="$home/timeline.rss" /> |
| 402 | @ <link rel="stylesheet" href="$stylesheet_url" type="text/css" \ |
| @@ -407,16 +404,23 @@ | |
| 407 | |
| 408 | /* |
| 409 | ** Initialize all the default TH1 variables |
| 410 | */ |
| 411 | static void style_init_th1_vars(const char *zTitle){ |
| 412 | Th_Store("nonce", style_nonce()); |
| 413 | Th_Store("project_name", db_get("project-name","Unnamed Fossil Project")); |
| 414 | Th_Store("project_description", db_get("project-description","")); |
| 415 | if( zTitle ) Th_Store("title", zTitle); |
| 416 | Th_Store("baseurl", g.zBaseURL); |
| 417 | Th_Store("secureurl", fossil_wants_https(1)? g.zHttpsURL: g.zBaseURL); |
| 418 | Th_Store("home", g.zTop); |
| 419 | Th_Store("index_page", db_get("index-page","/home")); |
| 420 | if( local_zCurrentPage==0 ) style_set_current_page("%T", g.zPath); |
| 421 | Th_Store("current_page", local_zCurrentPage); |
| 422 | Th_Store("csrf_token", g.zCsrfToken); |
| 423 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -389,14 +389,11 @@ | |
| 389 | */ |
| 390 | static char zDfltHeader[] = |
| 391 | @ <html> |
| 392 | @ <head> |
| 393 | @ <base href="$baseurl/$current_page" /> |
| 394 | @ <meta http-equiv="Content-Security-Policy" content="$default_csp" /> |
| 395 | @ <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| 396 | @ <title>$<project_name>: $<title></title> |
| 397 | @ <link rel="alternate" type="application/rss+xml" title="RSS Feed" \ |
| 398 | @ href="$home/timeline.rss" /> |
| 399 | @ <link rel="stylesheet" href="$stylesheet_url" type="text/css" \ |
| @@ -407,16 +404,23 @@ | |
| 404 | |
| 405 | /* |
| 406 | ** Initialize all the default TH1 variables |
| 407 | */ |
| 408 | static void style_init_th1_vars(const char *zTitle){ |
| 409 | const char *zNonce = style_nonce(); |
| 410 | char *zDfltCsp = sqlite3_mprintf("default-src 'self' data: ; " |
| 411 | "script-src 'self' 'nonce-%s' ; " |
| 412 | "style-src 'self' 'unsafe-inline'", |
| 413 | zNonce); |
| 414 | Th_Store("nonce", zNonce); |
| 415 | Th_Store("project_name", db_get("project-name","Unnamed Fossil Project")); |
| 416 | Th_Store("project_description", db_get("project-description","")); |
| 417 | if( zTitle ) Th_Store("title", zTitle); |
| 418 | Th_Store("baseurl", g.zBaseURL); |
| 419 | Th_Store("secureurl", fossil_wants_https(1)? g.zHttpsURL: g.zBaseURL); |
| 420 | Th_Store("default_csp", zDfltCsp); |
| 421 | sqlite3_free(zDfltCsp); |
| 422 | Th_Store("home", g.zTop); |
| 423 | Th_Store("index_page", db_get("index-page","/home")); |
| 424 | if( local_zCurrentPage==0 ) style_set_current_page("%T", g.zPath); |
| 425 | Th_Store("current_page", local_zCurrentPage); |
| 426 | Th_Store("csrf_token", g.zCsrfToken); |
| 427 |
+3
| --- www/customskin.md | ||
| +++ www/customskin.md | ||
| @@ -233,10 +233,13 @@ | ||
| 233 | 233 | * **current_page** - The name of the page currently being processed, |
| 234 | 234 | without the leading "/" and without query parameters. |
| 235 | 235 | Examples: "timeline", "doc/trunk/README.txt", "wiki". |
| 236 | 236 | |
| 237 | 237 | * **csrf_token** - A token used to prevent cross-site request forgery. |
| 238 | + | |
| 239 | + * **default_csp** - The content to be used within the default header | |
| 240 | + for the "Content-Security-Policy" meta tag. | |
| 238 | 241 | |
| 239 | 242 | * **release_version** - The release version of Fossil. Ex: "1.31" |
| 240 | 243 | |
| 241 | 244 | * **manifest_version** - A prefix on the check-in hash of the |
| 242 | 245 | specific version of fossil that is running. Ex: "\[47bb6432a1\]" |
| 243 | 246 |
| --- www/customskin.md | |
| +++ www/customskin.md | |
| @@ -233,10 +233,13 @@ | |
| 233 | * **current_page** - The name of the page currently being processed, |
| 234 | without the leading "/" and without query parameters. |
| 235 | Examples: "timeline", "doc/trunk/README.txt", "wiki". |
| 236 | |
| 237 | * **csrf_token** - A token used to prevent cross-site request forgery. |
| 238 | |
| 239 | * **release_version** - The release version of Fossil. Ex: "1.31" |
| 240 | |
| 241 | * **manifest_version** - A prefix on the check-in hash of the |
| 242 | specific version of fossil that is running. Ex: "\[47bb6432a1\]" |
| 243 |
| --- www/customskin.md | |
| +++ www/customskin.md | |
| @@ -233,10 +233,13 @@ | |
| 233 | * **current_page** - The name of the page currently being processed, |
| 234 | without the leading "/" and without query parameters. |
| 235 | Examples: "timeline", "doc/trunk/README.txt", "wiki". |
| 236 | |
| 237 | * **csrf_token** - A token used to prevent cross-site request forgery. |
| 238 | |
| 239 | * **default_csp** - The content to be used within the default header |
| 240 | for the "Content-Security-Policy" meta tag. |
| 241 | |
| 242 | * **release_version** - The release version of Fossil. Ex: "1.31" |
| 243 | |
| 244 | * **manifest_version** - A prefix on the check-in hash of the |
| 245 | specific version of fossil that is running. Ex: "\[47bb6432a1\]" |
| 246 |