Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Robot defense uses a mousedown event rather than mouse motion as one of the signals that the request is from a human. This should make robot defense work better for users on mobile. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
8d4e11432d2d54a7c3445b465d14c5ce |
User & Date: | drh 2022-02-12 00:38:06 |
Context
2022-02-12
| ||
01:01 | Modify the /honeypot to explain the situation to human readers who might accidentally reach it, and offer them a links to the login page to prove their humanness. ... (check-in: 533c2c71 user: drh tags: trunk) | |
00:38 | Robot defense uses a mousedown event rather than mouse motion as one of the signals that the request is from a human. This should make robot defense work better for users on mobile. ... (check-in: 8d4e1143 user: drh tags: trunk) | |
2022-02-11
| ||
21:25 | The REQUEST_URI CGI parameter should not include the QUERY_STRING. ... (check-in: 5bb921dd user: drh tags: trunk) | |
Changes
Changes to src/href.js.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** (with type='application/json' to avoid Content Security Policy issues) ** containing: ** ** {"delay":MILLISECONDS, "mouseover":BOOLEAN} ** ** The <script> must have an id='href-data'. DELAY is the number ** milliseconds delay prior to populating href= and action=. If the | | | > | > > > > > > > > < < | < | < | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | ** (with type='application/json' to avoid Content Security Policy issues) ** containing: ** ** {"delay":MILLISECONDS, "mouseover":BOOLEAN} ** ** The <script> must have an id='href-data'. DELAY is the number ** milliseconds delay prior to populating href= and action=. If the ** mouseover boolean is true, then the href= rewrite is further delayed ** until the first mousedown event that occurs after the timer expires. */ var antiRobotOnce = 0; function antiRobotSetAllHrefs(){ if( antiRobotOnce ) return; antiRobotOnce = 1; var anchors = document.getElementsByTagName("a"); for(var i=0; i<anchors.length; i++){ var j = anchors[i]; if(j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); } var forms = document.getElementsByTagName("form"); for(var i=0; i<forms.length; i++){ var j = forms[i]; if(j.hasAttribute("data-action")) j.action=j.getAttribute("data-action"); } } function antiRobotSetMouseEventHandler(){ document.getElementsByTagName("body")[0].onmousedown=function(){ antiRobotSetAllHrefs(); document.getElementsByTagName("body")[0].onmousedown=null; } } function antiRobotDefense(){ var x = document.getElementById("href-data"); var jx = x.textContent || x.innerText; var g = JSON.parse(jx); if( g.mouseover ){ setTimeout(antiRobotSetMouseEventHandler, g.delay); }else{ setTimeout(antiRobotSetAllHrefs, g.delay); } } antiRobotDefense(); |
Changes to src/security_audit.c.
︙ | ︙ | |||
487 488 489 490 491 492 493 | @ Suggested remediation: @ <ol type="a"> @ <li>Remove the 'h' privilege from the @ <a href="%R/setup_uedit?id=%d(nobodyId)">'nobody' user</a> so that @ robots cannot see hyperlinks. @ <li>Activate <a href="%R/setup_access#autoh">autohyperlink</a> so that @ human readers can still see hyperlinks even if they are not logged in. | < | > | 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 | @ Suggested remediation: @ <ol type="a"> @ <li>Remove the 'h' privilege from the @ <a href="%R/setup_uedit?id=%d(nobodyId)">'nobody' user</a> so that @ robots cannot see hyperlinks. @ <li>Activate <a href="%R/setup_access#autoh">autohyperlink</a> so that @ human readers can still see hyperlinks even if they are not logged in. @ Set the delay to at least 50 milliseconds and require a mousedown @ event for maximum robot defense. if( anonId>0 ){ @ <li>Perhaps set the 'h' privilege on the @ <a href="%R/setup_uedit?id=%d(anonId)">'anonymous' user</a> so @ that humans that have javascript disabled in their browsers can @ still see hyperlinks if they will log in as "anonymous". } @ </ol> |
︙ | ︙ |
Changes to src/setup.c.
︙ | ︙ | |||
470 471 472 473 474 475 476 | @ <p>Enable hyperlinks (the equivalent of the "h" permission) for all users, @ including user "nobody", as long as @ <ol><li>the User-Agent string in the @ HTTP header indicates that the request is coming from an actual human @ being, and @ <li>the user agent is able to @ run Javascript in order to set the href= attribute of hyperlinks, and | < | > > | | | | < | > > > > | | | 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 | @ <p>Enable hyperlinks (the equivalent of the "h" permission) for all users, @ including user "nobody", as long as @ <ol><li>the User-Agent string in the @ HTTP header indicates that the request is coming from an actual human @ being, and @ <li>the user agent is able to @ run Javascript in order to set the href= attribute of hyperlinks, and @ <li>a number of milliseconds have passed since the page loaded, and @ <li>a mousedown event is detected (optional - see the checkbox below) @ </ol> @ @ <p>This setting is designed to give easy access to humans while @ keeping out robots and spiders. @ You do not normally want a robot to walk your entire repository because @ if it does, your server will end up computing diffs and annotations for @ every historical version of every file and creating ZIPs and tarballs of @ every historical check-in, which can use a lot of CPU and bandwidth @ even for relatively small projects.</p> @ @ <p>Additional parameters that control this behavior:</p> @ <blockquote> entry_attribute("Delay in milliseconds before enabling hyperlinks", 5, "auto-hyperlink-delay", "ah-delay", "50", 0); @ <br /> onoff_attribute("Also require a mousedown event before enabling hyperlinks", "auto-hyperlink-mouseover", "ahmo", 0, 0); @ </blockquote> @ <p>For maximum robot defense, "Delay" should be at least 50 milliseconds @ and "require a mousedown event" should turned on. To test to see that @ this mechanism is working, visit the <a href="%R/test_env">/test_env</a> @ page (from a separate web browser that is not logged in, even as @ "anonymous") and verify that the "g.javascriptHyperlink" value is "1".</p> @ <p>(Properties: "auto-hyperlink", "auto-hyperlink-delay", and @ "auto-hyperlink-mouseover"")</p> @ <hr /> onoff_attribute("Require a CAPTCHA if not logged in", "require-captcha", "reqcapt", 1, 0); @ <p>Require a CAPTCHA for edit operations (appending, creating, or @ editing wiki or tickets or adding attachments to wiki or tickets) @ for users who are not logged in. (Property: "require-captcha")</p> |
︙ | ︙ |
Changes to src/style.c.
︙ | ︙ | |||
112 113 114 115 116 117 118 | ** and g.perm.Hyperlink variables. ** ** g.perm.Hyperlink g.javascriptHyperlink Returned anchor format ** ---------------- --------------------- ------------------------ ** 0 0 (empty string) ** 0 1 (empty string) ** 1 0 <a href="URL"> | | | > | | | 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | ** and g.perm.Hyperlink variables. ** ** g.perm.Hyperlink g.javascriptHyperlink Returned anchor format ** ---------------- --------------------- ------------------------ ** 0 0 (empty string) ** 0 1 (empty string) ** 1 0 <a href="URL"> ** 1 1 <a data-href="URL"> ** ** No anchor tag is generated if g.perm.Hyperlink is false. ** The href="URL" form is used if g.javascriptHyperlink is false. ** If g.javascriptHyperlink is true then the data-href="URL" and ** href="/honeypot" is generated and javascript is added to the footer ** to cause data-href values to be inserted into href ** after the page has loaded. The use of the data-href="URL" form ** instead of href="URL" is a defense against bots. ** ** If the user lacks the Hyperlink (h) property and the "auto-hyperlink" ** setting is true, then g.perm.Hyperlink is changed from 0 to 1 and ** g.javascriptHyperlink is set to 1 by login_check_credentials(). Thus ** the g.perm.Hyperlink property will be true even if the user does not ** have the "h" privilege if the "auto-hyperlink" setting is true. |
︙ | ︙ | |||
140 141 142 143 144 145 146 | ** ** So, in other words, tracing input configuration to final actions we have: ** ** User has "h" auto-hyperlink Returned anchor format ** ------------ -------------- ---------------------- ** 0 0 (empty string) ** 1 0 <a href="URL"> | | | | 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | ** ** So, in other words, tracing input configuration to final actions we have: ** ** User has "h" auto-hyperlink Returned anchor format ** ------------ -------------- ---------------------- ** 0 0 (empty string) ** 1 0 <a href="URL"> ** 0 1 <a data-href="URL"> ** 1 1 <a href="URL"> ** ** The name of these routines are deliberately kept short so that can be ** easily used within @-lines. Example: ** ** @ %z(href("%R/artifact/%s",zUuid))%h(zFN)</a> ** ** Note %z format. The string returned by this function is always |
︙ | ︙ | |||
1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 | @ g.zBaseURL = %h(g.zBaseURL)<br /> @ g.zHttpsURL = %h(g.zHttpsURL)<br /> @ g.zTop = %h(g.zTop)<br /> @ g.zPath = %h(g.zPath)<br /> @ g.userUid = %d(g.userUid)<br /> @ g.zLogin = %h(g.zLogin)<br /> @ g.isHuman = %d(g.isHuman)<br /> if( g.nRequest ){ @ g.nRequest = %d(g.nRequest)<br /> } if( g.nPendingRequest>1 ){ @ g.nPendingRequest = %d(g.nPendingRequest)<br /> } @ capabilities = %s(find_capabilities(zCap))<br /> | > | 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 | @ g.zBaseURL = %h(g.zBaseURL)<br /> @ g.zHttpsURL = %h(g.zHttpsURL)<br /> @ g.zTop = %h(g.zTop)<br /> @ g.zPath = %h(g.zPath)<br /> @ g.userUid = %d(g.userUid)<br /> @ g.zLogin = %h(g.zLogin)<br /> @ g.isHuman = %d(g.isHuman)<br /> @ g.javascriptHyperlink = %d(g.javascriptHyperlink)<br /> if( g.nRequest ){ @ g.nRequest = %d(g.nRequest)<br /> } if( g.nPendingRequest>1 ){ @ g.nPendingRequest = %d(g.nPendingRequest)<br /> } @ capabilities = %s(find_capabilities(zCap))<br /> |
︙ | ︙ |