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

Add another pattern in asyncpg-sqli ruleset #3022

Merged
merged 1 commit into from
Aug 2, 2023

Conversation

kholia
Copy link
Contributor

@kholia kholia commented Aug 2, 2023

This PR adds another pattern in asyncpg-sqli ruleset to catch more bad code patterns.

Before this PR

┌─────────────────┐
│ 9 Code Findings │
└─────────────────┘
                                   
    asyncpg-sqli.py 
       asyncpg-sqli                                                                         
          Detected string concatenation with a non-literal variable in a asyncpg Python SQL statement.
          This could lead to SQL injection if the variable is user-controlled and not properly        
          sanitized. In order to prevent SQL injection, use parameterized queries or prepared         
          statements instead. You can create parameterized queries like so: 'conn.fetch("SELECT $1    
          FROM table", value)'. You can also create prepared statements with 'Connection.prepare':    
          'stmt = conn.prepare("SELECT $1 FROM table"); await stmt.fetch(user_value)'                 
                                                                                                      
           10┆ values = await conn.fetch(query)
            ⋮┆----------------------------------------
           17┆ cur = await conn.cursor(sql_query)
            ⋮┆----------------------------------------
           23┆ await connection.execute(sql_query)
            ⋮┆----------------------------------------
           30┆ await pool.fetch(sql_query)
            ⋮┆----------------------------------------
           37┆ await con.execute("SELECT name FROM users WHERE age=" + req.FormValue("age"))
            ⋮┆----------------------------------------
           44┆ await con.execute('SELECT * FROM {}'.format(user_input))
            ⋮┆----------------------------------------
           50┆ conn.execute('SELECT * FROM %s'%(user_input))
            ⋮┆----------------------------------------
           54┆ conn.fetchrow(f'SELECT * FROM {user_input}')
            ⋮┆----------------------------------------
           58┆ conn.execute(
           59┆ "insert into %s values (%%s, %%s)" % ext.quote_ident(table_name),[10, 20])

It does NOT detect the following SQLi problem (aka a false negative):

def bad10(conn: asyncpg.Connection):
    async with conn.transaction():
        sql_query = 'SELECT * FROM {}'.format(user_input)
        # ruleid: asyncpg-sqli
        cur = await conn.cursor(sql_query)

After this PR

┌──────────────────┐
│ 10 Code Findings │
└──────────────────┘
                                   
    asyncpg-sqli.py 
       asyncpg-sqli                                                                         
          Detected string concatenation with a non-literal variable in a asyncpg Python SQL statement.
          This could lead to SQL injection if the variable is user-controlled and not properly        
          sanitized. In order to prevent SQL injection, use parameterized queries or prepared         
          statements instead. You can create parameterized queries like so: 'conn.fetch("SELECT $1    
          FROM table", value)'. You can also create prepared statements with 'Connection.prepare':    
          'stmt = conn.prepare("SELECT $1 FROM table"); await stmt.fetch(user_value)'                 
                                                                                                      
           10┆ values = await conn.fetch(query)
            ⋮┆----------------------------------------
           17┆ cur = await conn.cursor(sql_query)
            ⋮┆----------------------------------------
           23┆ await connection.execute(sql_query)
            ⋮┆----------------------------------------
           30┆ await pool.fetch(sql_query)
            ⋮┆----------------------------------------
           37┆ await con.execute("SELECT name FROM users WHERE age=" + req.FormValue("age"))
            ⋮┆----------------------------------------
           44┆ await con.execute('SELECT * FROM {}'.format(user_input))
            ⋮┆----------------------------------------
           50┆ conn.execute('SELECT * FROM %s'%(user_input))
            ⋮┆----------------------------------------
           54┆ conn.fetchrow(f'SELECT * FROM {user_input}')
            ⋮┆----------------------------------------
           58┆ conn.execute(
           59┆ "insert into %s values (%%s, %%s)" % ext.quote_ident(table_name),[10, 20])
            ⋮┆----------------------------------------
           65┆ cur = await conn.cursor(sql_query)

@CLAassistant
Copy link

CLAassistant commented Aug 2, 2023

CLA assistant check
All committers have signed the CLA.

@kurt-r2c kurt-r2c merged commit 6dd1d54 into semgrep:develop Aug 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants