Skip to content

Latest commit

Β 

History

History
2076 lines (1407 loc) Β· 69.9 KB

File metadata and controls

2076 lines (1407 loc) Β· 69.9 KB

HoundDog.ai Report

Generated by HoundDog.ai on 2026-01-29 11:54:49 AM.

Table of Contents

Viewing This Report

For the best viewing experience, we recommend using Google Chrome with Markdown Viewer extension. For large codebases such as monorepos, this report can be too large to render. So consider scanning a subset of the codebase, one service at a time.

Setup Instructions:

  1. Install the Markdown Viewer extension in Chrome

  2. Follow the instructions here to configure the extension.

  3. Open this file in Chrome to view it with optimal rendering.

If you face any issues, please reach out to us at support@hounddog.ai.

Key Terminology

  • Data Elements: Sensitive data types such as PII (Personally Identifiable Information), PHI (Protected Health Information), PIFI (Personally Identifiable Financial Information), authentication tokens, and other confidential information detected in source code.

  • Data Element Occurrences: Specific instances of sensitive data elements detected in the codebase. For example, a variable assignment var email = 'john@example.com' is one occurrence of the email data element.

  • Sensitivity: Data elements are assigned one of the following sensitivity levels:

    • πŸ”΄ Critical (e.g., credit card numbers)
    • 🟠 Medium (e.g., phone numbers)
    • 🟑 Low (e.g., email addresses)

    Note that the presence of sensitive data alone does not necessarily indicate a privacy risk.

  • Data Sinks: Destinations where sensitive data elements are transmitted or stored, including (but not limited to) logs, databases, HTTP APIs, and third-party SDKs.

  • Data Sink Occurrences: Specific instances of data sinks detected in the codebase. For example, a function call logger.info(user_email) is one occurrence of the logs data sink.

  • Dataflows: The paths that sensitive data element occurrences follow through the codebase to reach data sinks.

  • Safe Dataflows: Dataflows in which the transmission or storage of sensitive data elements are either:

    1. Sent to destinations that are generally known to be safe (e.g., encrypted databases, internal gRPC endpoints).
    2. Sent to destinations that are generally considered unsafe (e.g., logs, third-party APIs), but the data element is explicitly allowlisted.
    3. Sanitized before reaching the sink (e.g., hashed, masked, encrypted, redacted).
  • Risky Dataflows: Vulnerable dataflows where sensitive data reaches unsafe sinks without adequate sanitization, potentially exposing it to misuse or leakage.

  • Severity: Dataflows are assigned one of the following severity levels:

    • πŸŸ₯ Critical
    • 🟧 Medium
    • 🟨 Low
    • 🟩 Info (for safe dataflows)

    The severity is determined by the highest sensitivity of the data elements exposed.

Scan Configuration

The table below shows the configuration parameters used for this scan.

Parameter Value
Scanner Version dev
Scanner Build dev
Was HOUNDDOG_API_KEY provided? No
Scan Target Directory /Users/joohwan/hounddog-workspace/hounddog-test-python-app
Git Source Code Manager Type GitHub (Cloud)
Git Repository hounddogai/hounddog-test-python-app
Git Branch main
Git Commit SHA 781c916790f5f99150244ab4e9942c13a563d2c3
Ignored File Patterns 0
Ignored Data Elements 0
Ignored Data Sinks 0
Ignored Data Element Occurrences 0
Ignored Dataflows 0

Files Detected

The table below shows the files discovered in the codebase, grouped by programming language.

Language File Count Line Count
Markdown 1 463
Python 12 3993
TOML 1 19
Other 1 0
Total 15 4475

Data Elements

The table below shows the sensitive data elements discovered in the codebase and the sinks they are exposed to. Scroll down further to see detailed information about each data element.

Sensitivity Data Element Risky Sinks Safe Sinks
πŸ”΄ Critical Medical Condition None SQL Database
πŸ”΄ Critical Medical History OpenAI SQL Database
πŸ”΄ Critical Medical Record Number None SQL Database
🟠 Medium Blood Cholesterol None None
🟠 Medium Blood Pressure None None
🟠 Medium Blood Type None SQL Database
🟠 Medium Medication None SQL Database
🟠 Medium Phone Number Sentry SQL Database
🟠 Medium Sexual Orientation None SQL Database
🟠 Medium Vital Sign None None
🟑 Low Date of Birth None SQL Database
🟑 Low Email None SQL Database
🟑 Low Emergency Contact None SQL Database
🟑 Low First Name Logs SQL Database
🟑 Low Last Name Logs SQL Database

Medical Condition

Sensitivity: πŸ”΄ Critical β€’ Tags: PHI β€’ Occurrences: 49

Risky Dataflows:

No risky dataflows detected

Safe Dataflows:

SQL Database
  1. First detected here in utils/database.py:34:5

    allergies = Column(Text)
  2. Stored in SQL Database in utils/database.py:34:5

    allergies = Column(Text)

Visualization:

%%{init: {'flowchart': {'curve': 'linear'}}}%%
flowchart LR
de_43("<a href='#data-element-43'>Medical Condition</a>")
style de_43 fill:none,stroke:#808080,stroke-width:1px
file_43_a5d31205d55c70dbb753118aeba456b0("<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/database.py'>utils/database.py</a>")
style file_43_a5d31205d55c70dbb753118aeba456b0 fill:none,stroke:#808080,stroke-width:1px
de_43 --> file_43_a5d31205d55c70dbb753118aeba456b0
file_43_a5d31205d55c70dbb753118aeba456b0 --> |<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/database.py#L34-L34'>L34</a>| sink_sql_db
sink_sql_db("<a href='#data-sink-sql-db'>SQL Database</a>")
style sink_sql_db fill:#00800026,stroke:#006400,color:#006400

Loading

Medical History

Sensitivity: πŸ”΄ Critical β€’ Tags: PHI β€’ Occurrences: 54

Risky Dataflows:

OpenAI
  1. First detected here in pages/patient.py:59:9

    medical_history
  2. Placed inside a string and assigned to 'patient_context' in pages/patient.py:284:17

    patient_context = f"""
    Patient Medical History: {medical_history}
    """
  3. Wrapped in langchain_core.messages.SystemMessage and assigned to 'messages' in pages/patient.py:308:25

    messages = [SystemMessage(content=patient_context)]
  4. Exposed to OpenAI in pages/patient.py:321:36

    llm.invoke(messages)

Safe Dataflows:

SQL Database
  1. First detected here in utils/database.py:37:5

    medical_history = Column(Text)
  2. Stored in SQL Database in utils/database.py:37:5

    medical_history = Column(Text)

Visualization:

%%{init: {'flowchart': {'curve': 'linear'}}}%%
flowchart LR
de_45("<a href='#data-element-45'>Medical History</a>")
style de_45 fill:none,stroke:#808080,stroke-width:1px
file_45_a5d31205d55c70dbb753118aeba456b0("<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/database.py'>utils/database.py</a>")
style file_45_a5d31205d55c70dbb753118aeba456b0 fill:none,stroke:#808080,stroke-width:1px
de_45 --> file_45_a5d31205d55c70dbb753118aeba456b0
file_45_a5d31205d55c70dbb753118aeba456b0 --> |<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/database.py#L37-L37'>L37</a>| sink_sql_db
file_45_0a6344e795897f52ee7ed6e95daf4674("<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/pages/patient.py'>pages/patient.py</a>")
style file_45_0a6344e795897f52ee7ed6e95daf4674 fill:none,stroke:#808080,stroke-width:1px
de_45 --> file_45_0a6344e795897f52ee7ed6e95daf4674
file_45_0a6344e795897f52ee7ed6e95daf4674 --> |<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/pages/patient.py#L321-L321'>L321</a>| sink_openai
sink_sql_db("<a href='#data-sink-sql-db'>SQL Database</a>")
style sink_sql_db fill:#00800026,stroke:#006400,color:#006400
sink_openai("<a href='#data-sink-openai'>OpenAI</a>")
style sink_openai fill:#FF000026,stroke:#C80000,color:#C80000

Loading

Medical Record Number

Sensitivity: πŸ”΄ Critical β€’ Tags: PHI β€’ Occurrences: 9

Risky Dataflows:

No risky dataflows detected

Safe Dataflows:

SQL Database


Occurrence #1

  1. First detected here in utils/data_manager.py:387:69

    MedicalRecord.id
  2. Stored in SQL Database in utils/data_manager.py:387:58

    func.count(MedicalRecord.id)


Occurrence #2

  1. First detected here in utils/data_manager.py:248:45

    MedicalRecord.id
  2. Stored in SQL Database in utils/data_manager.py:248:34

    func.count(MedicalRecord.id)


Occurrence #3

  1. First detected here in utils/data_manager.py:496:54

    MedicalRecord.id
  2. Stored in SQL Database in utils/data_manager.py:496:43

    func.count(MedicalRecord.id)


Occurrence #4

  1. First detected here in utils/data_manager.py:387:69

    MedicalRecord.id
  2. Stored in SQL Database in utils/data_manager.py:389:32

    func.count(MedicalRecord.id)


Occurrence #5

  1. First detected here in utils/data_manager.py:239:45

    MedicalRecord.id
  2. Stored in SQL Database in utils/data_manager.py:239:34

    func.count(MedicalRecord.id)

Visualization:

%%{init: {'flowchart': {'curve': 'linear'}}}%%
flowchart LR
de_47("<a href='#data-element-47'>Medical Record Number</a>")
style de_47 fill:none,stroke:#808080,stroke-width:1px
file_47_f3b82eca6148dc549059de4f35e70529("<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/data_manager.py'>utils/data_manager.py</a>")
style file_47_f3b82eca6148dc549059de4f35e70529 fill:none,stroke:#808080,stroke-width:1px
de_47 --> file_47_f3b82eca6148dc549059de4f35e70529
file_47_f3b82eca6148dc549059de4f35e70529 --> |<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/data_manager.py#L248-L248'>L248</a>| sink_sql_db
sink_sql_db("<a href='#data-sink-sql-db'>SQL Database</a>")
style sink_sql_db fill:#00800026,stroke:#006400,color:#006400

Loading

Blood Cholesterol

Sensitivity: 🟠 Medium β€’ Tags: PHI β€’ Occurrences: 17

Risky Dataflows:

No risky dataflows detected

Safe Dataflows:

No safe dataflows detected

Blood Pressure

Sensitivity: 🟠 Medium β€’ Tags: PHI β€’ Occurrences: 34

Risky Dataflows:

No risky dataflows detected

Safe Dataflows:

No safe dataflows detected

Blood Type

Sensitivity: 🟠 Medium β€’ Tags: PHI β€’ Occurrences: 50

Risky Dataflows:

No risky dataflows detected

Safe Dataflows:

SQL Database
  1. First detected here in utils/database.py:33:5

    blood_type = Column(String(10))
  2. Stored in SQL Database in utils/database.py:33:5

    blood_type = Column(String(10))

Visualization:

%%{init: {'flowchart': {'curve': 'linear'}}}%%
flowchart LR
de_10("<a href='#data-element-10'>Blood Type</a>")
style de_10 fill:none,stroke:#808080,stroke-width:1px
file_10_a5d31205d55c70dbb753118aeba456b0("<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/database.py'>utils/database.py</a>")
style file_10_a5d31205d55c70dbb753118aeba456b0 fill:none,stroke:#808080,stroke-width:1px
de_10 --> file_10_a5d31205d55c70dbb753118aeba456b0
file_10_a5d31205d55c70dbb753118aeba456b0 --> |<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/database.py#L33-L33'>L33</a>| sink_sql_db
sink_sql_db("<a href='#data-sink-sql-db'>SQL Database</a>")
style sink_sql_db fill:#00800026,stroke:#006400,color:#006400

Loading

Medication

Sensitivity: 🟠 Medium β€’ Tags: PHI β€’ Occurrences: 49

Risky Dataflows:

No risky dataflows detected

Safe Dataflows:

SQL Database
  1. First detected here in utils/database.py:38:5

    current_medications = Column(Text)
  2. Stored in SQL Database in utils/database.py:38:5

    current_medications = Column(Text)

Visualization:

%%{init: {'flowchart': {'curve': 'linear'}}}%%
flowchart LR
de_49("<a href='#data-element-49'>Medication</a>")
style de_49 fill:none,stroke:#808080,stroke-width:1px
file_49_a5d31205d55c70dbb753118aeba456b0("<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/database.py'>utils/database.py</a>")
style file_49_a5d31205d55c70dbb753118aeba456b0 fill:none,stroke:#808080,stroke-width:1px
de_49 --> file_49_a5d31205d55c70dbb753118aeba456b0
file_49_a5d31205d55c70dbb753118aeba456b0 --> |<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/database.py#L38-L38'>L38</a>| sink_sql_db
sink_sql_db("<a href='#data-sink-sql-db'>SQL Database</a>")
style sink_sql_db fill:#00800026,stroke:#006400,color:#006400

Loading

Phone Number

Sensitivity: 🟠 Medium β€’ Tags: PII β€’ Occurrences: 57

Risky Dataflows:

Sentry
  1. First detected here in pages/patient.py:101:33

    "phone": phone
  2. Placed inside a dictionary and exposed to Sentry in pages/patient.py:98:21

    sentry_sdk.capture_message(
        f"Failed to add patient",
        level="error",
        extras={"phone": phone},
    )

Safe Dataflows:

SQL Database
  1. First detected here in utils/database.py:30:5

    phone = Column(String(50))
  2. Stored in SQL Database in utils/database.py:30:5

    phone = Column(String(50))

Visualization:

%%{init: {'flowchart': {'curve': 'linear'}}}%%
flowchart LR
de_60("<a href='#data-element-60'>Phone Number</a>")
style de_60 fill:none,stroke:#808080,stroke-width:1px
file_60_0a6344e795897f52ee7ed6e95daf4674("<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/pages/patient.py'>pages/patient.py</a>")
style file_60_0a6344e795897f52ee7ed6e95daf4674 fill:none,stroke:#808080,stroke-width:1px
de_60 --> file_60_0a6344e795897f52ee7ed6e95daf4674
file_60_0a6344e795897f52ee7ed6e95daf4674 --> |<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/pages/patient.py#L98-L102'>L98</a>| sink_sentry
file_60_a5d31205d55c70dbb753118aeba456b0("<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/database.py'>utils/database.py</a>")
style file_60_a5d31205d55c70dbb753118aeba456b0 fill:none,stroke:#808080,stroke-width:1px
de_60 --> file_60_a5d31205d55c70dbb753118aeba456b0
file_60_a5d31205d55c70dbb753118aeba456b0 --> |<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/database.py#L30-L30'>L30</a>| sink_sql_db
sink_sentry("<a href='#data-sink-sentry'>Sentry</a>")
style sink_sentry fill:#FF000026,stroke:#C80000,color:#C80000
sink_sql_db("<a href='#data-sink-sql-db'>SQL Database</a>")
style sink_sql_db fill:#00800026,stroke:#006400,color:#006400

Loading

Sexual Orientation

Sensitivity: 🟠 Medium β€’ Tags: PII β€’ Occurrences: 127

Risky Dataflows:

No risky dataflows detected

Safe Dataflows:

SQL Database
  1. First detected here in utils/database.py:29:5

    gender = Column(String(50), nullable=False)
  2. Stored in SQL Database in utils/database.py:29:5

    gender = Column(String(50), nullable=False)

Visualization:

%%{init: {'flowchart': {'curve': 'linear'}}}%%
flowchart LR
de_73("<a href='#data-element-73'>Sexual Orientation</a>")
style de_73 fill:none,stroke:#808080,stroke-width:1px
file_73_a5d31205d55c70dbb753118aeba456b0("<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/database.py'>utils/database.py</a>")
style file_73_a5d31205d55c70dbb753118aeba456b0 fill:none,stroke:#808080,stroke-width:1px
de_73 --> file_73_a5d31205d55c70dbb753118aeba456b0
file_73_a5d31205d55c70dbb753118aeba456b0 --> |<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/database.py#L29-L29'>L29</a>| sink_sql_db
sink_sql_db("<a href='#data-sink-sql-db'>SQL Database</a>")
style sink_sql_db fill:#00800026,stroke:#006400,color:#006400

Loading

Vital Sign

Sensitivity: 🟠 Medium β€’ Tags: PHI β€’ Occurrences: 4

Risky Dataflows:

No risky dataflows detected

Safe Dataflows:

No safe dataflows detected

Date of Birth

Sensitivity: 🟑 Low β€’ Tags: PII β€’ Occurrences: 79

Risky Dataflows:

No risky dataflows detected

Safe Dataflows:

SQL Database
  1. First detected here in utils/database.py:28:5

    date_of_birth = Column(Date, nullable=False)
  2. Stored in SQL Database in utils/database.py:28:5

    date_of_birth = Column(Date, nullable=False)

Visualization:

%%{init: {'flowchart': {'curve': 'linear'}}}%%
flowchart LR
de_16("<a href='#data-element-16'>Date of Birth</a>")
style de_16 fill:none,stroke:#808080,stroke-width:1px
file_16_a5d31205d55c70dbb753118aeba456b0("<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/database.py'>utils/database.py</a>")
style file_16_a5d31205d55c70dbb753118aeba456b0 fill:none,stroke:#808080,stroke-width:1px
de_16 --> file_16_a5d31205d55c70dbb753118aeba456b0
file_16_a5d31205d55c70dbb753118aeba456b0 --> |<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/database.py#L28-L28'>L28</a>| sink_sql_db
sink_sql_db("<a href='#data-sink-sql-db'>SQL Database</a>")
style sink_sql_db fill:#00800026,stroke:#006400,color:#006400

Loading

Email

Sensitivity: 🟑 Low β€’ Tags: PII β€’ Occurrences: 55

Risky Dataflows:

No risky dataflows detected

Safe Dataflows:

SQL Database
  1. First detected here in utils/database.py:31:5

    email = Column(String(100))
  2. Stored in SQL Database in utils/database.py:31:5

    email = Column(String(100))

Visualization:

%%{init: {'flowchart': {'curve': 'linear'}}}%%
flowchart LR
de_20("<a href='#data-element-20'>Email</a>")
style de_20 fill:none,stroke:#808080,stroke-width:1px
file_20_a5d31205d55c70dbb753118aeba456b0("<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/database.py'>utils/database.py</a>")
style file_20_a5d31205d55c70dbb753118aeba456b0 fill:none,stroke:#808080,stroke-width:1px
de_20 --> file_20_a5d31205d55c70dbb753118aeba456b0
file_20_a5d31205d55c70dbb753118aeba456b0 --> |<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/database.py#L31-L31'>L31</a>| sink_sql_db
sink_sql_db("<a href='#data-sink-sql-db'>SQL Database</a>")
style sink_sql_db fill:#00800026,stroke:#006400,color:#006400

Loading

Emergency Contact

Sensitivity: 🟑 Low β€’ Tags: PII β€’ Occurrences: 91

Risky Dataflows:

No risky dataflows detected

Safe Dataflows:

SQL Database
  1. First detected here in utils/database.py:36:5

    emergency_contact_phone = Column(String(50))
  2. Stored in SQL Database in utils/database.py:36:5

    emergency_contact_phone = Column(String(50))

Visualization:

%%{init: {'flowchart': {'curve': 'linear'}}}%%
flowchart LR
de_21("<a href='#data-element-21'>Emergency Contact</a>")
style de_21 fill:none,stroke:#808080,stroke-width:1px
file_21_a5d31205d55c70dbb753118aeba456b0("<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/database.py'>utils/database.py</a>")
style file_21_a5d31205d55c70dbb753118aeba456b0 fill:none,stroke:#808080,stroke-width:1px
de_21 --> file_21_a5d31205d55c70dbb753118aeba456b0
file_21_a5d31205d55c70dbb753118aeba456b0 --> |<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/database.py#L36-L36'>L36</a>| sink_sql_db
sink_sql_db("<a href='#data-sink-sql-db'>SQL Database</a>")
style sink_sql_db fill:#00800026,stroke:#006400,color:#006400

Loading

First Name

Sensitivity: 🟑 Low β€’ Tags: PII β€’ Occurrences: 81

Risky Dataflows:

Logs
  1. First detected here in scripts/seed_db.py:143:9

    first_name
  2. Placed inside a string and exposed to Logs in scripts/seed_db.py:168:13

    logger.debug(f"Added patient: {first_name} {last_name}")

Safe Dataflows:

SQL Database


Occurrence #1

  1. First detected here in utils/database.py:26:5

    first_name = Column(String(100), nullable=False)
  2. Stored in SQL Database in utils/database.py:26:5

    first_name = Column(String(100), nullable=False)


Occurrence #2

  1. First detected here in utils/data_manager.py:102:33

    Patient.first_name
  2. Stored in SQL Database in utils/data_manager.py:102:22

    func.lower(Patient.first_name)

Visualization:

%%{init: {'flowchart': {'curve': 'linear'}}}%%
flowchart LR
de_27("<a href='#data-element-27'>First Name</a>")
style de_27 fill:none,stroke:#808080,stroke-width:1px
file_27_a5d31205d55c70dbb753118aeba456b0("<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/database.py'>utils/database.py</a>")
style file_27_a5d31205d55c70dbb753118aeba456b0 fill:none,stroke:#808080,stroke-width:1px
de_27 --> file_27_a5d31205d55c70dbb753118aeba456b0
file_27_a5d31205d55c70dbb753118aeba456b0 --> |<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/database.py#L26-L26'>L26</a>| sink_sql_db
file_27_f3b82eca6148dc549059de4f35e70529("<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/data_manager.py'>utils/data_manager.py</a>")
style file_27_f3b82eca6148dc549059de4f35e70529 fill:none,stroke:#808080,stroke-width:1px
de_27 --> file_27_f3b82eca6148dc549059de4f35e70529
file_27_f3b82eca6148dc549059de4f35e70529 --> |<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/data_manager.py#L102-L102'>L102</a>| sink_sql_db
file_27_1494986c7747c28afab49b7804e0927c("<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/scripts/seed_db.py'>scripts/seed_db.py</a>")
style file_27_1494986c7747c28afab49b7804e0927c fill:none,stroke:#808080,stroke-width:1px
de_27 --> file_27_1494986c7747c28afab49b7804e0927c
file_27_1494986c7747c28afab49b7804e0927c --> |<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/scripts/seed_db.py#L168-L168'>L168</a>| sink_logs
sink_logs("<a href='#data-sink-logs'>Logs</a>")
style sink_logs fill:#FF000026,stroke:#C80000,color:#C80000
sink_sql_db("<a href='#data-sink-sql-db'>SQL Database</a>")
style sink_sql_db fill:#00800026,stroke:#006400,color:#006400

Loading

Last Name

Sensitivity: 🟑 Low β€’ Tags: PII β€’ Occurrences: 78

Risky Dataflows:

Logs
  1. First detected here in scripts/seed_db.py:144:9

    last_name
  2. Placed inside a string and exposed to Logs in scripts/seed_db.py:168:13

    logger.debug(f"Added patient: {first_name} {last_name}")

Safe Dataflows:

SQL Database


Occurrence #1

  1. First detected here in utils/data_manager.py:103:35

    Patient.last_name
  2. Stored in SQL Database in utils/data_manager.py:103:24

    func.lower(Patient.last_name)


Occurrence #2

  1. First detected here in utils/database.py:27:5

    last_name = Column(String(100), nullable=False)
  2. Stored in SQL Database in utils/database.py:27:5

    last_name = Column(String(100), nullable=False)

Visualization:

%%{init: {'flowchart': {'curve': 'linear'}}}%%
flowchart LR
de_37("<a href='#data-element-37'>Last Name</a>")
style de_37 fill:none,stroke:#808080,stroke-width:1px
file_37_a5d31205d55c70dbb753118aeba456b0("<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/database.py'>utils/database.py</a>")
style file_37_a5d31205d55c70dbb753118aeba456b0 fill:none,stroke:#808080,stroke-width:1px
de_37 --> file_37_a5d31205d55c70dbb753118aeba456b0
file_37_a5d31205d55c70dbb753118aeba456b0 --> |<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/database.py#L27-L27'>L27</a>| sink_sql_db
file_37_f3b82eca6148dc549059de4f35e70529("<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/data_manager.py'>utils/data_manager.py</a>")
style file_37_f3b82eca6148dc549059de4f35e70529 fill:none,stroke:#808080,stroke-width:1px
de_37 --> file_37_f3b82eca6148dc549059de4f35e70529
file_37_f3b82eca6148dc549059de4f35e70529 --> |<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/utils/data_manager.py#L103-L103'>L103</a>| sink_sql_db
file_37_1494986c7747c28afab49b7804e0927c("<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/scripts/seed_db.py'>scripts/seed_db.py</a>")
style file_37_1494986c7747c28afab49b7804e0927c fill:none,stroke:#808080,stroke-width:1px
de_37 --> file_37_1494986c7747c28afab49b7804e0927c
file_37_1494986c7747c28afab49b7804e0927c --> |<a href='https://github.com/hounddogai/hounddog-test-python-app/blob/781c916790f5/scripts/seed_db.py#L168-L168'>L168</a>| sink_logs
sink_logs("<a href='#data-sink-logs'>Logs</a>")
style sink_logs fill:#FF000026,stroke:#C80000,color:#C80000
sink_sql_db("<a href='#data-sink-sql-db'>SQL Database</a>")
style sink_sql_db fill:#00800026,stroke:#006400,color:#006400

Loading

Data Sinks

This section lists the data sinks detected and the data elements exposed to them.

Configuration Files

Risky Dataflows:

No risky dataflows detected

Safe Dataflows:

No safe dataflows detected

Environment Variables

Risky Dataflows:

No risky dataflows detected

Safe Dataflows:

No safe dataflows detected

Files

Risky Dataflows:

No risky dataflows detected

Safe Dataflows:

No safe dataflows detected

LangChain

Risky Dataflows:

No risky dataflows detected

Safe Dataflows:

No safe dataflows detected

Logs

Risky Dataflows:

🟑 First Name
  1. First detected here in scripts/seed_db.py:143:9

    first_name
  2. Placed inside a string and exposed to Logs in scripts/seed_db.py:168:13

    logger.debug(f"Added patient: {first_name} {last_name}")
🟑 Last Name
  1. First detected here in scripts/seed_db.py:144:9

    last_name
  2. Placed inside a string and exposed to Logs in scripts/seed_db.py:168:13

    logger.debug(f"Added patient: {first_name} {last_name}")

Safe Dataflows:

No safe dataflows detected

OpenAI

Risky Dataflows:

πŸ”΄ Medical History
  1. First detected here in pages/patient.py:59:9

    medical_history
  2. Placed inside a string and assigned to 'patient_context' in pages/patient.py:284:17

    patient_context = f"""
    Patient Medical History: {medical_history}
    """
  3. Wrapped in langchain_core.messages.SystemMessage and assigned to 'messages' in pages/patient.py:308:25

    messages = [SystemMessage(content=patient_context)]
  4. Exposed to OpenAI in pages/patient.py:321:36

    llm.invoke(messages)

Safe Dataflows:

No safe dataflows detected

SQL Database

Risky Dataflows:

No risky dataflows detected

Safe Dataflows:

πŸ”΄ Medical Condition
  1. First detected here in utils/database.py:34:5

    allergies = Column(Text)
  2. Stored in SQL Database in utils/database.py:34:5

    allergies = Column(Text)
πŸ”΄ Medical History
  1. First detected here in utils/database.py:37:5

    medical_history = Column(Text)
  2. Stored in SQL Database in utils/database.py:37:5

    medical_history = Column(Text)
πŸ”΄ Medical Record Number


Occurrence #1

  1. First detected here in utils/data_manager.py:387:69

    MedicalRecord.id
  2. Stored in SQL Database in utils/data_manager.py:387:58

    func.count(MedicalRecord.id)


Occurrence #2

  1. First detected here in utils/data_manager.py:248:45

    MedicalRecord.id
  2. Stored in SQL Database in utils/data_manager.py:248:34

    func.count(MedicalRecord.id)


Occurrence #3

  1. First detected here in utils/data_manager.py:496:54

    MedicalRecord.id
  2. Stored in SQL Database in utils/data_manager.py:496:43

    func.count(MedicalRecord.id)


Occurrence #4

  1. First detected here in utils/data_manager.py:387:69

    MedicalRecord.id
  2. Stored in SQL Database in utils/data_manager.py:389:32

    func.count(MedicalRecord.id)


Occurrence #5

  1. First detected here in utils/data_manager.py:239:45

    MedicalRecord.id
  2. Stored in SQL Database in utils/data_manager.py:239:34

    func.count(MedicalRecord.id)
🟠 Blood Type
  1. First detected here in utils/database.py:33:5

    blood_type = Column(String(10))
  2. Stored in SQL Database in utils/database.py:33:5

    blood_type = Column(String(10))
🟠 Medication
  1. First detected here in utils/database.py:38:5

    current_medications = Column(Text)
  2. Stored in SQL Database in utils/database.py:38:5

    current_medications = Column(Text)
🟠 Phone Number
  1. First detected here in utils/database.py:30:5

    phone = Column(String(50))
  2. Stored in SQL Database in utils/database.py:30:5

    phone = Column(String(50))
🟠 Sexual Orientation
  1. First detected here in utils/database.py:29:5

    gender = Column(String(50), nullable=False)
  2. Stored in SQL Database in utils/database.py:29:5

    gender = Column(String(50), nullable=False)
🟑 Date of Birth
  1. First detected here in utils/database.py:28:5

    date_of_birth = Column(Date, nullable=False)
  2. Stored in SQL Database in utils/database.py:28:5

    date_of_birth = Column(Date, nullable=False)
🟑 Email
  1. First detected here in utils/database.py:31:5

    email = Column(String(100))
  2. Stored in SQL Database in utils/database.py:31:5

    email = Column(String(100))
🟑 Emergency Contact
  1. First detected here in utils/database.py:36:5

    emergency_contact_phone = Column(String(50))
  2. Stored in SQL Database in utils/database.py:36:5

    emergency_contact_phone = Column(String(50))
🟑 First Name


Occurrence #1

  1. First detected here in utils/database.py:26:5

    first_name = Column(String(100), nullable=False)
  2. Stored in SQL Database in utils/database.py:26:5

    first_name = Column(String(100), nullable=False)


Occurrence #2

  1. First detected here in utils/data_manager.py:102:33

    Patient.first_name
  2. Stored in SQL Database in utils/data_manager.py:102:22

    func.lower(Patient.first_name)
🟑 Last Name


Occurrence #1

  1. First detected here in utils/data_manager.py:103:35

    Patient.last_name
  2. Stored in SQL Database in utils/data_manager.py:103:24

    func.lower(Patient.last_name)


Occurrence #2

  1. First detected here in utils/database.py:27:5

    last_name = Column(String(100), nullable=False)
  2. Stored in SQL Database in utils/database.py:27:5

    last_name = Column(String(100), nullable=False)

SQLAlchemy

Risky Dataflows:

No risky dataflows detected

Safe Dataflows:

No safe dataflows detected

Sentry

Risky Dataflows:

🟠 Phone Number
  1. First detected here in pages/patient.py:101:33

    "phone": phone
  2. Placed inside a dictionary and exposed to Sentry in pages/patient.py:98:21

    sentry_sdk.capture_message(
        f"Failed to add patient",
        level="error",
        extras={"phone": phone},
    )

Safe Dataflows:

No safe dataflows detected

Standard Output

Risky Dataflows:

No risky dataflows detected

Safe Dataflows:

No safe dataflows detected

Risky Dataflows

This section shows vulnerable dataflows where sensitive data reaches unsafe sinks without adequate sanitization.


πŸŸ₯ CRITICAL: Medical History exposed to OpenAI in pages/patient.py:321:36:

llm.invoke(messages)
View Details

This issue was rated as πŸŸ₯ CRITICAL for exposing the following data element(s) to OpenAI:

πŸ”΄ Medical History
  1. First detected here in pages/patient.py:59:9

    medical_history
  2. Placed inside a string and assigned to 'patient_context' in pages/patient.py:284:17

    patient_context = f"""
    Patient Medical History: {medical_history}
    """
  3. Wrapped in langchain_core.messages.SystemMessage and assigned to 'messages' in pages/patient.py:308:25

    messages = [SystemMessage(content=patient_context)]
  4. Exposed to OpenAI in pages/patient.py:321:36

    llm.invoke(messages)

Remediation:

Remove the offending code or sanitize the data.

For auto-closing vulnerabilities, see https://docs.hounddog.ai/scanner/remediation.

Compliance Frameworks: CWE-201, A01:2021, GDPR-A5-28, CCPA, HIPAA, NIST-800-53


🟧 MEDIUM: Phone Number exposed to Sentry in pages/patient.py:98:21:

sentry_sdk.capture_message(
    f"Failed to add patient",
    level="error",
    extras={"phone": phone},
)
View Details

This issue was rated as 🟧 MEDIUM for exposing the following data element(s) to Sentry:

🟠 Phone Number
  1. First detected here in pages/patient.py:101:33

    "phone": phone
  2. Placed inside a dictionary and exposed to Sentry in pages/patient.py:98:21

    sentry_sdk.capture_message(
        f"Failed to add patient",
        level="error",
        extras={"phone": phone},
    )

Remediation:

Remove the offending code or sanitize the data.

For auto-closing vulnerabilities, see https://docs.hounddog.ai/scanner/remediation.

Compliance Frameworks: CWE-201, A01:2021, GDPR-A5-28, CCPA, NIST-800-53


🟨 LOW: First Name and Last Name exposed to Logs in scripts/seed_db.py:168:13:

logger.debug(f"Added patient: {first_name} {last_name}")
View Details

This issue was rated as 🟨 LOW for exposing the following data element(s) to Logs:

🟑 First Name
  1. First detected here in scripts/seed_db.py:143:9

    first_name
  2. Placed inside a string and exposed to Logs in scripts/seed_db.py:168:13

    logger.debug(f"Added patient: {first_name} {last_name}")
🟑 Last Name
  1. First detected here in scripts/seed_db.py:144:9

    last_name
  2. Placed inside a string and exposed to Logs in scripts/seed_db.py:168:13

    logger.debug(f"Added patient: {first_name} {last_name}")

Remediation:

Remove the offending code or sanitize the data.

For auto-closing vulnerabilities, see https://docs.hounddog.ai/scanner/remediation.

Compliance Frameworks: CWE-532, A09:2021, GDPR-A5-32, CCPA, NIST-800-53

Safe Dataflows

This section shows dataflows where sensitive data reaches safe sinks or is properly sanitized.


🟩 INFO: First Name stored in SQL Database in utils/database.py:26:5:

first_name = Column(String(100), nullable=False)
View Details

This issue was rated as 🟩 INFO for exposing the following data element(s) to SQL Database:

🟑 First Name
  1. First detected here in utils/database.py:26:5

    first_name = Column(String(100), nullable=False)
  2. Stored in SQL Database in utils/database.py:26:5

    first_name = Column(String(100), nullable=False)

🟩 INFO: Medical Record Number stored in SQL Database in utils/data_manager.py:387:58:

func.count(MedicalRecord.id)
View Details

This issue was rated as 🟩 INFO for exposing the following data element(s) to SQL Database:

πŸ”΄ Medical Record Number
  1. First detected here in utils/data_manager.py:387:69

    MedicalRecord.id
  2. Stored in SQL Database in utils/data_manager.py:387:58

    func.count(MedicalRecord.id)

🟩 INFO: Date of Birth stored in SQL Database in utils/database.py:28:5:

date_of_birth = Column(Date, nullable=False)
View Details

This issue was rated as 🟩 INFO for exposing the following data element(s) to SQL Database:

🟑 Date of Birth
  1. First detected here in utils/database.py:28:5

    date_of_birth = Column(Date, nullable=False)
  2. Stored in SQL Database in utils/database.py:28:5

    date_of_birth = Column(Date, nullable=False)

🟩 INFO: Medical Record Number stored in SQL Database in utils/data_manager.py:248:34:

func.count(MedicalRecord.id)
View Details

This issue was rated as 🟩 INFO for exposing the following data element(s) to SQL Database:

πŸ”΄ Medical Record Number
  1. First detected here in utils/data_manager.py:248:45

    MedicalRecord.id
  2. Stored in SQL Database in utils/data_manager.py:248:34

    func.count(MedicalRecord.id)

🟩 INFO: Medical Record Number stored in SQL Database in utils/data_manager.py:496:43:

func.count(MedicalRecord.id)
View Details

This issue was rated as 🟩 INFO for exposing the following data element(s) to SQL Database:

πŸ”΄ Medical Record Number
  1. First detected here in utils/data_manager.py:496:54

    MedicalRecord.id
  2. Stored in SQL Database in utils/data_manager.py:496:43

    func.count(MedicalRecord.id)

🟩 INFO: Medical Condition stored in SQL Database in utils/database.py:34:5:

allergies = Column(Text)
View Details

This issue was rated as 🟩 INFO for exposing the following data element(s) to SQL Database:

πŸ”΄ Medical Condition
  1. First detected here in utils/database.py:34:5

    allergies = Column(Text)
  2. Stored in SQL Database in utils/database.py:34:5

    allergies = Column(Text)

🟩 INFO: First Name stored in SQL Database in utils/data_manager.py:102:22:

func.lower(Patient.first_name)
View Details

This issue was rated as 🟩 INFO for exposing the following data element(s) to SQL Database:

🟑 First Name
  1. First detected here in utils/data_manager.py:102:33

    Patient.first_name
  2. Stored in SQL Database in utils/data_manager.py:102:22

    func.lower(Patient.first_name)

🟩 INFO: Medical Record Number stored in SQL Database in utils/data_manager.py:389:32:

func.count(MedicalRecord.id)
View Details

This issue was rated as 🟩 INFO for exposing the following data element(s) to SQL Database:

πŸ”΄ Medical Record Number
  1. First detected here in utils/data_manager.py:387:69

    MedicalRecord.id
  2. Stored in SQL Database in utils/data_manager.py:389:32

    func.count(MedicalRecord.id)

🟩 INFO: Medical Record Number stored in SQL Database in utils/data_manager.py:239:34:

func.count(MedicalRecord.id)
View Details

This issue was rated as 🟩 INFO for exposing the following data element(s) to SQL Database:

πŸ”΄ Medical Record Number
  1. First detected here in utils/data_manager.py:239:45

    MedicalRecord.id
  2. Stored in SQL Database in utils/data_manager.py:239:34

    func.count(MedicalRecord.id)

🟩 INFO: Last Name stored in SQL Database in utils/data_manager.py:103:24:

func.lower(Patient.last_name)
View Details

This issue was rated as 🟩 INFO for exposing the following data element(s) to SQL Database:

🟑 Last Name
  1. First detected here in utils/data_manager.py:103:35

    Patient.last_name
  2. Stored in SQL Database in utils/data_manager.py:103:24

    func.lower(Patient.last_name)

🟩 INFO: Phone Number stored in SQL Database in utils/database.py:30:5:

phone = Column(String(50))
View Details

This issue was rated as 🟩 INFO for exposing the following data element(s) to SQL Database:

🟠 Phone Number
  1. First detected here in utils/database.py:30:5

    phone = Column(String(50))
  2. Stored in SQL Database in utils/database.py:30:5

    phone = Column(String(50))

🟩 INFO: Medical History stored in SQL Database in utils/database.py:37:5:

medical_history = Column(Text)
View Details

This issue was rated as 🟩 INFO for exposing the following data element(s) to SQL Database:

πŸ”΄ Medical History
  1. First detected here in utils/database.py:37:5

    medical_history = Column(Text)
  2. Stored in SQL Database in utils/database.py:37:5

    medical_history = Column(Text)

🟩 INFO: Emergency Contact stored in SQL Database in utils/database.py:36:5:

emergency_contact_phone = Column(String(50))
View Details

This issue was rated as 🟩 INFO for exposing the following data element(s) to SQL Database:

🟑 Emergency Contact
  1. First detected here in utils/database.py:36:5

    emergency_contact_phone = Column(String(50))
  2. Stored in SQL Database in utils/database.py:36:5

    emergency_contact_phone = Column(String(50))

🟩 INFO: Blood Type stored in SQL Database in utils/database.py:33:5:

blood_type = Column(String(10))
View Details

This issue was rated as 🟩 INFO for exposing the following data element(s) to SQL Database:

🟠 Blood Type
  1. First detected here in utils/database.py:33:5

    blood_type = Column(String(10))
  2. Stored in SQL Database in utils/database.py:33:5

    blood_type = Column(String(10))

🟩 INFO: Email stored in SQL Database in utils/database.py:31:5:

email = Column(String(100))
View Details

This issue was rated as 🟩 INFO for exposing the following data element(s) to SQL Database:

🟑 Email
  1. First detected here in utils/database.py:31:5

    email = Column(String(100))
  2. Stored in SQL Database in utils/database.py:31:5

    email = Column(String(100))

🟩 INFO: Medication stored in SQL Database in utils/database.py:38:5:

current_medications = Column(Text)
View Details

This issue was rated as 🟩 INFO for exposing the following data element(s) to SQL Database:

🟠 Medication
  1. First detected here in utils/database.py:38:5

    current_medications = Column(Text)
  2. Stored in SQL Database in utils/database.py:38:5

    current_medications = Column(Text)

🟩 INFO: Last Name stored in SQL Database in utils/database.py:27:5:

last_name = Column(String(100), nullable=False)
View Details

This issue was rated as 🟩 INFO for exposing the following data element(s) to SQL Database:

🟑 Last Name
  1. First detected here in utils/database.py:27:5

    last_name = Column(String(100), nullable=False)
  2. Stored in SQL Database in utils/database.py:27:5

    last_name = Column(String(100), nullable=False)

🟩 INFO: Sexual Orientation stored in SQL Database in utils/database.py:29:5:

gender = Column(String(50), nullable=False)
View Details

This issue was rated as 🟩 INFO for exposing the following data element(s) to SQL Database:

🟠 Sexual Orientation
  1. First detected here in utils/database.py:29:5

    gender = Column(String(50), nullable=False)
  2. Stored in SQL Database in utils/database.py:29:5

    gender = Column(String(50), nullable=False)

Remediation Strategy

Avoid sending sensitive data to unsafe data sinks, even during development and testing. For third parties, the shared data must align with your privacy notice and data processing agreement. Adjust or restrict sharing as necessary to maintain compliance and minimize privacy risks. For more straightforward sinks like logs, the recommendation is to remove the offending code entirely. For auto-closing vulnerabilities, see https://docs.hounddog.ai/scanner/remediation.