4

私は現在、ASP.netでコード化された通常の登録とログインのWebサイトを持っています。私はAccessデータベースを使用していますが、ほとんどのデータベースアクション(executeQuery、executeRead、isExits ...)を処理するために友人が作成したC#クラスを使用しています。

Webサイトの構築がほぼ完了したので、セキュリティの追加を開始したいと思います。ほとんどの場合、データベースに追加します。このテーマに関するチュートリアルをしばらく検索しましたが、コードを実際に機能させることができなかった古いmicrosoft msdnの記事を除いて、良いものは見つかりませんでした。私が今持っている最も遠いのは、ユーザー名とパスワードに危険な文字('、-、;など)を許可しないことですが、それは私が使用できるより悪い解決策であるかのように感じます(なぜすべきではないのですか?私のユーザーはこの文字を使用しませんか?)

私が見つけた最善の解決策は、変数を宣言した後にクエリ文字列に挿入することだと思います( "WHERE username = @ user"などと関係があります)が、それを機能させることができませんでしたアクセスし、私のoleDBManagerを使用します。

これが私の現在の登録コードです。handle()は文字列からすべての'を削除し、Validate()は文字列内の危険な部分をチェックします。

        string username = user.Text;
        string password = pass.Text;
        bool isThingy = false;
        if (handle(ref password)) isThingy = true;
        if (handle(ref username)) isThingy = true;

        if (username != "" && username != null)
        {
            if (password != "" && password != null)
            {
                if (Validate(username, password))
                {
                    if ((db.IsExist("SELECT * FROM Table1 WHERE username='" + username + "'") == false))
                    {
                        int a = db.ExecuteQuery("INSERT INTO `Table1`(`username`, `password`, `logins`, `email`, `fname`, `lname`, `country`, `city`, `birthday`, `userid`) VALUES ('" + username + "', '" + password + "', '0', '', '', '', '', '', '', '" + Convert.ToString(Convert.ToInt32(db.ExecuteCellRead("SELECT MAX(userid) FROM Table1")) + 1) + "');");

                        if (!isThingy) errorLabel.Text = "Your user has been successfully registered";
                        else errorLabel.Text = "The ' token is invalid. your user was registered absence the '.";
                    }
                    else
                        errorLabel.Text = "This username is already taken";
                }
                else errorLabel.Text = "Invalid name format";

            }
            else errorLabel.Text = "Please enter a password";
        }
        else errorLabel.Text = "Please enter a user name";

oleDBManager(私のコードではdbという名前)について:

    private OleDbConnection link; // The link instance
    private OleDbCommand command; // The command object
    private OleDbDataReader dataReader; // The data reader object
    private OleDbDataAdapter dataAdapter; // the data adapter object
    private DataTable dataTable; // the data table object
    private string dbName; // the Database filename
    private int version; // the usersTableG office version
    private string connectionString; // the connection string for the database connection
    private string provider; // the matching driver string for the connection string
    private string path; // the path to the database file


...


    public int ExecuteQuery(string query)
    {
        this.link.Open();
        int rowsAffected;
        // ---
        this.command = new OleDbCommand(query, this.link);
        try
        {
            rowsAffected = this.command.ExecuteNonQuery();
        }
        catch (InvalidOperationException e)
        {
            if (e.Data == null)
                throw;
            else
                rowsAffected = -1;
        }
        finally
        {
            this.command.Dispose();
            this.link.Close();
        }
        // ---
        return rowsAffected;
    }

    public bool IsExist(string query)
    {
        this.link.Open();
        // ---
        this.command = new OleDbCommand(query, this.link);
        this.dataReader = this.command.ExecuteReader();
        bool a = this.dataReader.Read();
        // ---
        this.command.Dispose();
        this.link.Close();
        // ---
        return a;
    }

    public string ExecuteCellRead(string query)
    {
        string output = "";
        this.dataTable = this.ExcecuteRead(query);

        foreach (DataRow row in this.dataTable.Rows)
        {
            foreach (object obj in row.ItemArray)
            {
                output += obj.ToString();
            }
        }

        return output;
    }

したがって、ご覧のとおり、主な問題は、ユーザーが文字を'として使用できないことです。最善の解決策はSQLクエリで@変数を使用することだと思いますが、その方法がわかりません。

[あなたの助けに感謝します]PS。テーブルの名前を変更しました;)

編集:ほとんどの人がこれらのパラメータ化されたクエリを使用するように言っていますが、私はそれを行ったことがないので、それらの使用方法の例を教えていただければ幸いです



したがって、@ Remouのおかげで、私の最終的なコードは次のようになります。

    db.DoWeirdStackOverFlowStuff(
    "INSERT INTO `Table1`(`username`, `password`, `logins`) VALUES (@username, @password, '0');"
    , new string[] { "@username", "@password" }
    , new string[] { username, password });

    public int DoWeirdStackOverFlowStuff(string query, string[] vars, string[] reps)
    {
        this.link.Open();
        int rowsAffected;
        // ---
        this.command = new OleDbCommand();
        this.command.CommandText = query;
        this.command.CommandType = System.Data.CommandType.Text;
        this.command.Connection = this.link;

        //Parameters in the order in which they appear in the query
        for (int i = 0; i < vars.Length; i++)
            this.command.Parameters.AddWithValue(vars[i], reps[i]);

        try
        {
            rowsAffected = this.command.ExecuteNonQuery();
        }
        catch (InvalidOperationException e)
        {
            if (e.Data == null)
                throw;
            else
                rowsAffected = -1;
        }
        finally
        {
            this.command.Dispose();
            this.link.Close();
        }
        // ---
        return rowsAffected;
    }

これを必要とする人のために=]

4

2 に答える 2

1

いくつかのメモ

MS Accessには、UpdateUserという名前の保存されたクエリがあります。次のようになります。

       UPDATE INTERNETSETTINGS 
       SET url = [@url], 
           databasename = [@databasename], 
           port = [@port], 
           username = [@username],
           [password] = [@password]

コマンドオブジェクトを使用して、コード内でこのクエリを名前で参照できます。

        OleDbCommand Command = new OleDbCommand();

        Command.CommandText = "UpdateUser"; //saved query
        Command.CommandType = System.Data.CommandType.StoredProcedure;
        Command.Connection = cn; //a connection to the database

        //Parameters in the order in which they appear in the query
        Command.Parameters.AddWithValue("@url", "a"); //a,b,c etc for my test run
        Command.Parameters.AddWithValue("@databasename", "b");
        Command.Parameters.AddWithValue("@port","c");
        Command.Parameters.AddWithValue("@username", "d");
        Command.Parameters.AddWithValue("@password", "e");

        Command.ExecuteNonQuery();
于 2013-03-14T16:45:50.160 に答える
0

ここでAccessがSQLServerと同じことを行うかどうかは覚えていませんが、SQL Serverでは、一重引用符を2倍にすることでエスケープできます。

username = username.Replace("'", "''");

したがって、文字列に一重引用符を含めたり、データベースに保存したり、悪意のある文字列ターミネータとして使用したりすることはできません。

于 2013-03-14T16:12:05.053 に答える