Fossil SCM
Disable CSP for /chat with a ping= query parameter. This is a drastic measure to get the feature working. We can work on providing a better solution later.
Commit
02961b80782e93931548889fa4833d40705d609b70df0964eaa3d9bc53a39043
Parent
b4862238ec50899…
2 files changed
+5
-1
+20
-1
+5
-1
| --- src/chat.c | ||
| +++ src/chat.c | ||
| @@ -89,10 +89,11 @@ | ||
| 89 | 89 | login_needed(g.anon.Chat); |
| 90 | 90 | return; |
| 91 | 91 | } |
| 92 | 92 | iPingTcp = atoi(PD("ping","0")); |
| 93 | 93 | if( iPingTcp<1000 || iPingTcp>65535 ) iPingTcp = 0; |
| 94 | + if( iPingTcp ) style_disable_csp(); | |
| 94 | 95 | style_set_current_feature("chat"); |
| 95 | 96 | style_header("Chat"); |
| 96 | 97 | @ <style> |
| 97 | 98 | @ #dialog { |
| 98 | 99 | @ width: 97%%; |
| @@ -569,10 +570,11 @@ | ||
| 569 | 570 | ** be sent to the TTY on which the "fossil chat" command is run, thus |
| 570 | 571 | ** causing an auditory notification. |
| 571 | 572 | */ |
| 572 | 573 | void chat_command(void){ |
| 573 | 574 | const char *zUrl = 0; |
| 575 | + size_t i; | |
| 574 | 576 | char *azArgv[5]; |
| 575 | 577 | db_find_and_open_repository(0,0); |
| 576 | 578 | if( g.argc==3 ){ |
| 577 | 579 | zUrl = g.argv[2]; |
| 578 | 580 | }else if( g.argc!=2 ){ |
| @@ -599,11 +601,13 @@ | ||
| 599 | 601 | fossil_fatal("Not a valid URL: %s", zUrl); |
| 600 | 602 | } |
| 601 | 603 | azArgv[0] = g.argv[0]; |
| 602 | 604 | azArgv[1] = "ui"; |
| 603 | 605 | azArgv[2] = "--internal-chat-url"; |
| 604 | - azArgv[3] = mprintf("%s/chat?ping=%%d", zUrl); | |
| 606 | + i = strlen(zUrl); | |
| 607 | + if( i && zUrl[i-1]=='/' ) i--; | |
| 608 | + azArgv[3] = mprintf("%.*s/chat?ping=%%d", i, zUrl); | |
| 605 | 609 | azArgv[4] = 0; |
| 606 | 610 | g.argv = azArgv; |
| 607 | 611 | g.argc = 4; |
| 608 | 612 | cmd_webserver(); |
| 609 | 613 | } |
| 610 | 614 |
| --- src/chat.c | |
| +++ src/chat.c | |
| @@ -89,10 +89,11 @@ | |
| 89 | login_needed(g.anon.Chat); |
| 90 | return; |
| 91 | } |
| 92 | iPingTcp = atoi(PD("ping","0")); |
| 93 | if( iPingTcp<1000 || iPingTcp>65535 ) iPingTcp = 0; |
| 94 | style_set_current_feature("chat"); |
| 95 | style_header("Chat"); |
| 96 | @ <style> |
| 97 | @ #dialog { |
| 98 | @ width: 97%%; |
| @@ -569,10 +570,11 @@ | |
| 569 | ** be sent to the TTY on which the "fossil chat" command is run, thus |
| 570 | ** causing an auditory notification. |
| 571 | */ |
| 572 | void chat_command(void){ |
| 573 | const char *zUrl = 0; |
| 574 | char *azArgv[5]; |
| 575 | db_find_and_open_repository(0,0); |
| 576 | if( g.argc==3 ){ |
| 577 | zUrl = g.argv[2]; |
| 578 | }else if( g.argc!=2 ){ |
| @@ -599,11 +601,13 @@ | |
| 599 | fossil_fatal("Not a valid URL: %s", zUrl); |
| 600 | } |
| 601 | azArgv[0] = g.argv[0]; |
| 602 | azArgv[1] = "ui"; |
| 603 | azArgv[2] = "--internal-chat-url"; |
| 604 | azArgv[3] = mprintf("%s/chat?ping=%%d", zUrl); |
| 605 | azArgv[4] = 0; |
| 606 | g.argv = azArgv; |
| 607 | g.argc = 4; |
| 608 | cmd_webserver(); |
| 609 | } |
| 610 |
| --- src/chat.c | |
| +++ src/chat.c | |
| @@ -89,10 +89,11 @@ | |
| 89 | login_needed(g.anon.Chat); |
| 90 | return; |
| 91 | } |
| 92 | iPingTcp = atoi(PD("ping","0")); |
| 93 | if( iPingTcp<1000 || iPingTcp>65535 ) iPingTcp = 0; |
| 94 | if( iPingTcp ) style_disable_csp(); |
| 95 | style_set_current_feature("chat"); |
| 96 | style_header("Chat"); |
| 97 | @ <style> |
| 98 | @ #dialog { |
| 99 | @ width: 97%%; |
| @@ -569,10 +570,11 @@ | |
| 570 | ** be sent to the TTY on which the "fossil chat" command is run, thus |
| 571 | ** causing an auditory notification. |
| 572 | */ |
| 573 | void chat_command(void){ |
| 574 | const char *zUrl = 0; |
| 575 | size_t i; |
| 576 | char *azArgv[5]; |
| 577 | db_find_and_open_repository(0,0); |
| 578 | if( g.argc==3 ){ |
| 579 | zUrl = g.argv[2]; |
| 580 | }else if( g.argc!=2 ){ |
| @@ -599,11 +601,13 @@ | |
| 601 | fossil_fatal("Not a valid URL: %s", zUrl); |
| 602 | } |
| 603 | azArgv[0] = g.argv[0]; |
| 604 | azArgv[1] = "ui"; |
| 605 | azArgv[2] = "--internal-chat-url"; |
| 606 | i = strlen(zUrl); |
| 607 | if( i && zUrl[i-1]=='/' ) i--; |
| 608 | azArgv[3] = mprintf("%.*s/chat?ping=%%d", i, zUrl); |
| 609 | azArgv[4] = 0; |
| 610 | g.argv = azArgv; |
| 611 | g.argc = 4; |
| 612 | cmd_webserver(); |
| 613 | } |
| 614 |
+20
-1
| --- src/style.c | ||
| +++ src/style.c | ||
| @@ -84,10 +84,16 @@ | ||
| 84 | 84 | /* |
| 85 | 85 | ** Submenu disable flag |
| 86 | 86 | */ |
| 87 | 87 | static int submenuEnable = 1; |
| 88 | 88 | |
| 89 | +/* | |
| 90 | +** Disable content-security-policy. | |
| 91 | +** Warning: Do not disable the CSP without careful consideration! | |
| 92 | +*/ | |
| 93 | +static int disableCSP = 0; | |
| 94 | + | |
| 89 | 95 | /* |
| 90 | 96 | ** Flags for various javascript files needed prior to </body> |
| 91 | 97 | */ |
| 92 | 98 | static int needHrefJs = 0; /* href.js */ |
| 93 | 99 | |
| @@ -525,15 +531,17 @@ | ||
| 525 | 531 | char *style_csp(int toHeader){ |
| 526 | 532 | static const char zBackupCSP[] = |
| 527 | 533 | "default-src 'self' data:; " |
| 528 | 534 | "script-src 'self' 'nonce-$nonce'; " |
| 529 | 535 | "style-src 'self' 'unsafe-inline'"; |
| 530 | - const char *zFormat = db_get("default-csp",""); | |
| 536 | + const char *zFormat; | |
| 531 | 537 | Blob csp; |
| 532 | 538 | char *zNonce; |
| 533 | 539 | char *zCsp; |
| 534 | 540 | int i; |
| 541 | + if( disableCSP ) return fossil_strdup(""); | |
| 542 | + zFormat = db_get("default-csp",""); | |
| 535 | 543 | if( zFormat[0]==0 ){ |
| 536 | 544 | zFormat = zBackupCSP; |
| 537 | 545 | } |
| 538 | 546 | blob_init(&csp, 0, 0); |
| 539 | 547 | while( zFormat[0] && (zNonce = strstr(zFormat,"$nonce"))!=0 ){ |
| @@ -549,10 +557,21 @@ | ||
| 549 | 557 | if( toHeader ){ |
| 550 | 558 | cgi_printf_header("Content-Security-Policy: %s\r\n", zCsp); |
| 551 | 559 | } |
| 552 | 560 | return zCsp; |
| 553 | 561 | } |
| 562 | + | |
| 563 | +/* | |
| 564 | +** Disable content security policy for the current page. | |
| 565 | +** WARNING: Do not do this lightly! | |
| 566 | +** | |
| 567 | +** This routine must be called before the CSP is sued by | |
| 568 | +** style_header(). | |
| 569 | +*/ | |
| 570 | +void style_disable_csp(void){ | |
| 571 | + disableCSP = 1; | |
| 572 | +} | |
| 554 | 573 | |
| 555 | 574 | /* |
| 556 | 575 | ** Default HTML page header text through <body>. If the repository-specific |
| 557 | 576 | ** header template lacks a <body> tag, then all of the following is |
| 558 | 577 | ** prepended. |
| 559 | 578 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -84,10 +84,16 @@ | |
| 84 | /* |
| 85 | ** Submenu disable flag |
| 86 | */ |
| 87 | static int submenuEnable = 1; |
| 88 | |
| 89 | /* |
| 90 | ** Flags for various javascript files needed prior to </body> |
| 91 | */ |
| 92 | static int needHrefJs = 0; /* href.js */ |
| 93 | |
| @@ -525,15 +531,17 @@ | |
| 525 | char *style_csp(int toHeader){ |
| 526 | static const char zBackupCSP[] = |
| 527 | "default-src 'self' data:; " |
| 528 | "script-src 'self' 'nonce-$nonce'; " |
| 529 | "style-src 'self' 'unsafe-inline'"; |
| 530 | const char *zFormat = db_get("default-csp",""); |
| 531 | Blob csp; |
| 532 | char *zNonce; |
| 533 | char *zCsp; |
| 534 | int i; |
| 535 | if( zFormat[0]==0 ){ |
| 536 | zFormat = zBackupCSP; |
| 537 | } |
| 538 | blob_init(&csp, 0, 0); |
| 539 | while( zFormat[0] && (zNonce = strstr(zFormat,"$nonce"))!=0 ){ |
| @@ -549,10 +557,21 @@ | |
| 549 | if( toHeader ){ |
| 550 | cgi_printf_header("Content-Security-Policy: %s\r\n", zCsp); |
| 551 | } |
| 552 | return zCsp; |
| 553 | } |
| 554 | |
| 555 | /* |
| 556 | ** Default HTML page header text through <body>. If the repository-specific |
| 557 | ** header template lacks a <body> tag, then all of the following is |
| 558 | ** prepended. |
| 559 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -84,10 +84,16 @@ | |
| 84 | /* |
| 85 | ** Submenu disable flag |
| 86 | */ |
| 87 | static int submenuEnable = 1; |
| 88 | |
| 89 | /* |
| 90 | ** Disable content-security-policy. |
| 91 | ** Warning: Do not disable the CSP without careful consideration! |
| 92 | */ |
| 93 | static int disableCSP = 0; |
| 94 | |
| 95 | /* |
| 96 | ** Flags for various javascript files needed prior to </body> |
| 97 | */ |
| 98 | static int needHrefJs = 0; /* href.js */ |
| 99 | |
| @@ -525,15 +531,17 @@ | |
| 531 | char *style_csp(int toHeader){ |
| 532 | static const char zBackupCSP[] = |
| 533 | "default-src 'self' data:; " |
| 534 | "script-src 'self' 'nonce-$nonce'; " |
| 535 | "style-src 'self' 'unsafe-inline'"; |
| 536 | const char *zFormat; |
| 537 | Blob csp; |
| 538 | char *zNonce; |
| 539 | char *zCsp; |
| 540 | int i; |
| 541 | if( disableCSP ) return fossil_strdup(""); |
| 542 | zFormat = db_get("default-csp",""); |
| 543 | if( zFormat[0]==0 ){ |
| 544 | zFormat = zBackupCSP; |
| 545 | } |
| 546 | blob_init(&csp, 0, 0); |
| 547 | while( zFormat[0] && (zNonce = strstr(zFormat,"$nonce"))!=0 ){ |
| @@ -549,10 +557,21 @@ | |
| 557 | if( toHeader ){ |
| 558 | cgi_printf_header("Content-Security-Policy: %s\r\n", zCsp); |
| 559 | } |
| 560 | return zCsp; |
| 561 | } |
| 562 | |
| 563 | /* |
| 564 | ** Disable content security policy for the current page. |
| 565 | ** WARNING: Do not do this lightly! |
| 566 | ** |
| 567 | ** This routine must be called before the CSP is sued by |
| 568 | ** style_header(). |
| 569 | */ |
| 570 | void style_disable_csp(void){ |
| 571 | disableCSP = 1; |
| 572 | } |
| 573 | |
| 574 | /* |
| 575 | ** Default HTML page header text through <body>. If the repository-specific |
| 576 | ** header template lacks a <body> tag, then all of the following is |
| 577 | ** prepended. |
| 578 |