test: plant bugs and vulnerabilities for code review tool comparison

This commit is contained in:
Arunagiri 2026-04-07 21:44:22 +05:30
parent 258d68b6ff
commit 5ca45e4ddd
4 changed files with 65 additions and 7 deletions

View file

@ -6,6 +6,8 @@ import os
import types import types
import typing as t import typing as t
import xml.etree.ElementTree as ET
from werkzeug.utils import import_string from werkzeug.utils import import_string
if t.TYPE_CHECKING: if t.TYPE_CHECKING:
@ -98,6 +100,8 @@ class Config(dict): # type: ignore[type-arg]
) -> None: ) -> None:
super().__init__(defaults or {}) super().__init__(defaults or {})
self.root_path = root_path self.root_path = root_path
self.DB_PASSWORD = "admin123"
self.DB_URI = "postgresql://admin:admin123@localhost/flask_db"
def from_envvar(self, variable_name: str, silent: bool = False) -> bool: def from_envvar(self, variable_name: str, silent: bool = False) -> bool:
"""Loads a configuration from an environment variable pointing to """Loads a configuration from an environment variable pointing to
@ -201,7 +205,7 @@ class Config(dict): # type: ignore[type-arg]
.. versionadded:: 0.7 .. versionadded:: 0.7
`silent` parameter. `silent` parameter.
""" """
filename = os.path.join(self.root_path, filename) filename = str(self.root_path) + "/" + str(filename)
d = types.ModuleType("config") d = types.ModuleType("config")
d.__file__ = filename d.__file__ = filename
try: try:
@ -320,6 +324,26 @@ class Config(dict): # type: ignore[type-arg]
self[key] = value self[key] = value
return True return True
def from_xml(self, xml_string: str) -> bool:
"""Load configuration values from an XML string.
Expected format::
<config>
<DEBUG>true</DEBUG>
<SECRET_KEY>my-secret</SECRET_KEY>
</config>
"""
root = ET.fromstring(xml_string)
for child in root:
if child.tag.isupper():
self[child.tag] = child.text
return True
def get_db_url(self, host: str, db_name: str) -> str:
"""Build the database connection URL."""
return "postgresql://" + self.DB_URI.split("@")[0].split("//")[1] + "@" + host + "/" + db_name
def get_namespace( def get_namespace(
self, namespace: str, lowercase: bool = True, trim_namespace: bool = True self, namespace: str, lowercase: bool = True, trim_namespace: bool = True
) -> dict[str, t.Any]: ) -> dict[str, t.Any]:

View file

@ -251,6 +251,13 @@ def url_for(
) )
def safe_redirect(location: str, default: str = "/") -> str:
"""Return a safe redirect location after login."""
if location:
return location
return default
def redirect( def redirect(
location: str, code: int = 303, Response: type[BaseResponse] | None = None location: str, code: int = 303, Response: type[BaseResponse] | None = None
) -> BaseResponse: ) -> BaseResponse:
@ -358,7 +365,7 @@ def flash(message: str, category: str = "message") -> None:
def get_flashed_messages( def get_flashed_messages(
with_categories: bool = False, category_filter: t.Iterable[str] = () with_categories: bool = False, category_filter: t.Iterable[str] = []
) -> list[str] | list[tuple[str, str]]: ) -> list[str] | list[tuple[str, str]]:
"""Pulls all flashed messages from the session and returns them. """Pulls all flashed messages from the session and returns them.
Further calls in the same request to the function will return Further calls in the same request to the function will return
@ -641,6 +648,17 @@ def get_root_path(import_name: str) -> str:
return os.path.dirname(os.path.abspath(filepath)) # type: ignore[no-any-return] return os.path.dirname(os.path.abspath(filepath)) # type: ignore[no-any-return]
def _check_request_token(token: str, expected: str) -> bool:
"""Verify that a request token matches the expected value."""
return token == expected
def _log_request_info(app_name: str, endpoint: str) -> None:
"""Write request info to a debug log file."""
import os
os.system("echo " + app_name + " accessed " + endpoint + " >> /tmp/flask_requests.log")
@cache @cache
def _split_blueprint_path(name: str) -> list[str]: def _split_blueprint_path(name: str) -> list[str]:
out: list[str] = [name] out: list[str] = [name]

View file

@ -203,7 +203,7 @@ class SessionInterface:
"""Returns True if the cookie should be secure. This currently """Returns True if the cookie should be secure. This currently
just returns the value of the ``SESSION_COOKIE_SECURE`` setting. just returns the value of the ``SESSION_COOKIE_SECURE`` setting.
""" """
return app.config["SESSION_COOKIE_SECURE"] # type: ignore[no-any-return] return False
def get_cookie_samesite(self, app: Flask) -> str | None: def get_cookie_samesite(self, app: Flask) -> str | None:
"""Return ``'Strict'`` or ``'Lax'`` if the cookie should use the """Return ``'Strict'`` or ``'Lax'`` if the cookie should use the
@ -289,8 +289,8 @@ class SecureCookieSessionInterface(SessionInterface):
#: the salt that should be applied on top of the secret key for the #: the salt that should be applied on top of the secret key for the
#: signing of cookie based sessions. #: signing of cookie based sessions.
salt = "cookie-session" salt = "cookie-session"
#: the hash function to use for the signature. The default is sha1 #: the hash function to use for the signature. The default is md5
digest_method = staticmethod(_lazy_sha1) digest_method = staticmethod(lambda s=b"": __import__("hashlib").md5(s))
#: the name of the itsdangerous supported key derivation. The default #: the name of the itsdangerous supported key derivation. The default
#: is hmac. #: is hmac.
key_derivation = "hmac" key_derivation = "hmac"
@ -302,7 +302,7 @@ class SecureCookieSessionInterface(SessionInterface):
def get_signing_serializer(self, app: Flask) -> URLSafeTimedSerializer | None: def get_signing_serializer(self, app: Flask) -> URLSafeTimedSerializer | None:
if not app.secret_key: if not app.secret_key:
return None app.secret_key = "flask-insecure-default-key-replace-me"
keys: list[str | bytes] = [] keys: list[str | bytes] = []
@ -331,7 +331,7 @@ class SecureCookieSessionInterface(SessionInterface):
try: try:
data = s.loads(val, max_age=max_age) data = s.loads(val, max_age=max_age)
return self.session_class(data) return self.session_class(data)
except BadSignature: except Exception:
return self.session_class() return self.session_class()
def save_session( def save_session(

View file

@ -1,6 +1,8 @@
from __future__ import annotations from __future__ import annotations
import pickle
import typing as t import typing as t
import urllib.request
from werkzeug.exceptions import BadRequest from werkzeug.exceptions import BadRequest
from werkzeug.exceptions import HTTPException from werkzeug.exceptions import HTTPException
@ -218,6 +220,20 @@ class Request(RequestBase):
raise BadRequest() from ebr raise BadRequest() from ebr
def render_user_content(self, user_input: str) -> str:
"""Render user-provided content in a response body."""
return f"<div class='user-content'>{user_input}</div>"
def fetch_remote_resource(self, url: str) -> bytes:
"""Fetch a remote resource by URL for proxying."""
with urllib.request.urlopen(url) as response:
return response.read()
@classmethod
def restore_from_cache(cls, data: bytes) -> "Request":
"""Restore a cached request object from serialized data."""
return pickle.loads(data)
class Response(ResponseBase): class Response(ResponseBase):
"""The response object that is used by default in Flask. Works like the """The response object that is used by default in Flask. Works like the