Skip to content
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

SHARD-1139: add better security for limit/offset query params #95

Merged
merged 2 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/Data/AccountDataProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,11 @@ export const provideAccountDataRequest = async (
// AND accountId <= "${accountEnd}" AND accountId >= "${accountStart}"
// ORDER BY timestamp, accountId LIMIT ${maxRecords}`

const safeSkip = Number.isInteger(offset) ? offset : 0
const safeLimit = Number.isInteger(maxRecords) ? maxRecords : 100
const sqlPrefix = `SELECT * FROM accounts WHERE `
const queryString = `accountId BETWEEN ? AND ? AND timestamp BETWEEN ? AND ? ORDER BY timestamp ASC, accountId ASC LIMIT ${maxRecords}`
const offsetCondition = ` OFFSET ${offset}`
const queryString = `accountId BETWEEN ? AND ? AND timestamp BETWEEN ? AND ? ORDER BY timestamp ASC, accountId ASC LIMIT ${safeLimit}`
const offsetCondition = ` OFFSET ${safeSkip}`
let sql = sqlPrefix
let values = []
if (accountOffset) {
Expand Down Expand Up @@ -263,6 +265,7 @@ export const provideAccountDataByListRequest = async (
): Promise<WrappedStateArray> => {
const { accountIds } = payload
const wrappedAccounts: WrappedStateArray = []
// todo: does this even work right now?
const sql = `SELECT * FROM accounts WHERE accountId IN (?)`
const accounts = await Account.fetchAccountsBySqlQuery(sql, accountIds)
for (const account of accounts) {
Expand Down
12 changes: 12 additions & 0 deletions src/dbstore/accounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ export async function queryAccountByAccountId(accountId: string): Promise<Accoun
}

export async function queryLatestAccounts(count: number): Promise<AccountsCopy[] | null> {
if (!Number.isInteger(count)) {
Logger.mainLogger.error('queryLatestAccounts - Invalid count value')
return null
}
try {
const sql = `SELECT * FROM accounts ORDER BY cycleNumber DESC, timestamp DESC LIMIT ${
count ? count : 100
Expand All @@ -114,6 +118,10 @@ export async function queryLatestAccounts(count: number): Promise<AccountsCopy[]
export async function queryAccounts(skip = 0, limit = 10000): Promise<AccountsCopy[]> {
let dbAccounts: DbAccountCopy[]
const accounts: AccountsCopy[] = []
if (!Number.isInteger(skip) || !Number.isInteger(limit)) {
Logger.mainLogger.error('queryAccounts - Invalid skip or limit value')
return accounts
}
try {
const sql = `SELECT * FROM accounts ORDER BY cycleNumber ASC, timestamp ASC LIMIT ${limit} OFFSET ${skip}`
dbAccounts = (await db.all(accountDatabase, sql)) as DbAccountCopy[]
Expand Down Expand Up @@ -174,6 +182,10 @@ export async function queryAccountsBetweenCycles(
): Promise<AccountsCopy[]> {
let dbAccounts: DbAccountCopy[]
const accounts: AccountsCopy[] = []
if (!Number.isInteger(skip) || !Number.isInteger(limit)) {
Logger.mainLogger.error('queryAccountsBetweenCycles - Invalid skip or limit value')
return accounts
}
try {
const sql = `SELECT * FROM accounts WHERE cycleNumber BETWEEN ? AND ? ORDER BY cycleNumber ASC, timestamp ASC LIMIT ${limit} OFFSET ${skip}`
dbAccounts = (await db.all(accountDatabase, sql, [startCycleNumber, endCycleNumber])) as DbAccountCopy[]
Expand Down
4 changes: 4 additions & 0 deletions src/dbstore/cycles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ export async function queryCycleByMarker(marker: string): Promise<Cycle> {
}

export async function queryLatestCycleRecords(count: number): Promise<P2P.CycleCreatorTypes.CycleData[]> {
if (!Number.isInteger(count)) {
Logger.mainLogger.error('queryLatestCycleRecords - Invalid count value')
return []
}
try {
const sql = `SELECT * FROM cycles ORDER BY counter DESC LIMIT ${count ? count : 100}`
const dbCycles = (await db.all(cycleDatabase, sql)) as DbCycle[]
Expand Down
8 changes: 8 additions & 0 deletions src/dbstore/originalTxsData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ export async function queryOriginalTxsData(
endCycle?: number
): Promise<OriginalTxData[]> {
let originalTxsData: DbOriginalTxData[] = []
if (!Number.isInteger(skip) || !Number.isInteger(limit)) {
Logger.mainLogger.error('queryOriginalTxsData - Invalid skip or limit')
return originalTxsData
}
try {
let sql = `SELECT * FROM originalTxsData`
const sqlSuffix = ` ORDER BY cycle ASC, timestamp ASC LIMIT ${limit} OFFSET ${skip}`
Expand Down Expand Up @@ -166,6 +170,10 @@ export async function queryOriginalTxDataCountByCycles(
}

export async function queryLatestOriginalTxs(count: number): Promise<OriginalTxData[]> {
if (!Number.isInteger(count)) {
Logger.mainLogger.error('queryLatestOriginalTxs - Invalid count value')
return null
}
try {
const sql = `SELECT * FROM originalTxsData ORDER BY cycle DESC, timestamp DESC LIMIT ${
count ? count : 100
Expand Down
12 changes: 12 additions & 0 deletions src/dbstore/receipts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,10 @@ export async function queryReceiptByReceiptId(receiptId: string, timestamp = 0):
}

export async function queryLatestReceipts(count: number): Promise<Receipt[]> {
if (!Number.isInteger(count)) {
Logger.mainLogger.error('queryLatestReceipts - Invalid count value')
return null
}
try {
const sql = `SELECT * FROM receipts ORDER BY cycle DESC, timestamp DESC LIMIT ${count ? count : 100}`
const receipts = (await db.all(receiptDatabase, sql)) as DbReceipt[]
Expand All @@ -179,6 +183,10 @@ export async function queryLatestReceipts(count: number): Promise<Receipt[]> {

export async function queryReceipts(skip = 0, limit = 10000): Promise<Receipt[]> {
let receipts: Receipt[] = []
if (!Number.isInteger(skip) || !Number.isInteger(limit)) {
Logger.mainLogger.error('queryReceipts - Invalid skip or limit')
return receipts
}
try {
const sql = `SELECT * FROM receipts ORDER BY cycle ASC, timestamp ASC LIMIT ${limit} OFFSET ${skip}`
receipts = (await db.all(receiptDatabase, sql)) as DbReceipt[]
Expand Down Expand Up @@ -261,6 +269,10 @@ export async function queryReceiptsBetweenCycles(
endCycleNumber: number
): Promise<Receipt[]> {
let receipts: Receipt[] = []
if (!Number.isInteger(skip) || !Number.isInteger(limit)) {
Logger.mainLogger.error('queryReceiptsBetweenCycles - Invalid skip or limit')
return receipts
}
try {
const sql = `SELECT * FROM receipts WHERE cycle BETWEEN ? AND ? ORDER BY cycle ASC, timestamp ASC LIMIT ${limit} OFFSET ${skip}`
receipts = (await db.all(receiptDatabase, sql, [startCycleNumber, endCycleNumber])) as DbReceipt[]
Expand Down
12 changes: 12 additions & 0 deletions src/dbstore/transactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ export async function queryTransactionByAccountId(accountId: string): Promise<Tr
}

export async function queryLatestTransactions(count: number): Promise<Transaction[]> {
if (!Number.isInteger(count)) {
Logger.mainLogger.error('queryLatestTransactions - Invalid count value')
return null
}
try {
const sql = `SELECT * FROM transactions ORDER BY cycleNumber DESC, timestamp DESC LIMIT ${
count ? count : 100
Expand All @@ -123,6 +127,10 @@ export async function queryLatestTransactions(count: number): Promise<Transactio

export async function queryTransactions(skip = 0, limit = 10000): Promise<Transaction[]> {
let transactions
if (!Number.isInteger(skip) || !Number.isInteger(limit)) {
Logger.mainLogger.error('queryTransactions - Invalid skip or limit')
return null
}
try {
const sql = `SELECT * FROM transactions ORDER BY cycleNumber ASC, timestamp ASC LIMIT ${limit} OFFSET ${skip}`
transactions = (await db.all(transactionDatabase, sql)) as DbTransaction[] // TODO: confirm structure of object from db
Expand Down Expand Up @@ -189,6 +197,10 @@ export async function queryTransactionsBetweenCycles(
endCycleNumber: number
): Promise<Transaction[]> {
let transactions
if (!Number.isInteger(skip) || !Number.isInteger(limit)) {
Logger.mainLogger.error('queryTransactionsBetweenCycles - Invalid skip or limit value')
return null
}
try {
const sql = `SELECT * FROM transactions WHERE cycleNumber BETWEEN ? AND ? ORDER BY cycleNumber ASC, timestamp ASC LIMIT ${limit} OFFSET ${skip}`
transactions = (await db.all(transactionDatabase, sql, [
Expand Down
Loading