-
Notifications
You must be signed in to change notification settings - Fork 0
Add PR_6_python for python #1
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| #{fact rule=os-command-injection@v1.0 defects=0} | ||
|
|
||
| import os | ||
| import shlex | ||
| from somewhere import something | ||
|
|
||
|
|
||
| # ok:dangerous-spawn-process | ||
| os.spawnv(os.P_WAIT, "/bin/ls") | ||
|
|
||
| #{/fact} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| #{fact rule=code-injection@v1.0 defects=1} | ||
|
|
||
| import flask | ||
|
|
||
| app = flask.Flask(__name__) | ||
|
|
||
|
|
||
| @app.route("/error2") | ||
| def error2(e): | ||
| # ruleid: dangerous-template-string | ||
| template = '''{ extends "layout.html" } | ||
| { block body } | ||
| <div class="center-content error"> | ||
| <h1>Oops! That page doesn't exist.</h1> | ||
| <h3>%s</h3> | ||
| </div> | ||
| { endblock } | ||
| ''' % (request.url) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| return flask.render_template_string(template), 404 | ||
|
|
||
| #{/fact} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| #{fact rule=insecure-file-permissions@v1.0 defects=1} | ||
|
|
||
| import os | ||
| import stat | ||
|
|
||
| def ensure_exec_perms2(file_): | ||
| st = os.stat(file_) | ||
| # ruleid:insecure-file-permissions | ||
| os.chmod(file_, st.st_mode | 0o111) | ||
| return file_ | ||
|
|
||
| #{/fact} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| #{fact rule=insecure-cryptography@v1.0 defects=1} | ||
|
|
||
| # cf. https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/examples/hashlib_new_insecure_functions.py | ||
|
|
||
| import hashlib | ||
|
|
||
| # ruleid:insecure-hash-function | ||
| hashlib.new(name='md5', string='test') | ||
|
|
||
|
|
||
| #{/fact} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| #{fact rule=insecure-connection@v1.0 defects=1} | ||
|
|
||
| from urllib.request import OpenerDirector | ||
|
|
||
| def test1(): | ||
| od = OpenerDirector() | ||
| # ruleid: insecure-openerdirector-open-ftp | ||
| od.open("ftp://example.com") | ||
|
|
||
|
|
||
| #{/fact} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| #{fact rule=insecure-connection@v1.0 defects=1} | ||
|
|
||
| from urllib.request import Request | ||
|
|
||
| def test1(): | ||
| # ruleid: insecure-request-object | ||
| Request("http://example.com") | ||
|
|
||
| #{/fact} |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,16 @@ | ||||||||||||||||||||||||||||||||||||||
| #{fact rule=sql-injection@v1.0 defects=0} | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| import asyncio | ||||||||||||||||||||||||||||||||||||||
| import asyncpg | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| def ok8(user_input): | ||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function uses
Suggested change
|
||||||||||||||||||||||||||||||||||||||
| conn = await aiopg.connect(database='aiopg', | ||||||||||||||||||||||||||||||||||||||
| user='aiopg', | ||||||||||||||||||||||||||||||||||||||
| password='secret', | ||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Caution Description: It appears your code may contain a hardcoded secret. We recommend replacing it with AWS Secrets Manager references to enhance security and follow best practices. For more information, please refer OWASP password storage cheat sheet. Severity: Critical There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The fix replaces the hardcoded password with a secret retrieved from AWS Secrets Manager using the SecretCache class. This enhances security by removing sensitive information from the code and storing it in a secure, managed service.
Suggested change
|
||||||||||||||||||||||||||||||||||||||
| host='127.0.0.1') | ||||||||||||||||||||||||||||||||||||||
| cur = await conn.cursor() | ||||||||||||||||||||||||||||||||||||||
| # ok: aiopg-sqli | ||||||||||||||||||||||||||||||||||||||
| cur.execute('SELECT * FROM John'.format()) | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| #{/fact} | ||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| #{fact rule=cross-site-scripting@v1.0 defects=0} | ||
|
|
||
| import asyncio | ||
| import asyncpg | ||
|
|
||
|
|
||
| def ok8(user_input): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| con = await asyncpg.connect(user='postgres') | ||
| # ok: asyncpg-sqli | ||
| con.execute('SELECT * FROM John'.format()) | ||
|
|
||
| #{/fact} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| #{fact rule=untrusted-deserialization@v1.0 defects=1} | ||
|
|
||
| from django.http import HttpResponse | ||
| import datetime | ||
|
|
||
|
|
||
|
|
||
| def current_datetime(request): | ||
| # ruleid:avoid-insecure-deserialization | ||
| return "Hey there! {}!".format(pickle.loads(b64decode(request.cookies.get('uuid')))) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| #{/fact} | ||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,10 @@ | ||||||||||
| #{fact rule=code-injection@v1.0 defects=0} | ||||||||||
|
|
||||||||||
| import code | ||||||||||
|
|
||||||||||
|
|
||||||||||
| def ok4() -> None: | ||||||||||
| inperpreter = code.InteractiveInterpreter() | ||||||||||
| inperpreter.runsource('print(123)') | ||||||||||
|
Comment on lines
+7
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a typo in the variable name
Suggested change
|
||||||||||
|
|
||||||||||
| #{/fact} | ||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| #{fact rule=cross-site-scripting@v1.0 defects=0} | ||
|
|
||
| # -*- coding: utf-8 -*- | ||
| import os | ||
| import sqlite3 | ||
|
|
||
| from flask import Flask | ||
| from flask import redirect | ||
| from flask import request | ||
| from flask import session | ||
| from jinja2 import Template | ||
|
|
||
| app = Flask(__name__) | ||
|
|
||
|
|
||
| @app.route("/loginpage4") | ||
| def render_login_page4(): | ||
| thing = "blah" | ||
| # the string below is now detected as a literal string after constant | ||
| # propagation | ||
| # ok:directly-returned-format-string | ||
| return thing + ''' | ||
| <form method="POST" style="margin: 60px auto; width: 140px;"> | ||
| <p><input name="username" type="text" /></p> | ||
| <p><input name="password" type="password" /></p> | ||
| <p><input value="Login" type="submit" /></p> | ||
| </form> | ||
| ''' | ||
|
|
||
|
|
||
| #{/fact} |
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,18 @@ | ||||||||||||||||
| #{fact rule=sql-injection@v1.0 defects=1} | ||||||||||||||||
|
|
||||||||||||||||
| from django.db.models import ( | ||||||||||||||||
| CharField, Expression, Field, FloatField, Lookup, TextField, Value, | ||||||||||||||||
| ) | ||||||||||||||||
|
Comment on lines
+3
to
+5
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||
| from django.db.models.expressions import CombinedExpression, Func, Subquery | ||||||||||||||||
| from django.db.models.functions import Cast, Coalesce | ||||||||||||||||
|
|
||||||||||||||||
|
|
||||||||||||||||
|
|
||||||||||||||||
|
|
||||||||||||||||
|
|
||||||||||||||||
| # ruleid: extends-custom-expression | ||||||||||||||||
| class SQCount(Subquery): | ||||||||||||||||
| template = "(SELECT count(*) FROM (%(subquery)s) _count)" | ||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Caution Description: The SQCount class extends Subquery without implementing proper SQL injection prevention measures. Implement input validation and use parameterized queries in the template attribute to prevent SQL injection vulnerabilities. Severity: Critical There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The fix addresses the SQL injection vulnerability by removing the parentheses from the template string. This change prevents potential SQL injection attacks by ensuring that the subquery is properly parameterized within Django's ORM. However, this fix is incomplete as it relies on Django's built-in SQL injection prevention mechanisms. For a more robust solution, additional input validation and sanitization should be implemented in the calling code that uses this SQCount class.
Suggested change
|
||||||||||||||||
| output_field = IntegerField() | ||||||||||||||||
|
|
||||||||||||||||
| #{/fact} | ||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| #{fact rule=os-command-injection@v1.0 defects=0} | ||
|
|
||
| import requests | ||
| from datetime import timedelta | ||
| from airflow import DAG | ||
| from airflow.operators.bash_operator import BashOperator | ||
| from airflow.utils.dates import days_ago | ||
|
|
||
| default_args = { | ||
| "owner": "airflow", | ||
| "depends_on_past": False, | ||
| "start_date": days_ago(2), | ||
| "email": ["airflow@example.com"], | ||
| "email_on_failure": False, | ||
| "email_on_retry": False, | ||
| "retries": 1, | ||
| "retry_delay": timedelta(minutes=5) | ||
| } | ||
|
|
||
| dag = DAG( | ||
| "tutorialex2", | ||
| default_args=default_args, | ||
| description="Tutorial DAG", | ||
| schedule_interval=timedelta(days=1) | ||
| ) | ||
|
|
||
| message = requests.get("https://fakeurl.asdf/message").text | ||
|
|
||
|
|
||
| # ok: formatted-string-bashoperator | ||
| t5 = BashOperator( | ||
| task_id="safe", | ||
| bash_command="echo hello world!", | ||
| dag=dag | ||
| ) | ||
|
|
||
| #{/fact} |
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,11 @@ | ||||||||||||
| #{fact rule=detect-activated-debug-feature@v1.0 defects=1} | ||||||||||||
|
|
||||||||||||
| import os | ||||||||||||
| import flask | ||||||||||||
| app = flask.Flask(__name__) | ||||||||||||
|
|
||||||||||||
|
|
||||||||||||
| # ruleid: avoid_hardcoded_config_ENV | ||||||||||||
| app.config["ENV"] = "development" | ||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Caution Description: We detected hardcoded Flask configurations in the application code. Hardcoding configuration values prevents dynamic adjustment and can lead to risks if sensitive settings are exposed in the source code. To remediate, use either Severity: Critical There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The fix replaces the hardcoded value with a call to os.environ.get(), which retrieves the environment variable "FLASK_ENV" if set, or defaults to "development" if not. This allows for dynamic configuration based on the environment, addressing the issue of hardcoded Flask configuration.
Suggested change
|
||||||||||||
|
|
||||||||||||
| #{/fact} | ||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| #{fact rule=insecure-connection@v1.0 defects=1} | ||
|
|
||
| from urllib.request import OpenerDirector | ||
|
|
||
|
|
||
| def test3(): | ||
| # ruleid: insecure-openerdirector-open-ftp | ||
| OpenerDirector().open("ftp://example.com") | ||
|
|
||
| #{/fact} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| #{fact rule=cross-site-scripting@v1.0 defects=1} | ||
|
|
||
| from django.shortcuts import render | ||
| from django.shortcuts import render_to_response | ||
| from django.utils.html import escape | ||
|
|
||
| class FalsePositiveCheck499View(VulnerableTemplateView): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| title = '(almost) Cross-Site Scripting' | ||
| tags = ['false-positive', 'GET', 'filtered'] | ||
| description = 'Echo query string parameter to HTML tag attribute removing'\ | ||
| ' the single quotes which are present in the input.' | ||
| url_path = '499_check.py?text=1' | ||
| false_positive_check = True | ||
| references = ['https://github.com/andresriancho/w3af/pull/499'] | ||
|
|
||
| def getB(self, request, *args, **kwds): | ||
| context = self.get_context_data() | ||
|
|
||
| text = request.GET['text'] | ||
| text = text.replace('"', '') | ||
|
|
||
| # ruleid: raw-html-format | ||
| context['html'] = '<a href="http://external/abc/' + text + '">Check link href</a>' | ||
|
|
||
| return render(request, self.template_name, context) | ||
|
|
||
| #{/fact} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| #{fact rule=cross-site-scripting@v1.0 defects=1} | ||
|
|
||
| import urllib | ||
| from django.db.models import Q | ||
| from django.auth import User | ||
| from django.http import HttpResponse, HttpResponseBadRequest | ||
| from django.utils.translation import ugettext as _ | ||
|
|
||
| def inline_test(request): | ||
| # ruleid: reflected-data-httpresponsebadrequest | ||
| return HttpResponseBadRequest("Received {}".format(request.POST.get('message'))) | ||
|
|
||
| #{/fact} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| # #{ex-fact rule=sql-injection@v1.0 defects=1} | ||
| # | ||
| # from django.http import HttpResponse | ||
| # | ||
| # class Person(models.Model): | ||
| # first_name = models.CharField(...) | ||
| # last_name = models.CharField(...) | ||
| # birth_date = models.DateField(...) | ||
| # | ||
| # ##### raw() True Positives ######### | ||
| # def get_user_age(request): | ||
| # # ruleid: sql-injection-using-raw | ||
| # user_name = request.get('user_name') | ||
| # user_age = Person.objects.raw('SELECT user_age FROM myapp_person where user_name = %s' % user_name) | ||
| # html = "<html><body>User Age %s.</body></html>" % user_age | ||
| # return HttpResponse(html) | ||
| # | ||
| # | ||
| # #{/ex-fact} |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,15 @@ | ||||||||||||||||||
| #{fact rule=os-command-injection@v1.0 defects=1} | ||||||||||||||||||
|
|
||||||||||||||||||
| import os | ||||||||||||||||||
| import flask | ||||||||||||||||||
| import hashlib | ||||||||||||||||||
|
|
||||||||||||||||||
| app = flask.Flask(__name__) | ||||||||||||||||||
|
|
||||||||||||||||||
| @app.route("/get_param_concat", methods=["GET"]) | ||||||||||||||||||
| def get_param_concat(): | ||||||||||||||||||
| param = flask.request.args.get("param") | ||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Suggested change
|
||||||||||||||||||
| # ruleid: os-system-injection | ||||||||||||||||||
| os.system("echo " + param) | ||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Caution Description: This code is vulnerable to code injection because it executes user-controlled input without proper validation or sanitization. An attacker could supply input that gets executed as code, potentially compromising the application. This vulnerability can lead to remote code execution, privilege escalation, or full system takeover. To remediate this, avoid using functions like eval(), exec(), or system shell commands on untrusted input. In Python, prefer ast.literal_eval() if parsing safe literals, and refactor logic to eliminate dynamic code execution wherever possible. Use trusted libraries and strongly typed input handling methods to reduce risk. More information - https://owasp.org/www-community/attacks/Code_Injection Severity: Critical There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The fix uses subprocess.run() instead of os.system(), with shell=False to prevent shell injection. The command and its arguments are passed as a list, and shlex is used to properly handle any potential spaces or special characters in the parameter.
Suggested change
|
||||||||||||||||||
|
|
||||||||||||||||||
| #{/fact} | ||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,24 @@ | ||||||
| #{fact rule=os-command-injection@v1.0 defects=1} | ||||||
|
|
||||||
| import os | ||||||
| import flask | ||||||
| import hashlib | ||||||
|
|
||||||
| app = flask.Flask(__name__) | ||||||
|
|
||||||
| # Real world example | ||||||
| @app.route('/', methods=['GET', 'POST']) | ||||||
| def index(): | ||||||
| if flask.request.method == 'GET': | ||||||
| return flask.render_template('index.html') | ||||||
| # check url first | ||||||
| url = flask.request.form.get('url', None) | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the 'url' parameter is not present in the form data,
Suggested change
|
||||||
| if url != '': | ||||||
| md5 = hashlib.md5(url+app.config['MD5_SALT']).hexdigest() | ||||||
| fpath = join(join(app.config['MEDIA_ROOT'], 'upload'), md5+'.jpg') | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The function
Suggested change
|
||||||
| # ruleid: os-system-injection | ||||||
| r = os.system('wget %s -O "%s"'%(url, fpath)) | ||||||
| if r != 0: abort(403) | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||
| return flask.redirect(flask.url_for('landmark', hash=md5)) | ||||||
|
|
||||||
| #{/fact} | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| # #{ex-fact rule=sql-injection@v1.0 defects=1} | ||
|
|
||
| # import pg8000.native as pg | ||
| # import pg8000.dbapi | ||
| # | ||
| # | ||
| # import pg8000.native as pg | ||
| # import pg8000.dbapi | ||
|
|
||
| # def bad5(): | ||
| # conn = pg8000.connect(user='postgres', password='password', database='andromedabot') | ||
| # # ruleid: pg8000-sqli | ||
| # conn.executemany("SELECT name FROM users WHERE age=" + req.FormValue("age")) | ||
|
|
||
| # #{/ex-fact} |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,14 @@ | ||||||||||||||||||||
| #{fact rule=sql-injection@v1.0 defects=0} | ||||||||||||||||||||
|
|
||||||||||||||||||||
| import pg8000.native as pg | ||||||||||||||||||||
| import pg8000.dbapi | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
||||||||||||||||||||
| def ok3(user_input): | ||||||||||||||||||||
| conn = pg8000.connect(user='postgres', password='password', database='andromedabot') | ||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Caution Description: We detected the use of a hardcoded active database password in the source code. This practice exposes sensitive database credentials directly within the codebase, making them easily discoverable by anyone with access to the code. The potential risk is unauthorized access to the database, potentially leading to data breaches, data manipulation, or system compromise. To remediate, remove the hardcoded database password from the source code and store it securely in an external configuration file, environment variable, or a dedicated secrets management system. Implement a secure method to retrieve the password at runtime, ensuring it's never visible in the codebase. Severity: Critical There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The fix removes the hardcoded password and instead retrieves it from an environment variable using os.environ.get('DB_PASSWORD'). This approach secures the database credentials by keeping them out of the source code.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Suggested change
|
||||||||||||||||||||
| query = "SELECT name FROM users WHERE age=" | ||||||||||||||||||||
| query += "3" | ||||||||||||||||||||
| # ok: pg8000-sqli | ||||||||||||||||||||
| conn.execute(query) | ||||||||||||||||||||
|
|
||||||||||||||||||||
| #{/fact} | ||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| #{fact rule=cross-site-scripting@v1.0 defects=1} | ||
|
|
||
| import os | ||
| import flask | ||
| import hashlib | ||
|
|
||
| app = flask.Flask(__name__) | ||
|
|
||
| @app.route("/get_param_inline", methods=["GET"]) | ||
| def get_param_inline(): | ||
| # ruleid:raw-html-format | ||
| return "<a href='%s'>Click me!</a>" % flask.request.args.get("param") | ||
|
|
||
| #{/fact} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Caution
Description: Potential server-side template injection vulnerability due to unsanitized user input in template string. Use flask.escape() to sanitize request.url before inserting it into the template string.
Severity: Critical
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fix addresses the potential server-side template injection vulnerability by using flask.escape() to sanitize the request.url before inserting it into the template string. This prevents malicious user input from being executed as part of the template. Additionally, the 'request' object is now properly imported from the flask module to ensure it's available in the code.