Skip to content

Vulnerable sample for Action test#2

Open
souro1212 wants to merge 1 commit into
mainfrom
feat/vuln-demo-1757571352
Open

Vulnerable sample for Action test#2
souro1212 wants to merge 1 commit into
mainfrom
feat/vuln-demo-1757571352

Conversation

@souro1212
Copy link
Copy Markdown
Member

@souro1212 souro1212 commented Sep 11, 2025

This PR intentionally adds risky patterns for testing ai-secure-code-review-action.

Summary by CodeRabbit

  • New Features
    • Introduces a lightweight HTTP service listening on port 8080.
    • Adds an endpoint that returns the 32‑character MD5 hash of a server‑stored file.
    • The file to hash is selected via a query parameter, enabling quick checksum retrieval for existing files.
    • Designed for simple, on-demand integrity checks from a browser or HTTP client.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Sep 11, 2025

Walkthrough

Introduces an HTTP server in Go exposing GET /read. The handler reads the query parameter file, loads ./data/, computes its MD5 checksum, and writes the 32-hex digest to the response. The server listens on :8080. File I/O errors are not handled in the handler.

Changes

Cohort / File(s) Summary
HTTP server and MD5 endpoint
main.go
Replace placeholder with an HTTP server. Add /read handler that parses query param file, reads ./data/, computes md5.Sum, writes hex digest, and starts http.ListenAndServe(":8080", nil).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Client
  participant Server as HTTP Server (:8080)
  participant FS as Filesystem (./data)
  participant MD5 as MD5

  Client->>Server: GET /read?file=<name>
  Server->>Server: Parse query param "file"
  Server->>FS: Read ./data/<file>
  FS-->>Server: []byte contents
  Server->>MD5: md5.Sum(contents)
  MD5-->>Server: 16-byte digest
  Server->>Server: Format 32-hex string
  Server-->>Client: 200 OK with hex digest
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Pre-merge checks (2 passed, 1 warning)

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "Vulnerable sample for Action test" is concise and directly reflects the PR objective of adding an intentionally vulnerable example for testing; it aligns with the changes that introduce an unsafe /read HTTP endpoint that reads server-side files and returns MD5 digests, so a reviewer can understand the primary intent at a glance.

Poem

I hopped to port eight-zero-eight,
Served checksums swift, a crunchy fate.
A nibble of bytes, a hex-y treat,
From data burrows, snug and neat.
With whisker-twitch, I hash and greet—
“MD5 delivered!”—then thump my feet.

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.

✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/vuln-demo-1757571352

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

🔐 Secure Code Review (AI)

Risk Summary: High (3), Medium (1)

  1. Finding: Path Traversal Vulnerability
    Why it matters: The code allows users to specify a file path via the query parameter, which can lead to unauthorized access to sensitive files on the server.
    Evidence (diff lines): file := r.URL.Query().Get("file") and ioutil.ReadFile("./data/" + file)
    Fix (concrete): Validate the file parameter to ensure it does not contain path traversal characters (e.g., ..). Consider using a whitelist of allowed filenames.

  2. Finding: Insecure Handling of Errors
    Why it matters: The code ignores errors from ioutil.ReadFile, which can lead to a denial of service (DoS) if the file does not exist or cannot be read.
    Evidence (diff lines): b, _ := ioutil.ReadFile("./data/" + file)
    Fix (concrete): Handle the error properly by checking if err is not nil and returning an appropriate HTTP error response.

  3. Finding: Exposure of Weak Cryptographic Hash
    Why it matters: MD5 is considered weak and vulnerable to collision attacks. Using it for integrity checks or security purposes is not recommended.
    Evidence (diff lines): fmt.Fprintf(w, "%x", md5.Sum(b))
    Fix (concrete): Replace MD5 with a stronger hashing algorithm such as SHA-256 (using crypto/sha256).

Safeguards Checklist:

  • Input validation: Fail
  • Error handling: Fail
  • Use of strong cryptography: Fail
  • Secure file access: Fail

This diff is not truncated, but it introduces several critical security issues that need to be addressed to ensure the application is secure.


Models can make mistakes. Verify before merging.

@secure-code-warrior-for-github
Copy link
Copy Markdown

Micro-Learning Topic: Weak cryptographic algorithm (Detected by phrase)

Matched on "Weak Cryptographic Hash"

What is this? (2min video)

As computing power and availability increases, cryptographic algorithms are periodically updated to ensure that these increases do not allow brute force attacks to succeed. Furthermore, ongoing cryptography research will often identify flaws in existing algorithms that weaken their security. Use of weak or outdated algorithms to protect sensitive data places it at risk because encryption weaknesses, hashing or signature algorithms can result in the protection being undone.

Try a challenge in Secure Code Warrior

Helpful references

Micro-Learning Topic: Denial of service (Detected by phrase)

Matched on "denial of service"

The Denial of Service (DoS) attack is focused on making a resource (site, application, server) unavailable for the purpose it was designed. There are many ways to make a service unavailable for legitimate users by manipulating network packets, programming, logical, or resources handling vulnerabilities, among others. Source: https://www.owasp.org/index.php/Denial_of_Service

Try a challenge in Secure Code Warrior

Micro-Learning Topic: Path traversal (Detected by phrase)

Matched on "Path Traversal"

What is this? (2min video)

Path traversal vulnerabilities occur when inputs that have not been sufficiently validated or sanitised are used to build directory or file paths. If an attacker can influence the path being accessed by the server, they may be able to gain unauthorised access to files or even execute arbitrary code on the server (when coupled with file upload functionality).

Try a challenge in Secure Code Warrior

Helpful references
  • OWASP Input Validation Cheat Sheet - This cheatsheet is focused on providing clear, simple, actionable guidance for preventing injection and input validation flaws in your applications, including defence against path traversal.
  • OWASP Path Traversal - OWASP community page with comprehensive information about path traversal, and links to various OWASP resources to help detect or prevent it.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
main.go (1)

14-15: Handle server errors and add timeouts to mitigate slowloris.

Don’t ignore ListenAndServe errors; configure reasonable timeouts.

-  http.ListenAndServe(":8080", nil)
+  srv := &http.Server{
+    Addr:         ":8080",
+    ReadTimeout:  5 * time.Second,
+    WriteTimeout: 10 * time.Second,
+    IdleTimeout:  60 * time.Second,
+  }
+  log.Fatal(srv.ListenAndServe())
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5a73ae7 and c1be38c.

📒 Files selected for processing (1)
  • main.go (1 hunks)

Comment thread main.go
Comment on lines +2 to +7
import (
"crypto/md5"
"fmt"
"io/ioutil"
"net/http"
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Use non-deprecated APIs and a modern hash.

ioutil is deprecated; MD5 is cryptographically broken. Prefer os + streaming and sha256.

-import (
-  "crypto/md5"
-  "fmt"
-  "io/ioutil"
-  "net/http"
-)
+import (
+  "crypto/sha256"
+  "fmt"
+  "io"
+  "log"
+  "net/http"
+  "os"
+  "path/filepath"
+  "strings"
+  "time"
+)
📝 Committable suggestion

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

Suggested change
import (
"crypto/md5"
"fmt"
"io/ioutil"
"net/http"
)
import (
"crypto/sha256"
"fmt"
"io"
"log"
"net/http"
"os"
"path/filepath"
"strings"
"time"
)
🤖 Prompt for AI Agents
In main.go around lines 2 to 7, the code imports deprecated ioutil and insecure
crypto/md5; replace them with non-deprecated streaming APIs and a modern hash:
swap "io/ioutil" for "io" (and "os" if reading files from disk), replace
"crypto/md5" with "crypto/sha256", and update the code to stream data into the
hasher (e.g., create sha256.New() and use io.Copy(hasher, source) where source
is an http response body or os.File) instead of reading everything with ReadAll;
ensure you close response bodies and handle errors appropriately.

Comment thread main.go
Comment on lines +9 to +13
http.HandleFunc("/read", func(w http.ResponseWriter, r *http.Request) {
file := r.URL.Query().Get("file")
b, _ := ioutil.ReadFile("./data/" + file)
fmt.Fprintf(w, "%x", md5.Sum(b))
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Block path traversal, handle I/O errors, avoid full-file reads, and set Content-Type.

Untrusted file is concatenated into a path (path traversal). Read errors are ignored, and ReadFile loads entire files (DoS risk). Also returns a digest without declaring a content type.

Apply this safer handler:

-  http.HandleFunc("/read", func(w http.ResponseWriter, r *http.Request) {
-    file := r.URL.Query().Get("file")
-    b, _ := ioutil.ReadFile("./data/" + file)
-    fmt.Fprintf(w, "%x", md5.Sum(b))
-  })
+  http.HandleFunc("/read", func(w http.ResponseWriter, r *http.Request) {
+    w.Header().Set("Content-Type", "text/plain; charset=utf-8")
+    file := r.URL.Query().Get("file")
+    if file == "" {
+      http.Error(w, "missing 'file' parameter", http.StatusBadRequest)
+      return
+    }
+    base := "./data"
+    baseAbs, err := filepath.Abs(base)
+    if err != nil {
+      http.Error(w, "server error", http.StatusInternalServerError)
+      return
+    }
+    targetAbs, err := filepath.Abs(filepath.Join(base, file))
+    if err != nil || !(targetAbs == baseAbs || strings.HasPrefix(targetAbs, baseAbs+string(os.PathSeparator))) {
+      http.Error(w, "invalid path", http.StatusBadRequest)
+      return
+    }
+    f, err := os.Open(targetAbs)
+    if err != nil {
+      if os.IsNotExist(err) {
+        http.Error(w, "not found", http.StatusNotFound)
+      } else {
+        http.Error(w, "unable to open file", http.StatusInternalServerError)
+      }
+      return
+    }
+    defer f.Close()
+    info, err := f.Stat()
+    if err != nil || info.IsDir() {
+      http.Error(w, "invalid file", http.StatusBadRequest)
+      return
+    }
+    const max = 10 << 20 // 10 MiB
+    if info.Size() > max {
+      http.Error(w, "file too large", http.StatusRequestEntityTooLarge)
+      return
+    }
+    h := sha256.New()
+    if _, err := io.Copy(h, f); err != nil {
+      http.Error(w, "read error", http.StatusInternalServerError)
+      return
+    }
+    fmt.Fprintf(w, "%x", h.Sum(nil))
+  })
📝 Committable suggestion

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

Suggested change
http.HandleFunc("/read", func(w http.ResponseWriter, r *http.Request) {
file := r.URL.Query().Get("file")
b, _ := ioutil.ReadFile("./data/" + file)
fmt.Fprintf(w, "%x", md5.Sum(b))
})
http.HandleFunc("/read", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
file := r.URL.Query().Get("file")
if file == "" {
http.Error(w, "missing 'file' parameter", http.StatusBadRequest)
return
}
base := "./data"
baseAbs, err := filepath.Abs(base)
if err != nil {
http.Error(w, "server error", http.StatusInternalServerError)
return
}
targetAbs, err := filepath.Abs(filepath.Join(base, file))
if err != nil || !(targetAbs == baseAbs || strings.HasPrefix(targetAbs, baseAbs+string(os.PathSeparator))) {
http.Error(w, "invalid path", http.StatusBadRequest)
return
}
f, err := os.Open(targetAbs)
if err != nil {
if os.IsNotExist(err) {
http.Error(w, "not found", http.StatusNotFound)
} else {
http.Error(w, "unable to open file", http.StatusInternalServerError)
}
return
}
defer f.Close()
info, err := f.Stat()
if err != nil || info.IsDir() {
http.Error(w, "invalid file", http.StatusBadRequest)
return
}
const max = 10 << 20 // 10 MiB
if info.Size() > max {
http.Error(w, "file too large", http.StatusRequestEntityTooLarge)
return
}
h := sha256.New()
if _, err := io.Copy(h, f); err != nil {
http.Error(w, "read error", http.StatusInternalServerError)
return
}
fmt.Fprintf(w, "%x", h.Sum(nil))
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant