mrheinen / lophiid

A distributed honeypot for monitoring large scale web attacks
GNU General Public License v2.0
6 stars 1 forks source link

Update app import mechanism #41

Closed mrheinen closed 1 month ago

mrheinen commented 1 month ago

User description

Make it more robust and move from JSON to YAML to make the files more human readable. Also add some app exports to the github report and update the CLI to allow importing of individual apps or entire directories.


PR Type

Enhancement, Bug fix, Documentation


Description


Changes walkthrough πŸ“

Relevant files
Enhancement
15 files
database.go
Enhance database models and operations for YAML support   

pkg/database/database.go
  • Added YammableBytes type for YAML marshalling of content data
  • Updated Content, ContentRule, and Application structs with new fields
    and YAML tags
  • Added SetExternalUuid method to ExternalDataModel interface
  • Implemented InsertExternalModel method in KSQLClient
  • Updated HandleUploadFile to handle ErrRecordNotFound error
  • +126/-72
    server.go
    Implement YAML-based app export and import                             

    pkg/api/server.go
  • Updated HandleUpsertSingleContentRule to set ContentUuid and AppUuid
  • Modified ExportAppWithContentAndRule to use YAML for export
  • Implemented ImportAppWithContentAndRule for YAML-based app imports
  • Added error handling for invalid UUIDs during import
  • +175/-27
    api_client.go
    Add app import functionality to API client                             

    cmd/api_client/api_client.go
  • Added app import functionality for single files and directories
  • Implemented recursive file search for directory imports
  • Updated main function to handle new import flags
  • +53/-2   
    generic_client.go
    Add import functionality to API client                                     

    pkg/api/generic_client.go
  • Renamed file from client.go to generic_client.go
  • Added Import method to ApiClient interface
  • Implemented Import method in GenericApiClient
  • +44/-1   
    cli.go
    Add ImportApp method to CLI                                                           

    pkg/api/cli/cli.go - Added ImportApp method for importing apps from YAML files
    +15/-0   
    general.go
    Add UUID validation utility function                                         

    pkg/util/general.go - Added IsValidUUID function for UUID validation
    +8/-0     
    AppForm.vue
    Enhance AppForm with CVEs and UUID display                             

    ui/src/components/container/AppForm.vue
  • Added CVEs input field
  • Implemented UUID display
  • Updated app export to use YAML format
  • +65/-3   
    RuleForm.vue
    Add UUID display to RuleForm                                                         

    ui/src/components/container/RuleForm.vue - Added UUID display field for rules
    +29/-15 
    AppsList.vue
    Enhance AppsList with rule links and date formatting         

    ui/src/components/container/AppsList.vue
  • Added link to view rules for each app
  • Imported dateToString function from helpers
  • +10/-4   
    ContentList.vue
    Update ContentList to use parsed names and helper functions

    ui/src/components/container/ContentList.vue
  • Updated to use parsed.name for content display
  • Imported truncateString and dateToString from helpers
  • +6/-5     
    RulesList.vue
    Update RulesList to use UUIDs and helper functions             

    ui/src/components/container/RulesList.vue
  • Updated link to use rule_uuid instead of rule_id
  • Imported truncateString and dateToString from helpers
  • +4/-12   
    ImportAppForm.vue
    Enhance ImportAppForm with YAML support and API key usage

    ui/src/components/container/ImportAppForm.vue
  • Added file type restriction to YAML files
  • Updated import process to use API key
  • +5/-1     
    ContentForm.vue
    Add UUID display to ContentForm                                                   

    ui/src/components/container/ContentForm.vue - Added UUID display field for content
    +14/-0   
    helpers.js
    Add string truncation and date formatting helpers               

    ui/src/helpers.js - Added truncateString and dateToString helper functions
    +10/-0   
    database.sql
    Update database schema for UUIDs and CVEs                               

    config/database.sql
  • Removed is_default column from content table
  • Added rule_uuid column to request table
  • Removed host column from content_rule table
  • Added app_uuid and content_uuid columns to content_rule table
  • Added cves column to app table
  • +9/-7     
    Bug fix
    1 files
    backend.go
    Update backend handling for file uploads and probes           

    pkg/backend/backend.go
  • Updated HandleUploadFile to handle ErrRecordNotFound error
  • Added RuleUuid field to HandleProbe function
  • +3/-2     
    Tests
    2 files
    general_test.go
    Add tests for UUID validation                                                       

    pkg/util/general_test.go - Added new file with tests for IsValidUUID function
    +45/-0   
    generic_client_test.go
    Update API client tests for import functionality                 

    pkg/api/generic_client_test.go
  • Renamed file from client_test.go to generic_client_test.go
  • Added test for Import method
  • +20/-1   
    Documentation
    4 files
    Geoserver-2.x.yaml
    Add Geoserver 2.x rules                                                                   

    rules/Geoserver-2.x.yaml - Added new YAML file for Geoserver 2.x rules
    +261/-0 
    phpunit-4.8.28.yaml
    Add phpunit 4.8.28 rules                                                                 

    rules/phpunit-4.8.28.yaml - Added new YAML file for phpunit 4.8.28 rules
    +69/-0   
    API_CLIENT.md
    Add documentation for app import functionality                     

    API_CLIENT.md
  • Added documentation for importing previously exported apps
  • Provided examples for importing single apps and directories
  • +38/-1   
    SEARCH_KEYWORDS.md
    Update search keywords documentation                                         

    SEARCH_KEYWORDS.md
  • Added rule_uuid to request search keywords
  • Updated content and content_rule search keywords
  • Added cves to app search keywords
  • +5/-1     
    Configuration changes
    3 files
    BUILD.bazel
    Update Bazel build file for API changes                                   

    pkg/api/BUILD.bazel - Updated file names and dependencies for API changes
    +6/-2     
    BUILD.bazel
    Update Bazel build file for database changes                         

    pkg/database/BUILD.bazel - Added new dependencies for UUID and YAML support
    +2/-0     
    BUILD.bazel
    Update Bazel build file for utility tests                               

    pkg/util/BUILD.bazel - Added general_test.go to test sources
    +1/-0     
    Additional files (token-limit)
    1 files
    TeamCity-2023.11.3.yaml
    ...                                                                                                           

    rules/TeamCity-2023.11.3.yaml ...
    +477/-0 

    πŸ’‘ PR-Agent usage: Comment /help on the PR to get a list of all available PR-Agent tools and their descriptions

    github-actions[bot] commented 1 month ago

    Preparing PR description...

    github-actions[bot] commented 1 month ago

    Preparing review...

    codiumai-pr-agent-pro[bot] commented 1 month ago

    PR Reviewer Guide πŸ”

    ⏱️ Estimated effort to review: 4 πŸ”΅πŸ”΅πŸ”΅πŸ”΅βšͺ
    πŸ§ͺ No relevant tests
    πŸ”’ Security concerns

    Sensitive information exposure:
    The new import/export functionality in `pkg/api/server.go` and `cmd/api_client/api_client.go` could potentially expose sensitive information if not properly secured. The code should be carefully reviewed to ensure that only authorized users can import/export data and that the exported data does not contain any unintended sensitive information.
    ⚑ Key issues to review

    Data Model Changes
    Significant changes to data models (Content, ContentRule, Application) including new fields and YAML serialization. This needs careful review to ensure data integrity and backwards compatibility. Import/Export Logic
    New import and export functionality for apps, rules, and contents. This needs thorough review to ensure data consistency and security during import/export operations. New CLI Functionality
    Added functionality for importing apps from files or directories. This needs review for proper error handling and security considerations when processing external files.
    codiumai-pr-agent-pro[bot] commented 1 month ago

    PR Code Suggestions ✨

    CategorySuggestion                                                                                                                                    Score
    Best practice
    Use a database transaction to ensure atomicity when importing and deleting data ___ **In the ImportAppWithContentAndRule function, consider using a transaction to ensure
    atomicity when inserting new data and deleting old data. This will prevent partial
    updates in case of errors during the process.** [pkg/api/server.go [1014-1140]](https://github.com/mrheinen/lophiid/pull/41/files#diff-734f9c34b34af099d24da13054e167f7df72706dc733edf21c61c0cc1548224aR1014-R1140) ```diff func (a *ApiServer) ImportAppWithContentAndRule(w http.ResponseWriter, req *http.Request) { var ae AppExport body, err := io.ReadAll(req.Body) if err != nil { a.sendStatus(w, err.Error(), ResultError, nil) return } if err = yaml.Unmarshal(body, &ae); err != nil { a.sendStatus(w, err.Error(), ResultError, nil) return } - // ... (rest of the function) + err = a.dbc.Transaction(func(tx *ksql.Tx) error { + // ... (rest of the function, using tx instead of a.dbc) + return nil + }) + + if err != nil { + a.sendStatus(w, err.Error(), ResultError, nil) + return + } a.sendStatus(w, "", ResultSuccess, nil) } ``` - [ ] **Apply this suggestion**
    Suggestion importance[1-10]: 9 Why: Using a transaction is a crucial best practice for ensuring data consistency, especially when performing multiple database operations that should be atomic.
    9
    Error handling
    βœ… Add error handling for HTTP response status code in the Import method ___
    Suggestion Impact:The commit implemented error handling for HTTP response status codes as suggested, with a slight modification in the error message. code diff: ```diff + if res.StatusCode != http.StatusOK { + return fmt.Errorf("got HTTP error code: %d", res.StatusCode) + } ```
    ___ **Consider adding error handling for the HTTP response status code in the Import
    method. This will help catch and handle unexpected server responses.** [pkg/api/generic_client.go [224-229]](https://github.com/mrheinen/lophiid/pull/41/files#diff-86e55a1fed585a7ea411843626b016f0b710653997dad82e66885fb40deef5f9R224-R229) ```diff res, err := a.httpClient.Do(req) if err != nil { return fmt.Errorf("while submitting: %s", err) } - defer res.Body.Close() +if res.StatusCode != http.StatusOK { + return fmt.Errorf("unexpected status code: %d", res.StatusCode) +} + ``` - [ ] **Apply this suggestion**
    Suggestion importance[1-10]: 9 Why: Adding error handling for HTTP response status codes is essential for proper error management and can prevent silent failures in the Import method.
    9
    Enhancement
    Add a check for empty value in the UnmarshalYAML method to handle potential empty or null values ___ **In the UnmarshalYAML method, consider adding a check for empty value before
    attempting to decode, to prevent potential errors when dealing with empty or null
    values.** [pkg/database/database.go [71-79]](https://github.com/mrheinen/lophiid/pull/41/files#diff-1adb887d06a44193c36fc1c5708be385f3129cd59c2f2aa555faa065941ed877R71-R79) ```diff func (yb *YammableBytes) UnmarshalYAML(node *yaml.Node) error { value := node.Value + if value == "" { + *yb = nil + return nil + } ba, err := base64.StdEncoding.DecodeString(value) if err != nil { return err } *yb = ba return nil } ``` - [ ] **Apply this suggestion**
    Suggestion importance[1-10]: 8 Why: This enhancement improves error handling and prevents potential issues when dealing with empty or null values, increasing the robustness of the code.
    8
    Add a test case for empty or invalid import data ___ **Consider adding a test case for when the import data is empty or invalid. This will
    help ensure the import functionality handles edge cases correctly.** [pkg/api/server_test.go [379-389]](https://github.com/mrheinen/lophiid/pull/41/files#diff-c1b7ac336704ec14ba929be928d0348b2817bd747a0056fdb8a437903486435dR379-R389) ```diff for _, test := range []struct { description string appID int app database.Application contentRules []database.ContentRule contents map[int64]database.Content expectedStatus string expectedNrApps int expectedNrRules int expectedNrContents int }{ + // ... existing test cases ... + { + description: "empty import data", + appID: 0, + app: database.Application{}, + contentRules: []database.ContentRule{}, + contents: map[int64]database.Content{}, + expectedStatus: ResultError, + expectedNrApps: 0, + expectedNrRules: 0, + expectedNrContents: 0, + }, ```
    Suggestion importance[1-10]: 8 Why: Adding a test case for empty or invalid import data is crucial for ensuring the robustness of the import functionality, covering important edge cases.
    8
    Add a severity field to each rule to indicate the level of risk ___ **Consider adding a severity field to each rule to indicate the level of risk or
    importance associated with each request.** [rules/TeamCity-2023.11.3.yaml [15-31]](https://github.com/mrheinen/lophiid/pull/41/files#diff-3a7ad09593c538a216e9856a43ed1e4273dbd50cb1aec6e0c023320f5adfa5adR15-R31) ```diff - id: 250 uri: /hax?jsp=/app/rest/debug/jvm/systemProperties;.jsp method: GET port: 0 uri_matching: exact body_matching: none content_id: 255 app_id: 103 app_uuid: 6cbb2aae-92f8-4cec-a493-9885d2c0aa98 content_uuid: 3c0c972f-fd28-4984-ab77-0552bd767be0 created_at: 2024-07-01T14:36:00.371465Z updated_at: 2024-08-31T16:18:03.700405Z alert: false ext_version: 1 ext_uuid: 98a32d7d-98c2-4d3c-a2f7-fd1080732f68 request_purpose: ATTACK + severity: high ``` - [ ] **Apply this suggestion**
    Suggestion importance[1-10]: 8 Why: Including a severity field for each rule is crucial for prioritizing and assessing the potential impact of different security issues.
    8
    Rename the custom type to better reflect its purpose and encoding behavior ___ **Consider using a more descriptive name for the YammableBytes type, such as
    Base64EncodedBytes, to better reflect its purpose and encoding behavior.** [pkg/database/database.go [65]](https://github.com/mrheinen/lophiid/pull/41/files#diff-1adb887d06a44193c36fc1c5708be385f3129cd59c2f2aa555faa065941ed877R65-R65) ```diff -type YammableBytes []byte +type Base64EncodedBytes []byte ``` - [ ] **Apply this suggestion**
    Suggestion importance[1-10]: 7 Why: The suggested name 'Base64EncodedBytes' is more descriptive and clearly indicates the encoding used, improving code readability and understanding.
    7
    Add error handling for the case when no rules are found for the given app ID during export ___ **In the ExportAppWithContentAndRule function, consider adding error handling for the
    case when no rules are found for the given app ID. This will provide better feedback
    to the user when exporting an app without any associated rules.** [pkg/api/server.go [930-954]](https://github.com/mrheinen/lophiid/pull/41/files#diff-734f9c34b34af099d24da13054e167f7df72706dc733edf21c61c0cc1548224aR930-R954) ```diff func (a *ApiServer) ExportAppWithContentAndRule(w http.ResponseWriter, req *http.Request) { appID, err := strconv.ParseInt(req.URL.Query().Get("app_id"), 10, 64) if err != nil { a.sendStatus(w, err.Error(), ResultError, nil) return } app, err := a.dbc.GetAppByID(appID) if err != nil { a.sendStatus(w, err.Error(), ResultError, nil) return } rules, err := a.dbc.SearchContentRules(0, 254, fmt.Sprintf("app_id:%d", appID)) if err != nil { a.sendStatus(w, err.Error(), ResultError, nil) return } + if len(rules) == 0 { + a.sendStatus(w, "No rules found for the given app ID", ResultError, nil) + return + } + // ... (rest of the function) } ``` - [ ] **Apply this suggestion**
    Suggestion importance[1-10]: 7 Why: This enhancement improves user feedback and error handling, making the API more robust and user-friendly.
    7
    Use a map for test cases to improve readability and maintainability ___ **Consider using a map for the test cases instead of a slice of structs. This can
    improve readability and make it easier to add or modify test cases.** [pkg/api/server_test.go [379-389]](https://github.com/mrheinen/lophiid/pull/41/files#diff-c1b7ac336704ec14ba929be928d0348b2817bd747a0056fdb8a437903486435dR379-R389) ```diff -for _, test := range []struct { - description string +testCases := map[string]struct { appID int app database.Application contentRules []database.ContentRule contents map[int64]database.Content expectedStatus string expectedNrApps int expectedNrRules int expectedNrContents int }{ +for name, test := range testCases { ``` - [ ] **Apply this suggestion**
    Suggestion importance[1-10]: 7 Why: Using a map for test cases can improve code organization and make it easier to add or modify test cases, enhancing maintainability.
    7
    Add a description field to provide more context about the application ___ **Consider adding a description field to the app section to provide more context about
    the TeamCity application and its purpose.** [rules/TeamCity-2023.11.3.yaml [1-11]](https://github.com/mrheinen/lophiid/pull/41/files#diff-3a7ad09593c538a216e9856a43ed1e4273dbd50cb1aec6e0c023320f5adfa5adR1-R11) ```diff app: id: 103 name: TeamCity version: 2023.11.3 vendor: Jetbrains os: Linux link: https://www.jetbrains.com/teamcity/ + description: TeamCity is a continuous integration and deployment server developed by JetBrains. created_at: 2024-07-01T11:30:46.706905Z updated_at: 2024-09-13T18:55:27.530016Z ext_version: 1 ext_uuid: 6cbb2aae-92f8-4cec-a493-9885d2c0aa98 ``` - [ ] **Apply this suggestion**
    Suggestion importance[1-10]: 7 Why: Adding a description field enhances the metadata and provides valuable context about the application, improving overall documentation.
    7
    Add a description field to each rule to explain its purpose ___ **Consider adding a brief description field to each rule to explain its purpose or the
    type of attack/reconnaissance it's designed to detect.** [rules/TeamCity-2023.11.3.yaml [15-31]](https://github.com/mrheinen/lophiid/pull/41/files#diff-3a7ad09593c538a216e9856a43ed1e4273dbd50cb1aec6e0c023320f5adfa5adR15-R31) ```diff - id: 250 uri: /hax?jsp=/app/rest/debug/jvm/systemProperties;.jsp method: GET port: 0 uri_matching: exact body_matching: none content_id: 255 app_id: 103 app_uuid: 6cbb2aae-92f8-4cec-a493-9885d2c0aa98 content_uuid: 3c0c972f-fd28-4984-ab77-0552bd767be0 created_at: 2024-07-01T14:36:00.371465Z updated_at: 2024-08-31T16:18:03.700405Z alert: false ext_version: 1 ext_uuid: 98a32d7d-98c2-4d3c-a2f7-fd1080732f68 request_purpose: ATTACK + description: Detects attempts to access system properties through the debug API, which could be used for information disclosure. ``` - [ ] **Apply this suggestion**
    Suggestion importance[1-10]: 7 Why: Adding descriptions to rules enhances understanding and maintainability, providing valuable context for each security check.
    7
    Input validation
    Improve CVE input validation to provide better feedback on invalid entries ___ **Consider adding input validation for the CVEs field to ensure that each entered CVE
    is valid before submitting the form.** [ui/src/components/container/AppForm.vue [201-221]](https://github.com/mrheinen/lophiid/pull/41/files#diff-7a86a79cacd17318733502cc0b9c4c47eb430bbbe709a2919410b5e12313c742R201-R221) ```diff appToSubmit.cves = [] if (this.cves != "") { var allCves = this.cves.split("\n"); - if (!allCves || allCves.length == 0) { - if (!isCVE(this.cves)) { - this.$toast.error("Please provide a valid CVE"); - return - } - allCves.push(this.cves); - } + var invalidCves = []; allCves.forEach((cve) => { + cve = cve.trim(); if (cve != "") { - if (!isCVE(this.cves)) { - this.$toast.error("Please provide valid CVEs"); - return + if (isCVE(cve)) { + appToSubmit.cves.push(cve); + } else { + invalidCves.push(cve); } - appToSubmit.cves.push(cve); } }); + + if (invalidCves.length > 0) { + this.$toast.error(`Invalid CVEs: ${invalidCves.join(", ")}`); + return; + } } ``` - [ ] **Apply this suggestion**
    Suggestion importance[1-10]: 8 Why: Enhancing CVE input validation improves user experience by providing more specific feedback on invalid entries and prevents submission of incorrect data.
    8
    Maintainability
    Group similar rules together using a common prefix or categorization ___ **Consider grouping similar rules together using a common prefix or categorization to
    improve organization and readability.** [rules/TeamCity-2023.11.3.yaml [14-46]](https://github.com/mrheinen/lophiid/pull/41/files#diff-3a7ad09593c538a216e9856a43ed1e4273dbd50cb1aec6e0c023320f5adfa5adR14-R46) ```diff rules: - - id: 250 + - id: attack_250 + category: rest_api_attack uri: /hax?jsp=/app/rest/debug/jvm/systemProperties;.jsp method: GET port: 0 uri_matching: exact body_matching: none content_id: 255 app_id: 103 app_uuid: 6cbb2aae-92f8-4cec-a493-9885d2c0aa98 content_uuid: 3c0c972f-fd28-4984-ab77-0552bd767be0 created_at: 2024-07-01T14:36:00.371465Z updated_at: 2024-08-31T16:18:03.700405Z alert: false ext_version: 1 ext_uuid: 98a32d7d-98c2-4d3c-a2f7-fd1080732f68 request_purpose: ATTACK - - id: 263 + - id: attack_263 + category: rest_api_attack uri: /hax?jsp=/app/rest/users;.jsp method: GET port: 0 uri_matching: exact body_matching: none content_id: 268 app_id: 103 app_uuid: 6cbb2aae-92f8-4cec-a493-9885d2c0aa98 content_uuid: 78315a54-8016-49db-b2ca-edcca49b72e6 created_at: 2024-07-01T14:43:54.618738Z updated_at: 2024-08-31T16:17:50.709303Z alert: false ext_version: 1 ext_uuid: 3bbf7b99-3498-4e49-a393-df26746bd26f request_purpose: ATTACK ``` - [ ] **Apply this suggestion**
    Suggestion importance[1-10]: 6 Why: Grouping similar rules improves organization and readability, but it's not as critical as addressing security concerns directly.
    6