Skip to content
This repository has been archived by the owner on Jul 17, 2021. It is now read-only.
Permalink
Browse files Browse the repository at this point in the history
Change behavior of PUT /verify/{}
* Instead of returning the same code, which someone else could hijack,
  generate a new code on repeated PUT to preserve integrity.
* Update docs to reflect this new behavior
  • Loading branch information
Kenny2github committed Nov 19, 2020
1 parent 2170fc5 commit a603769
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 7 deletions.
11 changes: 6 additions & 5 deletions backend/db.py
Expand Up @@ -162,18 +162,19 @@ async def start_verification(self, client_id, username):
await self.db.execute('SELECT code FROM scratchverifier_usage WHERE \
client_id=? AND username=?', (client_id, username))
row = await self.db.fetchone()
if row is not None:
await self.db.execute('UPDATE scratchverifier_usage SET expiry=? \
WHERE client_id=? AND username=? AND code=?', (int(time.time()) + VERIFY_EXPIRY,
client_id, username, row[0]))
return row[0]
code = sha256(
str(client_id).encode()
+ str(time.time()).encode()
+ username.encode()
+ token_bytes()
# 0->A, 1->B, etc, to avoid Scratch's phone number censor
).hexdigest().translate({ord('0') + i: ord('A') + i for i in range(10)})
if row is not None:
await self.db.execute(
'UPDATE scratchverifier_usage SET expiry=?, code=? \
WHERE client_id=? AND username=?', (int(time.time()) + VERIFY_EXPIRY,
code, client_id, username))
return code
await self.db.execute('INSERT INTO scratchverifier_usage (client_id, \
code, username, expiry) VALUES (?, ?, ?, ?)', (client_id, code, username,
int(time.time() + VERIFY_EXPIRY)))
Expand Down
2 changes: 1 addition & 1 deletion docs/docs.json
Expand Up @@ -59,7 +59,7 @@
{
"type": "endpoint",
"name": "Start/Renew Verification",
"desc": "Request a new verification code for a user. Only one code per user per client - if this endpoint is used again before the <a href=\"#finish-verification-endpoint\">Finish Verification</a> endpoint is used, this will instead renew the 30-minute expiry on the code and return the original code.",
"desc": "Request a new verification code for a user. Only one code per user per client - if this endpoint is used again before the <a href=\"#finish-verification-endpoint\">Finish Verification</a> endpoint is used, this will generate a new code and reset the 30-minute expiry, returning the new code instead.",
"method": "PUT",
"path": "/verify/{username}",
"params": {
Expand Down
2 changes: 1 addition & 1 deletion docs/reference.html
Expand Up @@ -21,7 +21,7 @@ <h2 id="authorization">Authorization</h2>
<h2 id="api-endpoints">API Endpoints</h2>
<p>The simplicity of this API is such that there are only three total endpoints for its ultimate purpose.</p>
<h3 id="start/renew-verification-endpoint">Start/Renew Verification Endpoint</h3>
<p>Request a new verification code for a user. Only one code per user per client - if this endpoint is used again before the <a href="#finish-verification-endpoint">Finish Verification</a> endpoint is used, this will instead renew the 30-minute expiry on the code and return the original code.</p>
<p>Request a new verification code for a user. Only one code per user per client - if this endpoint is used again before the <a href="#finish-verification-endpoint">Finish Verification</a> endpoint is used, this will generate a new code and reset the 30-minute expiry, returning the new code instead.</p>
<div class="endpoint">
<div class="method-path auth-needed" onclick="showOrHide(this)"><span class="method">PUT</span> <code>/verify/<span class="param">{username}</span></code> <a href="#authorization"><img src="https://image.flaticon.com/icons/png/512/61/61457.png" title="Authorization necessary" /></a></div>
<div style="display: none">
Expand Down

0 comments on commit a603769

Please sign in to comment.