The KeyCache class in scitokens was vulnerable to SQL Injection because it used Python's str.format() to construct SQL queries with user-supplied data (such as issuer and key_id). This allowed an attacker to execute arbitrary SQL commands against the local SQLite database.
Ran the POC below locally.
File: src/scitokens/utils/keycache.py
1. In addkeyinfo (around line 74):
curs.execute("DELETE FROM keycache WHERE issuer = '{}' AND key_id = '{}'".format(issuer, key_id))
2. In _addkeyinfo (around lines 89 and 94):
insert_key_statement = "INSERT OR REPLACE INTO keycache VALUES('{issuer}', '{expiration}', '{key_id}', \
'{keydata}', '{next_update}')"
# ...
curs.execute(insert_key_statement.format(issuer=issuer, expiration=time.time()+cache_timer, key_id=key_id,
keydata=json.dumps(keydata), next_update=time.time()+next_update))
3. In _delete_cache_entry (around line 128):
curs.execute("DELETE FROM keycache WHERE issuer = '{}' AND key_id = '{}'".format(issuer,
key_id))
4. In _add_negative_cache_entry (around lines 148 and 152):
insert_key_statement = "INSERT OR REPLACE INTO keycache VALUES('{issuer}', '{expiration}', '{key_id}', \
'{keydata}', '{next_update}')"
# ...
curs.execute(insert_key_statement.format(issuer=issuer, expiration=time.time()+cache_retry_interval, key_id=key_id,
keydata=keydata, next_update=time.time()+cache_retry_interval))
5. In getkeyinfo (around lines 193 and 198):
key_query = ("SELECT * FROM keycache WHERE "
"issuer = '{issuer}'")
# ...
curs.execute(key_query.format(issuer=issuer, key_id=key_id))
import sqlite3
import os
import sys
import tempfile
import shutil
import time
import json
from...
1.9.6Exploitability
AV:NAC:LPR:NUI:NScope
S:UImpact
C:HI:HA:H9.8/CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H