-
Notifications
You must be signed in to change notification settings - Fork 18
feat(gs): add debug endpoint for secure database queries #2770
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
TaprootFreak
wants to merge
8
commits into
develop
Choose a base branch
from
feature/debug-endpoint
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
d06a5a8 to
b4b852e
Compare
Yannick1712
approved these changes
Dec 31, 2025
Member
|
fc86ace to
6495c2d
Compare
Add new DEBUG user role for developer database access with POST /gs/debug endpoint for executing read-only SQL queries. Security layers: - Role-based access (DEBUG/ADMIN/SUPER_ADMIN only) - SQL parsing with node-sql-parser (AST validation) - Only single SELECT statements allowed - Blocked: UNION/INTERSECT/EXCEPT, SELECT INTO, FOR XML/JSON - Blocked: OPENROWSET, OPENQUERY, OPENDATASOURCE (external connections) - Pre-execution column checking (blocks alias bypass) - Input validation with MaxLength(10000) - Post-execution PII column masking (defense in depth) - Full audit trail with user identification Blocked columns: mail, email, firstname, surname, iban, ip, apiKey, etc.
6495c2d to
1b1b934
Compare
- Remove unused catch variable (use bare catch) - Remove unnecessary eslint-disable directive
- Remove organization.name, bank_tx.name, kyc_step.result from RestrictedColumns - Add 'name' and 'result' to DebugBlockedColumns - ADMIN can now see these columns on /gs/db - DEBUG role has these blocked on /gs/debug
5 tasks
…2782) * fix(gs): implement table-specific column blocking for debug endpoint Replace generic DebugBlockedColumns list with table-specific blocking: - TableBlockedColumns: Record<string, string[]> maps each table to its blocked columns - Pre-execution: Check columns against their specific tables - Post-execution for SELECT *: Mask columns from all query tables Examples: - SELECT name FROM asset → ALLOWED (asset has no blocked columns) - SELECT name FROM bank_tx → BLOCKED (bank_tx.name contains personal data) - SELECT * FROM bank_tx → name masked post-execution Tables with blocked columns: - user_data: mail, phone, firstname, surname, etc. - bank_tx: name, iban, addressLine1, etc. - bank_data: name, iban, label, comment - kyc_step: result (contains names, birthday) - organization: name, allBeneficialOwnersName, etc. * fix(gs): always run post-execution masking for defense in depth The previous implementation only masked post-execution for SELECT * queries. This was a security risk: if pre-execution column extraction failed (catch block), non-wildcard queries would not be masked. Now post-execution masking always runs, ensuring blocked columns are masked even if the SQL parser fails to detect them pre-execution. * fix(gs): add missing blocked columns from original list Add columns that were in the original DebugBlockedColumns but missing in the new table-specific structure: - user_data: countryId, verifiedCountryId, nationalityId - user: signature - fiat_output: accountNumber - checkout_tx: cardName (new table) - bank_account: accountNumber (new table) * fix(gs): add missing tables with sensitive columns Add tables that were missed when converting from global DebugBlockedColumns to table-specific TableBlockedColumns: - ref: ip (user IP for referral tracking) - ip_log: ip, country (user IP logging) - checkout_tx: ip (user IP during checkout, cardName already present) - buy: iban (user IBAN for buy routes) - deposit_route: iban (user IBAN for sell routes via Single Table Inheritance) These columns were blocked globally in the original implementation but were not added to all relevant tables in the table-specific version. * fix(gs): add additional sensitive columns found in codebase review Add missing blocked columns discovered during comprehensive entity scan: - buy_crypto: chargebackIban (user IBAN for refunds) - kyc_log: ipAddress (TfaLog), result (KYC data) - bank_tx_return: chargebackIban, recipientMail, chargebackRemittanceInfo - bank_tx_repeat: chargebackIban, chargebackRemittanceInfo - limit_request: recipientMail - ref_reward: recipientMail * fix(gs): add additional sensitive columns from codebase review Extend existing tables with missing blocked columns: - checkout_tx: cardBin, cardLast4, cardFingerPrint, cardIssuer, cardIssuerCountry, raw - buy_crypto: chargebackRemittanceInfo, siftResponse - buy_fiat: remittanceInfo, usedBank, info - crypto_input: senderAddresses - user_data: relatedUsers - limit_request: fundOriginText - bank_tx_return: info Add new tables with sensitive columns: - transaction_risk_assessment: reason, methods, summary, result (AML/KYC assessments) - support_issue: name, information (support tickets with user data) - support_message: message, fileUrl (message content and files) - sift_error_log: requestPayload (Sift API requests with PII) * fix(gs): add webhook.data to blocked columns * fix(gs): add notification.data to blocked columns * fix(gs): add kyc_step.data to blocked columns
…urity (#2778) Add POST /gs/debug/logs endpoint for querying Azure Application Insights logs using predefined, safe KQL templates. Security features: - Template-based queries only (no free-form KQL input) - Strict parameter validation via class-validator (GUID, alphanumeric) - All KQL-relevant special characters blocked in user input - Defense-in-depth string escaping - Result limits per template (200-500 rows) - Full audit logging of queries Available templates: - traces-by-operation: Traces for specific operation ID - traces-by-message: Traces filtered by message pattern - exceptions-recent: Recent exceptions - request-failures: Failed HTTP requests - dependencies-slow: Slow external dependencies (by duration threshold) - custom-events: Custom events by name Infrastructure: - AppInsightsQueryService: OAuth2 client with token caching - Proper error handling and logging - Mock responses for LOC mode Requires UserRole.DEBUG and APPINSIGHTS_APP_ID env variable.
Security improvements: 1. Block system tables and schemas: - Added BlockedSchemas list: sys, information_schema, master, msdb, tempdb - checkForBlockedSchemas() validates FROM clause and subqueries - Prevents access to sys.sql_logins, INFORMATION_SCHEMA.TABLES, etc. 2. Fix TOP validation to use AST instead of regex: - Previous regex /\btop\s+(\d+)/ missed TOP(n) with parentheses - Now uses stmt.top?.value from AST for accurate detection - Both TOP 100 and TOP(100) are correctly validated 3. Extend dangerous function check to all clauses: - Previous check only validated FROM clause - Now recursively checks SELECT columns and WHERE clauses - checkForDangerousFunctionsRecursive() traverses entire AST - Blocks OPENROWSET, OPENQUERY, OPENDATASOURCE, OPENXML everywhere
- Remove commented debug code - Fix return type any[] → Record<string, unknown>[] - Remove redundant try-catch in controller (service handles errors) - Rename misleading parameter userMail → userIdentifier - Standardize comment style
Collaborator
Author
✅ Ready to Merge - Security Review CompleteThis PR has undergone comprehensive security review and is production-ready. Security Implementation (12 Validation Layers)SQL Debug Endpoint (
App Insights Log Query (
Access Control
Code Quality
All identified security issues have been addressed. The defense-in-depth approach ensures multiple layers of protection against SQL injection, data exfiltration, and unauthorized access. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
POST /gs/debugendpoint for secure read-only SQL queriesPOST /gs/debug/logsendpoint for Azure App Insights log queriesEndpoints
POST /gs/debug - SQL Query
Execute read-only SQL queries against the database with automatic PII filtering.
POST /gs/debug/logs - Log Query
Query Azure App Insights logs using predefined KQL templates.
Security Layers (SQL Endpoint)
KQL Templates (Log Endpoint)
traces-by-operation- Traces by operation IDtraces-by-message- Traces by message filterexceptions-recent- Recent exceptionsrequest-failures- Failed requestsdependencies-slow- Slow dependenciescustom-events- Custom events by nameAccess Control