add slack bot - #122
add slack bot#122amyliiu wants to merge 7 commits into
Conversation
…oard data. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
hujalex
left a comment
There was a problem hiding this comment.
Automated code review (medium effort). 10 findings, most severe first. Verified as non-issues: signature verification (constant-time, length-checked, 5-minute skew), the intentional /api/slack middleware bypass, SET LOCAL transaction_read_only = on after a prior SET, the ai/@ai-sdk/openai lockfile resolution, and the hasSeenEvent LRU eviction.
… trust, and event handling. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
|
Wait, looks good to me, only thing is wondering if the keys are in the prod environment |
There was a problem hiding this comment.
fragile to schema updates. can this be a simple query for schema instead
There was a problem hiding this comment.
this isn't safe. can we do something tighter like a read only posgres role that the orm temp assumes?
There was a problem hiding this comment.
is there a slack sdk or something. this feels a bit brute.
Co-authored-by: Cursor <cursoragent@cursor.com>
pradhamk
left a comment
There was a problem hiding this comment.
- Please use Slack SDK for typescript so the bot can be reusable in the future and is resilient against api changes from slack
- Query the general schema of each table in schema-prompt.ts rather than defining each table manually (this will break easily if we make a table change during the hackathon). Instead, just whitelist the columns that the bot can read maybe? (we will never remove columns, only add during the event)
- Unsafe transactions are a big no-no in sql.ts. Should be able to use safe transactions here and be fine since we are only doing reads.
Security Issues:
- SQL allowlist bypass via derived-table subquery — lib/slack/sql.ts:341
- Severity: High
- Category: authorization_bypass / sql_scope_bypass
- Confidence: 9/10
Description: validateReadonlySelect() is the only thing constraining LLM-authored SQL before it is executed with tx.unsafe() on the application's privileged Postgres connection (lib/slack/sql.ts:447-451, pool from lib/db/index.ts:17). Its table allowlist is applied by extractTableNames(), which scans for from/join word tokens — but when a from/join is immediately followed by (, it calls skipParens() and advances the loop index past the closing parenthesis (lib/slack/sql.ts:341-348). Every token inside a derived table is therefore never examined: neither ALLOWED_TABLES (lib/slack/sql.ts:124-129) nor the public-only schema check in parseQualifiedName() (lib/slack/sql.ts:380-382) is reached. SELECT * FROM (SELECT * FROM auth.users) AS q passes validation. The same applies to JOIN (…) and to nesting inside CTE bodies. Note the non-derived forms are caught — SELECT (SELECT count(*) FROM auth.users) FROM users correctly throws — so the control looks like it works while being inert for the most natural subquery shape.
- SQL allowlist bypass via query-taking XML built-ins — lib/slack/sql.ts:48
- Severity: High
- Category: authorization_bypass / sql_scope_bypass
- Confidence: 9/10
Description: tokenizeSql() reduces every string literal to a contentless { type: "string" } token with no value field (lib/slack/sql.ts:226; same for dollar-quoted strings at lib/slack/sql.ts:174-184), so nothing inside a literal is ever inspected. Postgres ships built-ins that take a SQL string or a regclass and execute it under the caller's privileges, and FORBIDDEN_FUNCS (lib/slack/sql.ts:48-56) does not list any of them. SELECT query_to_xml('SELECT * FROM auth.users', true, false, '') contains no from/join token outside the literal, so extractTableNames() returns [] and the allowlist loop never executes at all. checkForbidden() sees only select, query_to_xml, true, false. The outer wrapper SELECT * FROM () AS q LIMIT 25 is valid around a FROM-less select, and is appended after validation so it cannot re-trigger the scanner.
…list holes. Co-authored-by: Cursor <cursoragent@cursor.com>
|
@pradhamk addressed in ac40d83:
Security: |
/api/slack/events) so organizers can @mention a bot and ask natural-language questions about dashboard Postgres (read-only SQL via Drizzle).usersrow with roleorganizer; skip session auth for/api/slack.task-definition.json) and document app setup, env vars, and local tunneling indocs/slack.md.