trying to take values from a user's input, known as the symbols
parameter in my def tickers()
function, and feed it into my SQL query as a filter. Right now it's vulnerable to injections:
@app.callback(
dash.dependencies.Output('output-graph', 'figure'),
[dash.dependencies.Input('dynamic-dropdown', 'value')])
def tickers(symbols):
conn.rollback()
if symbols == None:
raise PreventUpdate
elif symbols == '':
raise PreventUpdate
trace1 = [] #lines for stocks
d = {} #dates
p = {} #prices
stock_info = {}
for stock in symbols:
stock_info[stock] = get_dict_resultset(f"SELECT date, close FROM security_price WHERE security_price.id = '{stock}' ;")
d[stock] = [rec['date'] for rec in stock_info[stock]]
p[stock] = [rec['close'] for rec in stock_info[stock]]
trace1.append(go.Scatter(x=d[stock],
y=p[stock],
mode='lines',
opacity=0.7,
name=stock,
textposition='bottom center'))
I have sanitized my f-strings using the placeholder format. I couldn't get it to work using the format above.
For example, this works great:
def statsTable(symbols):
conn.rollback()
if symbols == None:
conn.rollback()
raise PreventUpdate
placeholders = ", ".join(['%s' for _ in symbols])
# PREPARED STATEMENT WITH PARAM PLACEHOLDERS
sql = f"""SELECT id, cast(marketcap as money), cast(week52high as money), cast(week52low as money)
, to_char(dividend_yield * 100, '99D99%%')
, pe_ratio, ROUND(beta,2)
FROM security_stats
WHERE security_stats.id IN ({placeholders})
"""
Going back to the original, first code block, above. I tried adding %s
as a placeholder to sanitize the same way I did before, but it does not work.
@app.callback(
dash.dependencies.Output('output-graph', 'figure'),
[dash.dependencies.Input('dynamic-dropdown', 'value')])
def tickers(symbols):
conn.rollback()
if symbols == None:
raise PreventUpdate
elif symbols == '':
raise PreventUpdate
placeholders = ", ".join(['%s' for _ in symbols])
trace1 = [] #lines for stocks
d = {} #dates
p = {} #prices
stock_info = {}
for stock in placeholders:
stock_info[stock] = get_dict_resultset(f"SELECT date, close FROM security_price WHERE security_price.id = '{stock}' ;")
d[stock] = [rec['date'] for rec in stock_info[stock]]
p[stock] = [rec['close'] for rec in stock_info[stock]]
trace1.append(go.Scatter(x=d[stock],
y=p[stock],
mode='lines',
opacity=0.7,
name=stock,
textposition='bottom center'))
I'm trying to pull up and find the error code, but it's not coming up. I will update this post when I can.