0

My Controller:

public IActionResult vuln(string input)
{
    using (var connection = new SqlConnection(@"Server=localhost;Database=AspDb;User Id=sa;Password=1234; TrustServerCertificate=true"))
    {
        connection.Open();
        using (var command = new SqlCommand($"SELECT UserName FROM AspDb.dbo.Users WHERE UserName LIKE '%{input}%'", connection))
        {
            using (var reader = command.ExecuteReader())
            {
                var content = new List<string>();
                while (reader.Read())
                {
                    content.Add(reader.GetString(0));
                }
                ViewData["vuln"] = content;
                return View("Example1");
            }
        }
    }
}

and my DB data model is:

namespace ASP.Models
{
    public class User
    {
        [Key] // PK 
        public int UserNo { get; set; }

        [Required(ErrorMessage ="UserName!")]
        public string UserName { get; set; }

        [Required(ErrorMessage = "UserId!.")]
        public string UserId { get; set; }

        [Required(ErrorMessage = "UserPassword!.")]
        public string UserPassword { get; set; }
    }
}

and my front-end:

<form asp-controller="My Controller" asp-action="vuln">
    <div class="row">

        <div class="col-md-10 offset-md-1">
            <div class="card m-auto" style="max-width:850px">
                <div class="card-body">
                    <form class="d-flex align-items-center">
                        <div class="row">
                            <div class="col-9">
                                <input class="form-control form-control-lg flex-shrink-1 form-control-borderless" type="search" placeholder="search word" name="input">
                            </div>
                            <div class="col-3">
                                <button class="btn btn-success btn-lg" type="submit">search</button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
            <hr>
            <div class="card m-auto" style="max-width:850px">
                <div class="card-body"><textarea class="form-control" readonly="" style="height: 350px;">@ViewData["vuln"]</textarea></div>
            </div>
        </div>
    </div>
</form>

If I search for only one character of the user name, the full name should be printed. Also when I click the button without entering anything, all saved usernames should be printed out.

But the value I got is

System.Collections.Generic.List`1[System.String].

How can I output the value of the DB table normally?

I use C# ASP.NET Core 7.0.

Yong Shun
  • 35,286
  • 4
  • 24
  • 46
awefwefwv
  • 13
  • 3
  • 1
    Don't use string interpolation to prepare your query with parameters – it's exposing your app for SQL injection attack. You should use [parameters](https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/configuring-parameters-and-parameter-data-types). – Oshawott Jan 15 '23 at 11:22
  • Your frontend code is missing, you need to show how you try to render the data. – Sebastian S. Jan 15 '23 at 11:33
  • I'm trying to create two types of code: vulnerable and secure. The above code is vulnerable. – awefwefwv Jan 15 '23 at 11:34
  • I added my frontend. – awefwefwv Jan 15 '23 at 11:38

1 Answers1

1

From Object.ToString Method,

Default implementations of the Object.ToString method return the fully qualified name of the object's type.

So the output is the default behavior that the @ViewData["vuln"] is printed as the qualified name instead of its value.

You should use either foreach loop:

<div class="card-body">
    <textarea class="form-control" readonly="" style="height: 350px;">
        @foreach (var username in (List<string>)@ViewData["vuln"])
        {
            @username
            &nbsp;
        }
    </textarea> 
</div>

Or work with String.Join method:

<div class="card-body">
    <textarea class="form-control" readonly="" style="height: 350px;">
        @String.Join(",", (List<string>)@ViewData["vuln"]
    </textarea>  
</div>

While also considering working the query as the parameterized query instead of string concatenation in the query.

using (var command = new SqlCommand($"SELECT UserName FROM AspDb.dbo.Users WHERE UserName LIKE @input", connection))
{
    command.Parameters.Add("@input", SqlDbType.NVarChar).Value = $"%{input}%";

    ...
}
Yong Shun
  • 35,286
  • 4
  • 24
  • 46