Skip to content

test circle ci #76

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
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
55 changes: 0 additions & 55 deletions .github/workflows/docker-build.yml

This file was deleted.

39 changes: 0 additions & 39 deletions .github/workflows/linters.yaml

This file was deleted.

21 changes: 0 additions & 21 deletions .github/workflows/security.yml

This file was deleted.

32 changes: 0 additions & 32 deletions .github/workflows/staging-cd.yml

This file was deleted.

2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

A temporary frontend for new api functions, before we can redo them in react.

We also have circle-ci tests now

# deployment

```
Expand Down
67 changes: 67 additions & 0 deletions app2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from flask import Flask, request, jsonify, Response
import sqlite3

app = Flask(__name__)

# Database file
DATABASE = 'app.db'

def get_db_connection():
conn = sqlite3.connect(DATABASE)
return conn

def init_db():
# Create table and insert data
conn = get_db_connection()
cursor = conn.cursor()
# Check if table already exists to prevent overwriting
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='users';")
if cursor.fetchone() is None:
cursor.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER);')
cursor.execute("INSERT INTO users (name, age) VALUES ('Alice', 30), ('Bob', 25), ('Charlie', 35);")
conn.commit()
conn.close()
Comment on lines +13 to +23
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling to the database initialization function.

The init_db() function lacks try-except blocks to properly handle database errors, and the connection isn't properly closed in case of exceptions.

def init_db():
-    # Create table and insert data
-    conn = get_db_connection()
-    cursor = conn.cursor()
-    # Check if table already exists to prevent overwriting
-    cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='users';")
-    if cursor.fetchone() is None:
-        cursor.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER);')
-        cursor.execute("INSERT INTO users (name, age) VALUES ('Alice', 30), ('Bob', 25), ('Charlie', 35);")
-        conn.commit()
-    conn.close()
+    conn = None
+    try:
+        # Create table and insert data
+        conn = get_db_connection()
+        cursor = conn.cursor()
+        # Check if table already exists to prevent overwriting
+        cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='users';")
+        if cursor.fetchone() is None:
+            cursor.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER);')
+            # Use parameterized queries for data insertion
+            users = [('Alice', 30), ('Bob', 25), ('Charlie', 35)]
+            cursor.executemany("INSERT INTO users (name, age) VALUES (?, ?);", users)
+            conn.commit()
+    except sqlite3.Error as e:
+        print(f"Database initialization error: {e}")
+        if conn:
+            conn.rollback()
+    finally:
+        if conn:
+            conn.close()
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def init_db():
# Create table and insert data
conn = get_db_connection()
cursor = conn.cursor()
# Check if table already exists to prevent overwriting
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='users';")
if cursor.fetchone() is None:
cursor.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER);')
cursor.execute("INSERT INTO users (name, age) VALUES ('Alice', 30), ('Bob', 25), ('Charlie', 35);")
conn.commit()
conn.close()
def init_db():
conn = None
try:
# Create table and insert data
conn = get_db_connection()
cursor = conn.cursor()
# Check if table already exists to prevent overwriting
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='users';")
if cursor.fetchone() is None:
cursor.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER);')
# Use parameterized queries for data insertion
users = [('Alice', 30), ('Bob', 25), ('Charlie', 35)]
cursor.executemany("INSERT INTO users (name, age) VALUES (?, ?);", users)
conn.commit()
except sqlite3.Error as e:
print(f"Database initialization error: {e}")
if conn:
conn.rollback()
finally:
if conn:
conn.close()


@app.route('/users', methods=['GET'])
def get_user():
name = request.args.get('name')
conn = get_db_connection()
cursor = conn.cursor()

# Vulnerable SQL Query from raw string concatenation
query = f"SELECT * FROM users WHERE name = '{name}'"
cursor.execute(query)

Comment on lines +31 to +34
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix SQL injection vulnerability by switching to parameterized queries.
Replacing raw string concatenation with parameterization is essential for secure code.

Here is a proposed fix:

-    query = f"SELECT * FROM users WHERE name = '{name}'"
-    cursor.execute(query)
+    query = "SELECT * FROM users WHERE name = ?"
+    cursor.execute(query, (name,))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Vulnerable SQL Query from raw string concatenation
query = f"SELECT * FROM users WHERE name = '{name}'"
cursor.execute(query)
# Vulnerable SQL Query from raw string concatenation
query = "SELECT * FROM users WHERE name = ?"
cursor.execute(query, (name,))

# # Fixed SQL Query using parameterized queries
# query = "SELECT * FROM users WHERE name = ?"
# cursor.execute(query, (name,))

user = cursor.fetchone()
conn.close()
if user:
return jsonify({"id": user[0], "name": user[1], "age": user[2]})
else:
return jsonify({"error": "User not found"}), 404
Comment on lines +25 to +44
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add input validation and error handling to the user endpoint.

The endpoint is missing input validation for the name parameter and proper error handling for database operations.

@app.route('/users', methods=['GET'])
def get_user():
    name = request.args.get('name')
+    if not name:
+        return jsonify({"error": "Name parameter is required"}), 400
+    
+    conn = None
+    try:
-    conn = get_db_connection()
-    cursor = conn.cursor()
+        conn = get_db_connection()
+        cursor = conn.cursor()

-    # Vulnerable SQL Query from raw string concatenation
-    query = f"SELECT * FROM users WHERE name = '{name}'"
-    cursor.execute(query)
+        # Use parameterized query for security
+        query = "SELECT * FROM users WHERE name = ?"
+        cursor.execute(query, (name,))
-    # # Fixed SQL Query using parameterized queries
-    # query = "SELECT * FROM users WHERE name = ?"
-    # cursor.execute(query, (name,))
    
-    user = cursor.fetchone()
-    conn.close()
-    if user:
-        return jsonify({"id": user[0], "name": user[1], "age": user[2]})
-    else:
-        return jsonify({"error": "User not found"}), 404
+        user = cursor.fetchone()
+        if user:
+            return jsonify({"id": user[0], "name": user[1], "age": user[2]})
+        else:
+            return jsonify({"error": "User not found"}), 404
+    except sqlite3.Error as e:
+        app.logger.error(f"Database error in get_user: {e}")
+        return jsonify({"error": "Database error occurred"}), 500
+    finally:
+        if conn:
+            conn.close()
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@app.route('/users', methods=['GET'])
def get_user():
name = request.args.get('name')
conn = get_db_connection()
cursor = conn.cursor()
# Vulnerable SQL Query from raw string concatenation
query = f"SELECT * FROM users WHERE name = '{name}'"
cursor.execute(query)
# # Fixed SQL Query using parameterized queries
# query = "SELECT * FROM users WHERE name = ?"
# cursor.execute(query, (name,))
user = cursor.fetchone()
conn.close()
if user:
return jsonify({"id": user[0], "name": user[1], "age": user[2]})
else:
return jsonify({"error": "User not found"}), 404
@app.route('/users', methods=['GET'])
def get_user():
name = request.args.get('name')
if not name:
return jsonify({"error": "Name parameter is required"}), 400
conn = None
try:
conn = get_db_connection()
cursor = conn.cursor()
# Use parameterized query for security
query = "SELECT * FROM users WHERE name = ?"
cursor.execute(query, (name,))
user = cursor.fetchone()
if user:
return jsonify({"id": user[0], "name": user[1], "age": user[2]})
else:
return jsonify({"error": "User not found"}), 404
except sqlite3.Error as e:
app.logger.error(f"Database error in get_user: {e}")
return jsonify({"error": "Database error occurred"}), 500
finally:
if conn:
conn.close()


@app.route('/.env', methods=['GET'])
def get_env():
env_content = """
DB_NAME=crapi
DB_USER=crapi
DB_PASSWORD=crapi
DB_HOST=postgresdb
DB_PORT=5432
SERVER_PORT=8080
MONGO_DB_HOST=mongodb
MONGO_DB_PORT=27017
MONGO_DB_USER=crapi
MONGO_DB_PASSWORD=crapi
MONGO_DB_NAME=crapi
"""
return Response(env_content, headers={
"Content-Disposition": "attachment; filename=env"
})
Comment on lines +46 to +63
Copy link

@alexcrtestapp alexcrtestapp bot Mar 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Avoid exposing sensitive environment credentials in plain text.
Serving environment variables as a downloadable file is risky; it can lead to potential data breaches and unauthorized access. Restrict this route to authorized users or remove it entirely from production.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexcrtestapp create an issue to follow up on this


if __name__ == '__main__':
init_db() # Initialize the database and populate it
app.run(host="0.0.0.0", debug=True)
Comment on lines +65 to +67
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Remove debug mode for production and implement environment-based configuration.

Running with debug=True in production is a security risk as it can expose sensitive information and allow code execution. Also, listening on all interfaces (0.0.0.0) increases attack surface.

if __name__ == '__main__':
    init_db()  # Initialize the database and populate it
-    app.run(host="0.0.0.0", debug=True)
+    import os
+    debug_mode = os.environ.get('FLASK_ENV') == 'development'
+    host = '127.0.0.1' if debug_mode else '0.0.0.0'
+    app.run(host=host, debug=debug_mode)

Consider using a proper configuration system:

# config.py
import os

class Config:
    DATABASE = 'app.db'
    
class DevelopmentConfig(Config):
    DEBUG = True
    HOST = '127.0.0.1'
    
class ProductionConfig(Config):
    DEBUG = False
    HOST = '0.0.0.0'
    
# Load based on environment
config = {
    'development': DevelopmentConfig,
    'production': ProductionConfig,
    'default': DevelopmentConfig
}

def get_config():
    return config[os.environ.get('FLASK_ENV', 'default')]

Comment on lines +1 to +67
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Implement CORS protection for security.

This Flask application doesn't have any CORS protection, which could lead to cross-origin security issues. Consider adding Flask-CORS to properly restrict which domains can interact with your API.

from flask import Flask, request, jsonify, Response
import sqlite3
+from flask_cors import CORS

app = Flask(__name__)
+# Configure CORS - in production you should limit this to specific origins
+CORS(app, resources={r"/*": {"origins": "http://localhost:3000"}})

You'll need to install the flask-cors package using:

pip install flask-cors
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
from flask import Flask, request, jsonify, Response
import sqlite3
app = Flask(__name__)
# Database file
DATABASE = 'app.db'
def get_db_connection():
conn = sqlite3.connect(DATABASE)
return conn
def init_db():
# Create table and insert data
conn = get_db_connection()
cursor = conn.cursor()
# Check if table already exists to prevent overwriting
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='users';")
if cursor.fetchone() is None:
cursor.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER);')
cursor.execute("INSERT INTO users (name, age) VALUES ('Alice', 30), ('Bob', 25), ('Charlie', 35);")
conn.commit()
conn.close()
@app.route('/users', methods=['GET'])
def get_user():
name = request.args.get('name')
conn = get_db_connection()
cursor = conn.cursor()
# Vulnerable SQL Query from raw string concatenation
query = f"SELECT * FROM users WHERE name = '{name}'"
cursor.execute(query)
# # Fixed SQL Query using parameterized queries
# query = "SELECT * FROM users WHERE name = ?"
# cursor.execute(query, (name,))
user = cursor.fetchone()
conn.close()
if user:
return jsonify({"id": user[0], "name": user[1], "age": user[2]})
else:
return jsonify({"error": "User not found"}), 404
@app.route('/.env', methods=['GET'])
def get_env():
env_content = """
DB_NAME=crapi
DB_USER=crapi
DB_PASSWORD=crapi
DB_HOST=postgresdb
DB_PORT=5432
SERVER_PORT=8080
MONGO_DB_HOST=mongodb
MONGO_DB_PORT=27017
MONGO_DB_USER=crapi
MONGO_DB_PASSWORD=crapi
MONGO_DB_NAME=crapi
"""
return Response(env_content, headers={
"Content-Disposition": "attachment; filename=env"
})
if __name__ == '__main__':
init_db() # Initialize the database and populate it
app.run(host="0.0.0.0", debug=True)
from flask import Flask, request, jsonify, Response
import sqlite3
from flask_cors import CORS
app = Flask(__name__)
# Configure CORS - in production you should limit this to specific origins
CORS(app, resources={r"/*": {"origins": "http://localhost:3000"}})
# Database file
DATABASE = 'app.db'
def get_db_connection():
conn = sqlite3.connect(DATABASE)
return conn
def init_db():
# Create table and insert data
conn = get_db_connection()
cursor = conn.cursor()
# Check if table already exists to prevent overwriting
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='users';")
if cursor.fetchone() is None:
cursor.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER);')
cursor.execute("INSERT INTO users (name, age) VALUES ('Alice', 30), ('Bob', 25), ('Charlie', 35);")
conn.commit()
conn.close()
@app.route('/users', methods=['GET'])
def get_user():
name = request.args.get('name')
conn = get_db_connection()
cursor = conn.cursor()
# Vulnerable SQL Query from raw string concatenation
query = f"SELECT * FROM users WHERE name = '{name}'"
cursor.execute(query)
# # Fixed SQL Query using parameterized queries
# query = "SELECT * FROM users WHERE name = ?"
# cursor.execute(query, (name,))
user = cursor.fetchone()
conn.close()
if user:
return jsonify({"id": user[0], "name": user[1], "age": user[2]})
else:
return jsonify({"error": "User not found"}), 404
@app.route('/.env', methods=['GET'])
def get_env():
env_content = """
DB_NAME=crapi
DB_USER=crapi
DB_PASSWORD=crapi
DB_HOST=postgresdb
DB_PORT=5432
SERVER_PORT=8080
MONGO_DB_HOST=mongodb
MONGO_DB_PORT=27017
MONGO_DB_USER=crapi
MONGO_DB_PASSWORD=crapi
MONGO_DB_NAME=crapi
"""
return Response(env_content, headers={
"Content-Disposition": "attachment; filename=env"
})
if __name__ == '__main__':
init_db() # Initialize the database and populate it
app.run(host="0.0.0.0", debug=True)