Implemented SQL injection attackable service
This commit is contained in:
@@ -6,3 +6,10 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
actix-web="4.3.1"
|
||||||
|
actix-files="0.6.2"
|
||||||
|
actix-web-validator = "5.0.1"
|
||||||
|
serde = { veresion = "1.0.160", features = ["derive"] }
|
||||||
|
serde_json = "1.0.96"
|
||||||
|
handlebars = { version="4.3.6", features = ["dir_source"] }
|
||||||
|
rusqlite = "0.29.0"
|
||||||
|
|||||||
23
Readme.md
Normal file
23
Readme.md
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# Sql-Injection-Test
|
||||||
|
|
||||||
|
> Version: 1.0.23110.1 \
|
||||||
|
> Created by: Jali<jali@orca-central.de>
|
||||||
|
> Last Modified by: Jali<jali@orca-central.de>
|
||||||
|
|
||||||
|
## About
|
||||||
|
|
||||||
|
This project implements a very simple web-service, that is vulnerable to an SQL
|
||||||
|
injection attack. In this case a simple web-page is protected by a user name and
|
||||||
|
password, and the password is checked by requesting the user name and password
|
||||||
|
from the database, and check if they exist. If they do, users are granted access
|
||||||
|
to the web-page, if not they are thrown back to the login page.
|
||||||
|
|
||||||
|
The SQL queries, however, are vulnerable to SQL injection. So a user can gain
|
||||||
|
access by simply putting a statement such as
|
||||||
|
|
||||||
|
```wurst' OR '1'='1```
|
||||||
|
|
||||||
|
into the password field. The where clause '1'='1' will always be true, and
|
||||||
|
therefore the statement always returns a list of all possible users.
|
||||||
|
|
||||||
|
The example creates an in memory database with users Alice and Bob.
|
||||||
123
src/main.rs
123
src/main.rs
@@ -1,3 +1,122 @@
|
|||||||
fn main() {
|
use actix_files::Files;
|
||||||
println!("Hello, world!");
|
use actix_web::{web, App, HttpResponse, HttpServer};
|
||||||
|
use handlebars::Handlebars;
|
||||||
|
use serde::Deserialize;
|
||||||
|
use serde_json::json;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct Credentials {
|
||||||
|
username: String,
|
||||||
|
password: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init_sql() -> rusqlite::Connection {
|
||||||
|
let connection = rusqlite::Connection::open_in_memory().unwrap();
|
||||||
|
connection
|
||||||
|
.execute(
|
||||||
|
"CREATE TABLE IF NOT EXISTS users (username TEXT, password TEXT, UNIQUE(username));",
|
||||||
|
(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
connection
|
||||||
|
.execute("INSERT OR IGNORE INTO users VALUES ('Alice', 'test');", ())
|
||||||
|
.unwrap();
|
||||||
|
connection
|
||||||
|
.execute(
|
||||||
|
"INSERT OR IGNORE INTO users VALUES ('Bob', 'lovesApples');",
|
||||||
|
(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
connection
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn index(hb: web::Data<Handlebars<'_>>) -> HttpResponse {
|
||||||
|
let data = json!({
|
||||||
|
"project_name": "Book Store Login",
|
||||||
|
});
|
||||||
|
|
||||||
|
let body = hb.render("index", &data).unwrap();
|
||||||
|
HttpResponse::Ok().body(body)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn validate_login(
|
||||||
|
hb: web::Data<Handlebars<'_>>,
|
||||||
|
cred: web::Form<Credentials>,
|
||||||
|
) -> HttpResponse {
|
||||||
|
let connection = init_sql();
|
||||||
|
let query = format!(
|
||||||
|
"SELECT * FROM users WHERE username = '{}' AND password = '{}';",
|
||||||
|
cred.username, cred.password
|
||||||
|
);
|
||||||
|
println!("{}", query);
|
||||||
|
let mut stmt = connection.prepare(query.as_str()).unwrap();
|
||||||
|
let users = stmt
|
||||||
|
.query_map([], |row| {
|
||||||
|
Ok(Credentials {
|
||||||
|
username: row.get(0)?,
|
||||||
|
password: row.get(1)?,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
if users.count() > 0 {
|
||||||
|
println!("Match!");
|
||||||
|
return storepage(hb).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("No Match!");
|
||||||
|
index(hb).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn storepage(hb: web::Data<Handlebars<'_>>) -> HttpResponse {
|
||||||
|
let data = json!({
|
||||||
|
"project_name": "Book Store",
|
||||||
|
"books":[
|
||||||
|
{
|
||||||
|
"name":"Harry Potter",
|
||||||
|
"author":"J K Rowlings",
|
||||||
|
"image_path":"/static/images/download.jpeg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"Lord of the ring",
|
||||||
|
"author":"Tolken",
|
||||||
|
"image_path": "/static/images/lord_of.jpeg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"Americanah",
|
||||||
|
"author":"Chimamada Adichie",
|
||||||
|
"image_path":"/static/images/americanah.jpeg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"Elon Musk",
|
||||||
|
"author":"#####",
|
||||||
|
"image_path":"/static/images/elon.jpeg"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
let body = hb.render("store", &data).unwrap();
|
||||||
|
HttpResponse::Ok().body(body)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[actix_web::main]
|
||||||
|
async fn main() -> std::io::Result<()> {
|
||||||
|
let mut handlebars = Handlebars::new();
|
||||||
|
handlebars
|
||||||
|
.register_templates_directory(".html", "./static/")
|
||||||
|
.unwrap();
|
||||||
|
let handlebars_ref = web::Data::new(handlebars);
|
||||||
|
|
||||||
|
println!("listening on port 8080");
|
||||||
|
HttpServer::new(move || {
|
||||||
|
App::new()
|
||||||
|
.app_data(handlebars_ref.clone())
|
||||||
|
.service(Files::new("/static", "static").show_files_listing())
|
||||||
|
//.service(web::resource("/login").route(web::post().to(validate_login)))
|
||||||
|
.route("/", web::post().to(validate_login))
|
||||||
|
.route("/", web::get().to(index))
|
||||||
|
})
|
||||||
|
.bind("0.0.0.0:8080")?
|
||||||
|
.run()
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|||||||
16
static/css/index.css
Normal file
16
static/css/index.css
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
.cats {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.books {
|
||||||
|
border: 1px solid grey;
|
||||||
|
min-width: 200px;
|
||||||
|
min-height: 350px;
|
||||||
|
margin: 5px;
|
||||||
|
padding: 5px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.book > img {
|
||||||
|
width: 190px;
|
||||||
|
}
|
||||||
BIN
static/images/americanah.jpeg
Normal file
BIN
static/images/americanah.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
BIN
static/images/download.jpeg
Normal file
BIN
static/images/download.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
BIN
static/images/elon.jpeg
Normal file
BIN
static/images/elon.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
BIN
static/images/lord_of.jpeg
Normal file
BIN
static/images/lord_of.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.6 KiB |
23
static/index.html
Normal file
23
static/index.html
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>{{project_name}}</title>
|
||||||
|
<link rel="stylesheet" href="static/css/index.css" type="text/css">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>{{project_name}}</h1>
|
||||||
|
<form method="post" a>
|
||||||
|
<label for="username">Username: </label>
|
||||||
|
<input type="text" name="username" required>
|
||||||
|
<br>
|
||||||
|
<label for="password">Password: </label>
|
||||||
|
<input type="text" name="password" required>
|
||||||
|
<br>
|
||||||
|
<input type="submit" value="login">
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
23
static/store.html
Normal file
23
static/store.html
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>{{project_name}}</title>
|
||||||
|
<link rel="stylesheet" href="static/css/index.css" type="text/css">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>{{project_name}}</h1>
|
||||||
|
<section class="cats">
|
||||||
|
{{#each books}}
|
||||||
|
<article class="cat">
|
||||||
|
<h3>{{this.name}}</h3>
|
||||||
|
<img src="{{this.image_path}}" />
|
||||||
|
<h4>Author: {{this.author}}</h4>
|
||||||
|
</article>
|
||||||
|
{{/each}}
|
||||||
|
</section>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user