feat(backend): built basic sql connection infrastructure and added sql injection protection
This commit is contained in:
parent
64d3f29931
commit
45c46d19db
|
@ -1 +1,2 @@
|
|||
/target
|
||||
test.sqlite
|
||||
|
|
|
@ -284,10 +284,34 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"actix-web",
|
||||
"anyhow",
|
||||
"libinjection",
|
||||
"serde",
|
||||
"sqlite",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.63.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36d860121800b2a9a94f9b5604b332d5cffb234ce17609ea479d723dbc9d3885"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"lazy_static",
|
||||
"lazycell",
|
||||
"log",
|
||||
"peeking_take_while",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn 1.0.109",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
|
@ -349,12 +373,32 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cexpr"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"libc",
|
||||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.4.0"
|
||||
|
@ -429,6 +473,12 @@ dependencies = [
|
|||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
||||
|
||||
[[package]]
|
||||
name = "encoding_rs"
|
||||
version = "0.8.32"
|
||||
|
@ -520,6 +570,27 @@ version = "0.27.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e"
|
||||
|
||||
[[package]]
|
||||
name = "git2"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2994bee4a3a6a51eb90c218523be382fd7ea09b16380b9312e9dbe955ff7c7d1"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
"libgit2-sys",
|
||||
"log",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.3.20"
|
||||
|
@ -615,12 +686,84 @@ version = "0.3.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "lazycell"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
||||
|
||||
[[package]]
|
||||
name = "libgit2-sys"
|
||||
version = "0.14.2+1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f3d95f6b51075fe9810a7ae22c7095f12b98005ab364d8544797a825ce946a4"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"libssh2-sys",
|
||||
"libz-sys",
|
||||
"openssl-sys",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libinjection"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6a9a90ce65224c87515f603d1eed413909886dec98f2e9985044f0b88e26039"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"git2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libssh2-sys"
|
||||
version = "0.2.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b094a36eb4b8b8c8a7b4b8ae43b2944502be3e59cd87687595cf6b0a71b3f4ca"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"libz-sys",
|
||||
"openssl-sys",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libz-sys"
|
||||
version = "1.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "local-channel"
|
||||
version = "0.1.3"
|
||||
|
@ -667,6 +810,12 @@ version = "0.3.17"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.1"
|
||||
|
@ -688,6 +837,16 @@ dependencies = [
|
|||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.16.0"
|
||||
|
@ -713,6 +872,24 @@ version = "1.18.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.91"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "866b5f16f90776b9bb8dc1e1802ac6f0513de3a7a7465867bfbc563dc737faac"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.1"
|
||||
|
@ -742,6 +919,12 @@ version = "1.0.14"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
|
||||
|
||||
[[package]]
|
||||
name = "peeking_take_while"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.0"
|
||||
|
@ -864,6 +1047,12 @@ version = "0.1.23"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.0"
|
||||
|
@ -945,6 +1134,12 @@ dependencies = [
|
|||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.1"
|
||||
|
@ -989,6 +1184,36 @@ dependencies = [
|
|||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlite"
|
||||
version = "0.31.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3ddda64c469a257a3b31298805427784d992c226c94b81003f96e8b122286ad"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"sqlite3-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlite3-src"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfc95a51a1ee38839599371685b9d4a926abb51791f0bc3bf8c3bb7867e6e454"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlite3-sys"
|
||||
version = "0.15.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2752c669433e40ebb08fde824146f50d9628aa0b66a3b7fc6be34db82a8063b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"sqlite3-src",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
|
@ -1157,6 +1382,12 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
|
@ -1169,6 +1400,17 @@ version = "0.11.0+wasi-snapshot-preview1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "4.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269"
|
||||
dependencies = [
|
||||
"either",
|
||||
"libc",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
|
|
@ -11,3 +11,5 @@ tokio = { version = "1.29", features = ["macros", "rt-multi-thread", "sync"] }
|
|||
anyhow = "1.0"
|
||||
actix-web = "4"
|
||||
serde = { version = "1.0.183", features = ["derive"] }
|
||||
sqlite = "0.31.0"
|
||||
libinjection = "0.3.2"
|
||||
|
|
30
README.md
30
README.md
|
@ -21,18 +21,19 @@ Registers a new account.
|
|||
|
||||
#### Responses
|
||||
|
||||
| Response | Description |
|
||||
|----------|------------------------------------------|
|
||||
| 200 | User created successfully |
|
||||
| 400 | Formal error in the request |
|
||||
| 409 | The requested username is already in use |
|
||||
| 500 | Internal server error |
|
||||
| Response | Description |
|
||||
|----------|----------------------------------------------------------|
|
||||
| 200 | User created successfully |
|
||||
| 400 | Formal error in the request |
|
||||
| 403 | Rejected for security reasons (sql injection protection) |
|
||||
| 409 | The requested username is already in use |
|
||||
| 500 | Internal server error |
|
||||
|
||||
|
||||
### `/authenticate`
|
||||
Authenticates using an existing account.
|
||||
|
||||
#### Payload
|
||||
#### Content / Payload
|
||||
|
||||
| Field | Description |
|
||||
|------------|-----------------------------------|
|
||||
|
@ -41,13 +42,14 @@ Authenticates using an existing account.
|
|||
|
||||
#### Responses
|
||||
|
||||
| Response | Description |
|
||||
|----------|----------------------------------------------------|
|
||||
| 200 | Authenticated successfully |
|
||||
| 400 | Formal error in the request |
|
||||
| 401 | Authentication failure (wrong password) |
|
||||
| 404 | There was no account found with the specified name |
|
||||
| 500 | Internal server error |
|
||||
| Response | Description |
|
||||
|----------|----------------------------------------------------------|
|
||||
| 200 | Authenticated successfully |
|
||||
| 400 | Formal error in the request |
|
||||
| 401 | Authentication failure (wrong password) |
|
||||
| 403 | Rejected for security reasons (sql injection production) |
|
||||
| 404 | There was no account found with the specified name |
|
||||
| 500 | Internal server error |
|
||||
|
||||
---
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ struct AuthenticateData {
|
|||
/// Possible Responses:
|
||||
/// * 200 -> Authentication was successfull
|
||||
/// * 401 -> Authentication failed (wrong password)
|
||||
/// * 403 -> The request was rejected due to security reasons
|
||||
/// * 404 -> User not found
|
||||
/// * 500 -> Internal Server Error
|
||||
#[post("/authenticate")]
|
||||
|
@ -44,6 +45,7 @@ async fn authenticate(
|
|||
ResponseAuthenticate::Success => HttpResponse::Ok().finish(),
|
||||
ResponseAuthenticate::UserNotFound => HttpResponse::NotFound().finish(),
|
||||
ResponseAuthenticate::WrongPassword => HttpResponse::Unauthorized().finish(),
|
||||
ResponseAuthenticate::Rejected => HttpResponse::Forbidden().finish(),
|
||||
},
|
||||
_ => HttpResponse::InternalServerError().finish(),
|
||||
},
|
||||
|
@ -59,6 +61,7 @@ struct RegisterData {
|
|||
|
||||
/// Possible Responses:
|
||||
/// * 200 -> User created successfully
|
||||
/// * 403 -> The request was rejected due to security reasons
|
||||
/// * 409 -> The requested username is already in use
|
||||
/// * 500 -> Internal Server Error
|
||||
#[post("/register")]
|
||||
|
@ -81,6 +84,7 @@ async fn register(data: web::Data<ApiState>, body: web::Json<RegisterData>) -> i
|
|||
Response::Register(r) => match r {
|
||||
ResponseRegister::Success => HttpResponse::Ok().finish(),
|
||||
ResponseRegister::NameAlreadyInUse => HttpResponse::Conflict().finish(),
|
||||
ResponseRegister::Rejected => HttpResponse::Forbidden().finish(),
|
||||
},
|
||||
_ => HttpResponse::InternalServerError().finish(),
|
||||
},
|
||||
|
|
|
@ -1,11 +1,25 @@
|
|||
use anyhow::Result;
|
||||
use libinjection::sqli;
|
||||
|
||||
use crate::call::{Response, ResponseAuthenticate, ResponseDelete, ResponseRegister};
|
||||
|
||||
pub struct Backend {}
|
||||
pub struct Backend {
|
||||
db: sqlite::Connection,
|
||||
}
|
||||
|
||||
fn is_sql_injection(string: &String) -> bool {
|
||||
match sqli(string) {
|
||||
Some((is_injection, _)) => is_injection,
|
||||
None => true, // this could be a false positive, but that would be better than an SQLi
|
||||
}
|
||||
}
|
||||
|
||||
impl Backend {
|
||||
pub fn register(&mut self, username: &String, password: &String) -> Result<Response> {
|
||||
if is_sql_injection(username) {
|
||||
return Ok(Response::Register(ResponseRegister::Rejected));
|
||||
}
|
||||
|
||||
println!(
|
||||
"<Dummy> Registered Account: (Username: '{}' | Password: '{}')",
|
||||
username, password
|
||||
|
@ -14,6 +28,10 @@ impl Backend {
|
|||
}
|
||||
|
||||
pub fn authenticate(&mut self, username: &String, password: &String) -> Result<Response> {
|
||||
if is_sql_injection(username) {
|
||||
return Ok(Response::Authenticate(ResponseAuthenticate::Rejected));
|
||||
}
|
||||
|
||||
println!(
|
||||
"<Dummy> Authentication Request: (Username: '{}' | Password: '{}')",
|
||||
username, password
|
||||
|
@ -23,12 +41,28 @@ impl Backend {
|
|||
}
|
||||
|
||||
pub fn delete(&mut self, username: &String) -> Result<Response> {
|
||||
if is_sql_injection(username) {
|
||||
return Ok(Response::Delete(ResponseDelete::Rejected));
|
||||
}
|
||||
|
||||
println!("<Dummy> Deletion Request: (Username: '{}')", username);
|
||||
println!(" -> Accepted");
|
||||
Ok(Response::Delete(ResponseDelete::Success))
|
||||
}
|
||||
|
||||
pub fn new() -> Result<Self> {
|
||||
Ok(Self {})
|
||||
pub fn new(database: &std::path::Path) -> Result<Self> {
|
||||
let conn = sqlite::open(database)?;
|
||||
|
||||
conn.execute(
|
||||
"CREATE TABLE IF NOT EXISTS BaseAuth (
|
||||
id INTEGER,
|
||||
username TEXT,
|
||||
salt TEXT,
|
||||
password TEXT,
|
||||
PRIMARY KEY(id)
|
||||
);",
|
||||
)?;
|
||||
|
||||
Ok(Self { db: conn })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ pub enum Call {
|
|||
pub enum ResponseRegister {
|
||||
Success,
|
||||
NameAlreadyInUse,
|
||||
Rejected,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -21,12 +22,14 @@ pub enum ResponseAuthenticate {
|
|||
Success,
|
||||
UserNotFound,
|
||||
WrongPassword,
|
||||
Rejected,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ResponseDelete {
|
||||
Success,
|
||||
UserNotFound,
|
||||
Rejected,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
|
@ -8,7 +8,7 @@ use anyhow::Result;
|
|||
async fn main() -> Result<()> {
|
||||
println!("Starting BaseAuth server v0.1");
|
||||
|
||||
let backend = backend::Backend::new()?;
|
||||
let backend = backend::Backend::new(&std::path::Path::new("test.sqlite"))?;
|
||||
|
||||
let tx = call::start_worker(backend).await?;
|
||||
api::start_worker(8080, tx).await?;
|
||||
|
|
Loading…
Reference in New Issue