Fossil

Check-in [0a66be2b75]
Login

Check-in [0a66be2b75]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:More intensive use of the Synchronizer Token Pattern for CSRF defense.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | csrf-defense-enhancement
Files: files | file ages | folders
SHA3-256: 0a66be2b7545262a62ec8f45ce82a6ff32750ab8d4038d0e285f1f4684cfbd10
User & Date: drh 2023-09-18 15:10:48.882
Context
2023-09-18
15:24
Fix forum-post approval buttons so that they send the CSRF token. ... (check-in: bf9974cf8d user: drh tags: csrf-defense-enhancement)
15:10
More intensive use of the Synchronizer Token Pattern for CSRF defense. ... (check-in: 0a66be2b75 user: drh tags: csrf-defense-enhancement)
14:32
Strengthen CSRF requirements for the skin editor. ... (check-in: 6912636dc3 user: drh tags: csrf-defense-enhancement)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/alerts.c.
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
    register_page();
    return;
  }
  style_set_current_feature("alerts");
  alert_submenu_common();
  needCaptcha = !login_is_individual();
  if( P("submit")
   && cgi_csrf_safe(1)
   && subscribe_error_check(&eErr,&zErr,needCaptcha)
  ){
    /* A validated request for a new subscription has been received. */
    char ssub[20];
    const char *zEAddr = P("e");
    const char *zCode;  /* New subscriber code (in hex) */
    int nsub = 0;







|







1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
    register_page();
    return;
  }
  style_set_current_feature("alerts");
  alert_submenu_common();
  needCaptcha = !login_is_individual();
  if( P("submit")
   && cgi_csrf_safe(2)
   && subscribe_error_check(&eErr,&zErr,needCaptcha)
  ){
    /* A validated request for a new subscription has been received. */
    char ssub[20];
    const char *zEAddr = P("e");
    const char *zCode;  /* New subscriber code (in hex) */
    int nsub = 0;
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
  }
  if( sid==0 ){
    db_commit_transaction();
    cgi_redirect("subscribe");
    /*NOTREACHED*/
  }
  alert_submenu_common();
  if( P("submit")!=0 && cgi_csrf_safe(1) ){
    char newSsub[10];
    int nsub = 0;
    Blob update;

    sdonotcall = PB("sdonotcall");
    sdigest = PB("sdigest");
    semail = P("semail");







|







1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
  }
  if( sid==0 ){
    db_commit_transaction();
    cgi_redirect("subscribe");
    /*NOTREACHED*/
  }
  alert_submenu_common();
  if( P("submit")!=0 && cgi_csrf_safe(2) ){
    char newSsub[10];
    int nsub = 0;
    Blob update;

    sdonotcall = PB("sdonotcall");
    sdigest = PB("sdigest");
    semail = P("semail");
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
    db_unprotect(PROTECT_READONLY);
    db_multi_exec(
      "UPDATE subscriber SET lastContact=now()/86400"
      " WHERE subscriberId=%d", sid
    );
    db_protect_pop();
  }
  if( P("delete")!=0 && cgi_csrf_safe(1) ){
    if( !PB("dodelete") ){
      eErr = 9;
      zErr = mprintf("Select this checkbox and press \"Unsubscribe\" again to"
                     " unsubscribe");
    }else{
      alert_unsubscribe(sid);
      db_commit_transaction();







|







1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
    db_unprotect(PROTECT_READONLY);
    db_multi_exec(
      "UPDATE subscriber SET lastContact=now()/86400"
      " WHERE subscriberId=%d", sid
    );
    db_protect_pop();
  }
  if( P("delete")!=0 && cgi_csrf_safe(2) ){
    if( !PB("dodelete") ){
      eErr = 9;
      zErr = mprintf("Select this checkbox and press \"Unsubscribe\" again to"
                     " unsubscribe");
    }else{
      alert_unsubscribe(sid);
      db_commit_transaction();
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
    return;
  }

  style_set_current_feature("alerts");

  zEAddr = PD("e","");
  dx = atoi(PD("dx","0"));
  bSubmit = P("submit")!=0 && P("e")!=0 && cgi_csrf_safe(1);
  if( bSubmit ){
    if( !captcha_is_correct(1) ){
      eErr = 2;
      zErr = mprintf("enter the security code shown below");
      bSubmit = 0;
    }
  }







|







2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
    return;
  }

  style_set_current_feature("alerts");

  zEAddr = PD("e","");
  dx = atoi(PD("dx","0"));
  bSubmit = P("submit")!=0 && P("e")!=0 && cgi_csrf_safe(2);
  if( bSubmit ){
    if( !captcha_is_correct(1) ){
      eErr = 2;
      zErr = mprintf("enter the security code shown below");
      bSubmit = 0;
    }
  }
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
    style_finish_page();
    return;
  }
  if( P("submit")!=0 
   && P("subject")!=0
   && P("msg")!=0
   && P("from")!=0
   && cgi_csrf_safe(1)
   && captcha_is_correct(0)
  ){
    Blob hdr, body;
    AlertSender *pSender = alert_sender_new(0,0);
    blob_init(&hdr, 0, 0);
    blob_appendf(&hdr, "To: <%s>\r\nSubject: %s administrator message\r\n",
                 zAdminEmail, db_get("email-subname","Fossil Repo"));







|







3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
    style_finish_page();
    return;
  }
  if( P("submit")!=0 
   && P("subject")!=0
   && P("msg")!=0
   && P("from")!=0
   && cgi_csrf_safe(2)
   && captcha_is_correct(0)
  ){
    Blob hdr, body;
    AlertSender *pSender = alert_sender_new(0,0);
    blob_init(&hdr, 0, 0);
    blob_appendf(&hdr, "To: <%s>\r\nSubject: %s administrator message\r\n",
                 zAdminEmail, db_get("email-subname","Fossil Repo"));
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
  style_set_current_feature("alerts");
  if( fossil_strcmp(P("name"),"test1")==0 ){
    /* Visit the /announce/test1 page to see the CGI variables */
    zAction = "announce/test1";
    @ <p style='border: 1px solid black; padding: 1ex;'>
    cgi_print_all(0, 0, 0);
    @ </p>
  }else if( P("submit")!=0 && cgi_csrf_safe(1) ){
    char *zErr = alert_send_announcement();
    style_header("Announcement Sent");
    if( zErr ){
      @ <h1>Internal Error</h1>
      @ <p>The following error was reported by the system:
      @ <blockquote><pre>
      @ %h(zErr)







|







3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
  style_set_current_feature("alerts");
  if( fossil_strcmp(P("name"),"test1")==0 ){
    /* Visit the /announce/test1 page to see the CGI variables */
    zAction = "announce/test1";
    @ <p style='border: 1px solid black; padding: 1ex;'>
    cgi_print_all(0, 0, 0);
    @ </p>
  }else if( P("submit")!=0 && cgi_csrf_safe(2) ){
    char *zErr = alert_send_announcement();
    style_header("Announcement Sent");
    if( zErr ){
      @ <h1>Internal Error</h1>
      @ <p>The following error was reported by the system:
      @ <blockquote><pre>
      @ %h(zErr)
3500
3501
3502
3503
3504
3505
3506

3507
3508
3509
3510
3511
3512
3513
    @ <a href="https://fossil-scm.org/fossil/doc/trunk/www/alerts.md">set up</a>
    @ for this repository.</p>
    return;
  }

  style_header("Send Announcement");
  @ <form method="POST" action="%R/%s(zAction)">

  @ <table class="subscribe">
  if( g.perm.Admin ){
    int aa = PB("aa");
    int all = PB("all");
    int aMod = PB("mods");
    const char *aack = aa ? "checked" : "";
    const char *allck = all ? "checked" : "";







>







3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
    @ <a href="https://fossil-scm.org/fossil/doc/trunk/www/alerts.md">set up</a>
    @ for this repository.</p>
    return;
  }

  style_header("Send Announcement");
  @ <form method="POST" action="%R/%s(zAction)">
  login_insert_csrf_secret();
  @ <table class="subscribe">
  if( g.perm.Admin ){
    int aa = PB("aa");
    int all = PB("all");
    int aMod = PB("mods");
    const char *aack = aa ? "checked" : "";
    const char *allck = all ? "checked" : "";
Changes to src/forum.c.
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564

1565
1566
1567
1568
1569
1570
1571
  const char *zContent = PDT("content","");

  login_check_credentials();
  if( !g.perm.WrForum ){
    login_needed(g.anon.WrForum);
    return;
  }
  if( P("submit") && cgi_csrf_safe(1) ){
    if( forum_post(zTitle, 0, 0, 0, zMimetype, zContent,
                   forum_post_flags()) ) return;
  }
  if( P("preview") && !whitespace_only(zContent) ){
    @ <h1>Preview:</h1>
    forum_render(zTitle, zMimetype, zContent, "forumEdit", 1);
  }
  style_set_current_feature("forum");
  style_header("New Forum Thread");
  @ <form action="%R/forume1" method="POST">
  @ <h1>New Thread:</h1>
  forum_from_line();
  forum_post_widget(zTitle, zMimetype, zContent);
  @ <input type="submit" name="preview" value="Preview">
  if( P("preview") && !whitespace_only(zContent) ){
    @ <input type="submit" name="submit" value="Submit">
  }else{
    @ <input type="submit" name="submit" value="Submit" disabled>
  }
  forum_render_debug_options();

  @ </form>
  forum_emit_js();
  style_finish_page();
}

/*
** WEBPAGE: forume2







|




















>







1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
  const char *zContent = PDT("content","");

  login_check_credentials();
  if( !g.perm.WrForum ){
    login_needed(g.anon.WrForum);
    return;
  }
  if( P("submit") && cgi_csrf_safe(2) ){
    if( forum_post(zTitle, 0, 0, 0, zMimetype, zContent,
                   forum_post_flags()) ) return;
  }
  if( P("preview") && !whitespace_only(zContent) ){
    @ <h1>Preview:</h1>
    forum_render(zTitle, zMimetype, zContent, "forumEdit", 1);
  }
  style_set_current_feature("forum");
  style_header("New Forum Thread");
  @ <form action="%R/forume1" method="POST">
  @ <h1>New Thread:</h1>
  forum_from_line();
  forum_post_widget(zTitle, zMimetype, zContent);
  @ <input type="submit" name="preview" value="Preview">
  if( P("preview") && !whitespace_only(zContent) ){
    @ <input type="submit" name="submit" value="Submit">
  }else{
    @ <input type="submit" name="submit" value="Submit" disabled>
  }
  forum_render_debug_options();
  login_insert_csrf_secret();
  @ </form>
  forum_emit_js();
  style_finish_page();
}

/*
** WEBPAGE: forume2
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
  if( P("cancel") ){
    cgi_redirectf("%R/forumpost/%S",zFpid);
    return;
  }
  bPreview = P("preview")!=0;
  bReply = P("reply")!=0;
  iClosed = forum_rid_is_closed(fpid, 1);
  isCsrfSafe = cgi_csrf_safe(1);
  bPrivate = content_is_private(fpid);
  bSameUser = login_is_individual()
    && fossil_strcmp(pPost->zUser, g.zLogin)==0;
  if( isCsrfSafe && (g.perm.ModForum || (bPrivate && bSameUser)) ){
    if( g.perm.ModForum && P("approve") ){
      const char *zUserToTrust;
      moderation_approve('f', fpid);







|







1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
  if( P("cancel") ){
    cgi_redirectf("%R/forumpost/%S",zFpid);
    return;
  }
  bPreview = P("preview")!=0;
  bReply = P("reply")!=0;
  iClosed = forum_rid_is_closed(fpid, 1);
  isCsrfSafe = cgi_csrf_safe(2);
  bPrivate = content_is_private(fpid);
  bSameUser = login_is_individual()
    && fossil_strcmp(pPost->zUser, g.zLogin)==0;
  if( isCsrfSafe && (g.perm.ModForum || (bPrivate && bSameUser)) ){
    if( g.perm.ModForum && P("approve") ){
      const char *zUserToTrust;
      moderation_approve('f', fpid);
1677
1678
1679
1680
1681
1682
1683

1684
1685
1686
1687
1688
1689
1690
    style_header("Delete %s", zTitle ? "Post" : "Reply");
    @ <h1>Original Post:</h1>
    forum_render(pPost->zThreadTitle, pPost->zMimetype, pPost->zWiki,
                 "forumEdit", 1);
    @ <h1>Change Into:</h1>
    forum_render(zTitle, zMimetype, zContent,"forumEdit", 1);
    @ <form action="%R/forume2" method="POST">

    @ <input type="hidden" name="fpid" value="%h(P("fpid"))">
    @ <input type="hidden" name="nullout" value="1">
    @ <input type="hidden" name="mimetype" value="%h(zMimetype)">
    @ <input type="hidden" name="content" value="%h(zContent)">
    if( zTitle ){
      @ <input aria-label="Title" type="hidden" name="title" value="%h(zTitle)">
    }







>







1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
    style_header("Delete %s", zTitle ? "Post" : "Reply");
    @ <h1>Original Post:</h1>
    forum_render(pPost->zThreadTitle, pPost->zMimetype, pPost->zWiki,
                 "forumEdit", 1);
    @ <h1>Change Into:</h1>
    forum_render(zTitle, zMimetype, zContent,"forumEdit", 1);
    @ <form action="%R/forume2" method="POST">
    login_insert_csrf_secret();
    @ <input type="hidden" name="fpid" value="%h(P("fpid"))">
    @ <input type="hidden" name="nullout" value="1">
    @ <input type="hidden" name="mimetype" value="%h(zMimetype)">
    @ <input type="hidden" name="content" value="%h(zContent)">
    if( zTitle ){
      @ <input aria-label="Title" type="hidden" name="title" value="%h(zTitle)">
    }
1704
1705
1706
1707
1708
1709
1710

1711
1712
1713
1714
1715
1716
1717
                 "forumEdit", 1);
    if( bPreview ){
      @ <h2>Preview of Edited Post:</h2>
      forum_render(zTitle, zMimetype, zContent,"forumEdit", 1);
    }
    @ <h2>Revised Message:</h2>
    @ <form action="%R/forume2" method="POST">

    @ <input type="hidden" name="fpid" value="%h(P("fpid"))">
    @ <input type="hidden" name="edit" value="1">
    forum_from_line();
    forum_post_widget(zTitle, zMimetype, zContent);
  }else{
    /* Reply */
    char *zDisplayName;







>







1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
                 "forumEdit", 1);
    if( bPreview ){
      @ <h2>Preview of Edited Post:</h2>
      forum_render(zTitle, zMimetype, zContent,"forumEdit", 1);
    }
    @ <h2>Revised Message:</h2>
    @ <form action="%R/forume2" method="POST">
    login_insert_csrf_secret();
    @ <input type="hidden" name="fpid" value="%h(P("fpid"))">
    @ <input type="hidden" name="edit" value="1">
    forum_from_line();
    forum_post_widget(zTitle, zMimetype, zContent);
  }else{
    /* Reply */
    char *zDisplayName;
1748
1749
1750
1751
1752
1753
1754

1755
1756
1757
1758
1759
1760
1761
  @ <input type="submit" name="cancel" value="Cancel">
  if( (bPreview && !whitespace_only(zContent)) || isDelete ){
    if( !iClosed || g.perm.Admin ) {
      @ <input type="submit" name="submit" value="Submit">
    }
  }
  forum_render_debug_options();

  @ </form>
  forum_emit_js();
  style_finish_page();
}

/*
** WEBPAGE: setup_forum







>







1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
  @ <input type="submit" name="cancel" value="Cancel">
  if( (bPreview && !whitespace_only(zContent)) || isDelete ){
    if( !iClosed || g.perm.Admin ) {
      @ <input type="submit" name="submit" value="Submit">
    }
  }
  forum_render_debug_options();
  login_insert_csrf_secret();
  @ </form>
  forum_emit_js();
  style_finish_page();
}

/*
** WEBPAGE: setup_forum
Changes to src/interwiki.c.
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
  char *zErr = 0;

  login_check_credentials();
  if( !g.perm.Read && !g.perm.RdWiki && ~g.perm.RdTkt ){
    login_needed(0);
    return;
  }
  if( g.perm.Setup && P("submit")!=0 && cgi_csrf_safe(1) ){
    zTag = PT("tag");
    zBase = PT("base");
    zHash = PT("hash");
    zWiki = PT("wiki");
    if( zTag==0 || zTag[0]==0 || !interwiki_valid_name(zTag) ){
      zErr = mprintf("Not a valid interwiki tag name: \"%s\"", zTag?zTag : "");
    }else if( zBase==0 || zBase[0]==0 ){







|







312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
  char *zErr = 0;

  login_check_credentials();
  if( !g.perm.Read && !g.perm.RdWiki && ~g.perm.RdTkt ){
    login_needed(0);
    return;
  }
  if( g.perm.Setup && P("submit")!=0 && cgi_csrf_safe(2) ){
    zTag = PT("tag");
    zBase = PT("base");
    zHash = PT("hash");
    zWiki = PT("wiki");
    if( zTag==0 || zTag[0]==0 || !interwiki_valid_name(zTag) ){
      zErr = mprintf("Not a valid interwiki tag name: \"%s\"", zTag?zTag : "");
    }else if( zBase==0 || zBase[0]==0 ){
Changes to src/login.c.
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
  zUserID = PDT("u","");
  zPasswd = PDT("p","");
  zConfirm = PDT("cp","");
  zEAddr = PDT("ea","");
  zDName = PDT("dn","");

  /* Verify user imputs */
  if( P("new")==0 || !cgi_csrf_safe(1) ){
    /* This is not a valid form submission.  Fall through into
    ** the form display */
  }else if( (captchaIsCorrect = captcha_is_correct(1))==0 ){
    iErrLine = 6;
    zErr = "Incorrect CAPTCHA";
  }else if( strlen(zUserID)<6 ){
    iErrLine = 1;







|







1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
  zUserID = PDT("u","");
  zPasswd = PDT("p","");
  zConfirm = PDT("cp","");
  zEAddr = PDT("ea","");
  zDName = PDT("dn","");

  /* Verify user imputs */
  if( P("new")==0 || !cgi_csrf_safe(2) ){
    /* This is not a valid form submission.  Fall through into
    ** the form display */
  }else if( (captchaIsCorrect = captcha_is_correct(1))==0 ){
    iErrLine = 6;
    zErr = "Incorrect CAPTCHA";
  }else if( strlen(zUserID)<6 ){
    iErrLine = 1;
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
    @ with the project administrator.
    style_finish_page();
    return;
  }
  zEAddr = PDT("ea","");

  /* Verify user imputs */
  if( !cgi_csrf_safe(1) || P("reqpwreset")==0 ){
    /* This is the initial display of the form.  No processing or error
    ** checking is to be done. Fall through into the form display
    */
  }else if( (captchaIsCorrect = captcha_is_correct(1))==0 ){
    iErrLine = 2;
    zErr = "Incorrect CAPTCHA";
  }else if( zEAddr[0]==0 ){







|







2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
    @ with the project administrator.
    style_finish_page();
    return;
  }
  zEAddr = PDT("ea","");

  /* Verify user imputs */
  if( !cgi_csrf_safe(2) || P("reqpwreset")==0 ){
    /* This is the initial display of the form.  No processing or error
    ** checking is to be done. Fall through into the form display
    */
  }else if( (captchaIsCorrect = captcha_is_correct(1))==0 ){
    iErrLine = 2;
    zErr = "Incorrect CAPTCHA";
  }else if( zEAddr[0]==0 ){
Changes to src/security_audit.c.
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812

813
814
815
816
817
818
819
    @ the "fossil http" or "fossil server" commands then add
    @ a command-line option "--errorlog <i>FILENAME</i>" to that
    @ command.
    @ </ol>
    style_finish_page();
    return;
  }
  if( P("truncate1") && cgi_csrf_safe(1) ){
    fclose(fopen(g.zErrlog,"w"));
  }
  if( P("download") ){
    Blob log;
    blob_read_from_file(&log, g.zErrlog, ExtFILE);
    cgi_set_content_type("text/plain");
    cgi_set_content(&log);
    return;
  }
  szFile = file_size(g.zErrlog, ExtFILE);
  if( P("truncate") ){
    @ <form action="%R/errorlog" method="POST">

    @ <p>Confirm that you want to truncate the %,lld(szFile)-byte error log:
    @ <input type="submit" name="truncate1" value="Confirm">
    @ <input type="submit" name="cancel" value="Cancel">
    @ </form>
    style_finish_page();
    return;
  }







|












>







793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
    @ the "fossil http" or "fossil server" commands then add
    @ a command-line option "--errorlog <i>FILENAME</i>" to that
    @ command.
    @ </ol>
    style_finish_page();
    return;
  }
  if( P("truncate1") && cgi_csrf_safe(2) ){
    fclose(fopen(g.zErrlog,"w"));
  }
  if( P("download") ){
    Blob log;
    blob_read_from_file(&log, g.zErrlog, ExtFILE);
    cgi_set_content_type("text/plain");
    cgi_set_content(&log);
    return;
  }
  szFile = file_size(g.zErrlog, ExtFILE);
  if( P("truncate") ){
    @ <form action="%R/errorlog" method="POST">
    login_insert_csrf_secret();
    @ <p>Confirm that you want to truncate the %,lld(szFile)-byte error log:
    @ <input type="submit" name="truncate1" value="Confirm">
    @ <input type="submit" name="cancel" value="Cancel">
    @ </form>
    style_finish_page();
    return;
  }
Changes to src/setup.c.
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
void setup_adunit(void){
  login_check_credentials();
  if( !g.perm.Admin ){
    login_needed(0);
    return;
  }
  db_begin_transaction();
  if( P("clear")!=0 && cgi_csrf_safe(1) ){
    db_unprotect(PROTECT_CONFIG);
    db_multi_exec("DELETE FROM config WHERE name GLOB 'adunit*'");
    db_protect_pop();
    cgi_replace_parameter("adunit","");
    cgi_replace_parameter("adright","");
    setup_incr_cfgcnt();
  }







|







1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
void setup_adunit(void){
  login_check_credentials();
  if( !g.perm.Admin ){
    login_needed(0);
    return;
  }
  db_begin_transaction();
  if( P("clear")!=0 && cgi_csrf_safe(2) ){
    db_unprotect(PROTECT_CONFIG);
    db_multi_exec("DELETE FROM config WHERE name GLOB 'adunit*'");
    db_protect_pop();
    cgi_replace_parameter("adunit","");
    cgi_replace_parameter("adright","");
    setup_incr_cfgcnt();
  }
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
  }
  login_check_credentials();
  if( !g.perm.Admin ){
    login_needed(0);
    return;
  }
  db_begin_transaction();
  if( !cgi_csrf_safe(1) ){
    /* Allow no state changes if not safe from CSRF */
  }else if( P("setlogo")!=0 && zLogoMime && zLogoMime[0] && szLogoImg>0 ){
    Blob img;
    Stmt ins;
    blob_init(&img, aLogoImg, szLogoImg);
    db_unprotect(PROTECT_CONFIG);
    db_prepare(&ins,







|







1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
  }
  login_check_credentials();
  if( !g.perm.Admin ){
    login_needed(0);
    return;
  }
  db_begin_transaction();
  if( !cgi_csrf_safe(2) ){
    /* Allow no state changes if not safe from CSRF */
  }else if( P("setlogo")!=0 && zLogoMime && zLogoMime[0] && szLogoImg>0 ){
    Blob img;
    Stmt ins;
    blob_init(&img, aLogoImg, szLogoImg);
    db_unprotect(PROTECT_CONFIG);
    db_prepare(&ins,
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
  int go = P("go")!=0;
  login_check_credentials();
  if( !g.perm.Setup ){
    login_needed(0);
    return;
  }
  add_content_sql_commands(g.db);
  zQ = cgi_csrf_safe(1) ? P("q") : 0;
  style_set_current_feature("setup");
  style_header("Raw SQL Commands");
  @ <p><b>Caution:</b> There are no restrictions on the SQL that can be
  @ run by this page.  You can do serious and irrepairable damage to the
  @ repository.  Proceed with extreme caution.</p>
  @
#if 0







|







1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
  int go = P("go")!=0;
  login_check_credentials();
  if( !g.perm.Setup ){
    login_needed(0);
    return;
  }
  add_content_sql_commands(g.db);
  zQ = cgi_csrf_safe(2) ? P("q") : 0;
  style_set_current_feature("setup");
  style_header("Raw SQL Commands");
  @ <p><b>Caution:</b> There are no restrictions on the SQL that can be
  @ run by this page.  You can do serious and irrepairable damage to the
  @ repository.  Proceed with extreme caution.</p>
  @
#if 0
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
*/
static void setup_update_url_alias(
  Blob *pSql,
  const char *zOldName,
  const char *zNewName,
  const char *zValue
){
  if( !cgi_csrf_safe(1) ) return;
  if( zNewName[0]==0 || zValue[0]==0 ){
    if( zOldName[0] ){
      blob_append_sql(pSql,
        "DELETE FROM config WHERE name='walias:%q';\n",
        zOldName);
    }
    return;







|







2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
*/
static void setup_update_url_alias(
  Blob *pSql,
  const char *zOldName,
  const char *zNewName,
  const char *zValue
){
  if( !cgi_csrf_safe(2) ) return;
  if( zNewName[0]==0 || zValue[0]==0 ){
    if( zOldName[0] ){
      blob_append_sql(pSql,
        "DELETE FROM config WHERE name='walias:%q';\n",
        zOldName);
    }
    return;
Changes to src/setupuser.c.
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
  if( P("can") ){
    /* User pressed the cancel button */
    cgi_redirect(cgi_referer("setup_ulist"));
    return;
  }

  /* Check for requests to delete the user */
  if( P("delete") && cgi_csrf_safe(1) ){
    int n;
    if( P("verifydelete") ){
      /* Verified delete user request */
      db_unprotect(PROTECT_USER);
      if( alert_tables_exist() ){
        /* Also delete any subscriptions associated with this user */
        db_multi_exec("DELETE FROM subscriber WHERE suname="







|







340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
  if( P("can") ){
    /* User pressed the cancel button */
    cgi_redirect(cgi_referer("setup_ulist"));
    return;
  }

  /* Check for requests to delete the user */
  if( P("delete") && cgi_csrf_safe(2) ){
    int n;
    if( P("verifydelete") ){
      /* Verified delete user request */
      db_unprotect(PROTECT_USER);
      if( alert_tables_exist() ){
        /* Also delete any subscriptions associated with this user */
        db_multi_exec("DELETE FROM subscriber WHERE suname="
Changes to src/style.c.
1458
1459
1460
1461
1462
1463
1464
1465



















1466
1467
1468
1469
1470
1471
1472
      @ anonymous-adds = %s(find_anon_capabilities(zCap))<br>
    }
    @ g.zRepositoryName = %h(g.zRepositoryName)<br>
    @ load_average() = %f(load_average())<br>
#ifndef _WIN32
    @ RSS = %.2f(fossil_rss()/1000000.0) MB</br>
#endif
    @ cgi_csrf_safe(0) = %d(cgi_csrf_safe(0))<br>



















    @ fossil_exe_id() = %h(fossil_exe_id())<br>
    if( g.perm.Admin ){
      int k;
      for(k=0; g.argvOrig[k]; k++){
        Blob t;
        blob_init(&t, 0, 0);
        blob_append_escaped_arg(&t, g.argvOrig[k], 0);







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
      @ anonymous-adds = %s(find_anon_capabilities(zCap))<br>
    }
    @ g.zRepositoryName = %h(g.zRepositoryName)<br>
    @ load_average() = %f(load_average())<br>
#ifndef _WIN32
    @ RSS = %.2f(fossil_rss()/1000000.0) MB</br>
#endif
    (void)cgi_csrf_safe(2);
    switch( g.okCsrf ){
      case 1: {
         @ CSRF safety = Same origin<br>
         break;
      }
      case 2: {
         @ CSRF safety = Same origin, POST<br>
         break;
      }
      case 3: {
         @ CSRF safety = Same origin, POST, CSRF token<br>
         break;
      }
      default: {
         @ CSRF safety = unsafe<br>
         break;
      }
    }
    
    @ fossil_exe_id() = %h(fossil_exe_id())<br>
    if( g.perm.Admin ){
      int k;
      for(k=0; g.argvOrig[k]; k++){
        Blob t;
        blob_init(&t, 0, 0);
        blob_append_escaped_arg(&t, g.argvOrig[k], 0);