forked from bati-itao/example
-
Notifications
You must be signed in to change notification settings - Fork 0
/
captcha-accessible-en.html
198 lines (191 loc) · 9.97 KB
/
captcha-accessible-en.html
1
2
3
4
5
6
7
8
9
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
<!DOCTYPE html>
<!--[if lt IE 9]><html class="no-js lt-ie9" lang="en" dir="ltr"><![endif]-->
<!--[if gt IE 8]><!-->
<html class="no-js" lang="en" dir="ltr">
<!--<![endif]-->
<head>
<meta charset="utf-8">
<!-- Web Experience Toolkit (WET) / Boîte à outils de l'expérience Web (BOEW) wet-boew.github.io/wet-boew/License-en.html / wet-boew.github.io/wet-boew/Licence-fr.html -->
<title>Are CAPTCHAs accessible? - ESDC / IT Accessibility office</title>
<meta content="width=device-width,initial-scale=1" name="viewport">
<!-- Meta data -->
<meta name="description"
content="IT Accessibility Office provides adaptive technology and advocate for inclusiveness of people with disabilities in the workplace.">
<!-- Meta data-->
<!-- Load closure template scripts -->
<script src="https://ssl-templates.services.gc.ca/rn/cls/wet/gcweb/cdts/compiled/soyutils.js"></script>
<script src="https://ssl-templates.services.gc.ca/rn/cls/wet/gcweb/cdts/compiled/wet-en.js"></script>
<!-- Write closure template -->
<script src="https://bati-itao.github.io/scripts/refTop.min.js"></script>
</head>
<body vocab="https://schema.org/" typeof="WebPage">
<div id="def-top">
</div>
<!-- Write closure template -->
<script>
var defTop = document.getElementById("def-top");
defTop.outerHTML = wet.builder.appTop({
"appName": [{
"text": "ESDC / IT Accessibility office",
"href": "https://bati-itao.github.io/index-en.html"
}],
"breadcrumbs": [{
"title": "Home",
"href": "https://bati-itao.github.io/index-en.html"
}],
"lngLinks": [{
"lang": "fr",
"href": "./index-fr.html",
"text": "Français"
}],
"menuPath": "https://bati-itao.github.io/ajax/menu-en.html"
});
</script>
<main role="main" property="mainContentOfPage" class="container">
<h1 property="name" id="wb-cont">Are CAPTCHAs accessible?</h1>
<p>Why are the usual strategies used online not accessible and not an option for us? The following CAPTCHA’s are
typically used to prevent BOT attacks but are not accessible or fully compliant, and/or have other
identified challenges.</p>
<h2>CAPTCHAs</h2>
<h3>Image based CAPTCHA’s</h3>
<p>Not accessible as visually impaired people cannot see the images and input the requested information.</p>
<h3>Audio CAPTCHA</h3>
<p>This will work with the screen readers, as the user can “hear” the word(s), but it can be exploited by smart
and presents the same problem as Image Based CAPTCHA’s for the visually impaired. Here is an <a href="https://gbhackers.com/security-researcher-breaks-googles-recaptcha-v2-using-googles-tool/">audio CAPTCHA</a> that covers it in details.</p>
<h3>reCAPTCHA</h3>
<p>Uses digitized words but presents the same problem as Image Based CAPTCHA’s for the visually impaired.</p>
<h2>Alternative methods</h2>
<p>In addition to the above mentioned CAPTCHA’s. the following are also used to prevent attacks.</p>
<h3>Common names are not used for attributes</h3>
<p>When bots crawl, they typically look for common field names like email address, name etc. This information
can be made obscure as a way to deter bots but it would be confusing for our legitimate end users. This
option is accessible, but not user friendly.</p>
<h3>Hidden input fields</h3>
<p>A field that is not required for business can be hidden using Cascading Style Sheets (CSS). A BOT would
typically complete this hidden field and upon Submit, we can check if that field has data and if it does we
simply reject submission. This option is accessible, but can be hacked.</p>
<h3>Random question</h3>
<p>Random questions can be asked based on “other” input from the user. For example: What is the second and
seventh digit of your phone number. This option is accessible, but can be hacked and there is a significant
level of effort required to implement this option.</p>
<h3>Email address field/confirmation process</h3>
<p>Capturing an email address and implementing an email confirmation process protects against BOT attacks
because an email which contains a unique confirmation link is sent to the user immediately after form
submission. Successful confirmation via this link verifies the authenticity of the user and persists the
data. If the subscription is not confirmed, within a period of time as identified by the business, the data
is discarded. This ensures that the data committed to the database is from actual users and not BOT
submissions, which in-turn ensures the integrity and accuracy of the data.</p>
<h2>Additional information</h2>
<p>To further secure the form data, it is recommended that the following additional functionality be
implemented as further security.</p>
<h4>Hidden input fields</h4>
<p>Although as mentioned above, on its own this option is not completely secure but when used with the email
address/confirmation process it adds an additional layer to protect data and is not difficult to implement.
To ensure accessibility and compliance, this field will be hidden visually and from screen readers, and the
input value of this field will be checked before accepting submission of data.</p>
<h2>Recommendation</h2>
<p>Implementation of the following methods for the web form are recommended to optimize user
experience and accessibility, as well as ensure data integrity and accuracy:</p>
<ul>
<li>Include a required email address field/confirmation process and persist data only upon successful
confirmation.</li>
<li>Enable hidden field validation on form submission.</li>
</ul>
<p>If you wish to know more information about CAPTCHAs and alternative methods to prevent BOT attacks we encourage you to visit the <a href="https://www.w3.org/WAI/GL/wiki/Captcha_Alternatives_and_thoughts">Captcha Alternative and thoughts</a> page on the W3C website.</p>
<section>
<h2>Honeypot technique</h2>
<section>
<h3>Preamble</h3>
<p>How the honeypot technique should work:</p>
<ul>
<li>Expose a form field to a bot, but not a human.</li>
<li>The field should have a programmatically determinable purpose (such as through the use of a <code>label</code> element that's associated to the <code>input</code> so a bot can figure out what's being asked.</li>
<li>That field should be something that the form <em>could</em> be asking for, but isn't, such as a birthdate, or a secondary phone number.</li>
<li>A bot should have as much evidence as possible that the field should be filled in, like even adding "<code>required</code>" to the <code>label</code> text, and <strong>not</strong> embedding a class name like "<code>hidden</code>" or having <code>style="display:none;"</code>.</li>
<li>Add <code>required</code> attributes to the <code><input></code>, then get the browser to ignore it: either remove with JavaScript just before form submission or use the <code>novalidate</code> attribute on the <code><form></code> element.</li>
<li>In order for humans to avoid filling it in:
<ul>
<li>It should be hidden visually (like using <code>class="sr-only"</code>, <code>class="wb-inv"</code>)</li>
<li>It should be removed form the tab order using <code>tabindex="-1"</code></li>
<li>They should be hidden from screen readers using JavaScript to apply <code>aria-hidden="true"</code> on an ancestor element of the <code>input</code> and <code>label</code></li></ul></li>
<li>If, after submitting, the server detects a value in that form field, it should ignore the form submission.</li>
</ul>
</section>
<section>
<h3>Code Example</h3>
<p>The following code is the bare minimum needed for this to work. This is a website registration form that requires a username, a password (to be entered twice), and an email address. The Birthday field is a honeypot field.</p>
<h4>HTML</h4>
<code><pre>
<form id="regForm" action="registrationPage" method="POST" novalidate>
<div>
<label for="username"></label>
<input id="username" name="username" aria-describedby="formatforusername" required>
</div>
<div>
<label for="password"></label>
<input id="password" name="password" required type="password">
</div>
<div>
<label for="repassword"></label>
<input id="repassword" name="repassword" required type="password">
</div>
<div>
<label for="email"></label>
<input id="email" name="email" required type="email">
</div>
<div>
<label for="birthday" class="invisibleStuff"></label>
<input id="birthday" name="birthday" class="hpclass" required>
</div>
<div>
<input id="saveBtn" name="saveBtn" value="Register" type="submit">
</div>
</form>
<script src="user.js"></pre>
</code>
<h4>CSS</h4>
<code><pre>
.invisibleStuff {
position: absolute;
height: 1px;
width: 1px;
clip: rect(1px, 1px, 1px, 1px);
overflow: hidden;
margin: 0;
}
.hpclass {
z-index: -5;
font-size: 0pt;
position: relative;
top: -5em;
height: 0px;
overflow: hidden;
width: 0;
line-height: 0px;
margin: 0;
padding: 0;
}
</pre></code>
<h4>Javascript</h4>
<code><pre>
function hp () {
let hps = document.querySelectorAll("input.hpclass");
window["wb-frmvld"] = {"ignore" : "input.hpclass"}; // This line is only necessary if the page uses WET validation
for (let i = 0; i < hps.length; i++) {
hps[i].setAttribute("tabindex", "-1");
hps[i].classList.add("invisibleStuff");
hps[i].parentNode.setAttribute("aria-hidden", "true");
}
}
document.addEventListener("DOMContentLoaded", hp, false);
</pre></code>
</section>
<div id="def-preFooter"></div>
<script src="https://bati-itao.github.io/scripts/preFooter.min.js"></script>
</main>
<div id="def-footer"></div>
<script src="https://bati-itao.github.io/scripts/appFooter.min.js"></script>
<script src="https://bati-itao.github.io/scripts/refFooter.min.js"></script>
<script src="https://bati-itao.github.io/scripts/bati-itao.min.js"></script>
</body>
</html>