Skip to content

Commit

Permalink
Ch10: Prevent Cross-site scripting attack by encoding characters
Browse files Browse the repository at this point in the history
  • Loading branch information
tahaafzal5 committed Aug 26, 2024
1 parent 9c1f4ca commit 00d08c3
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 1 deletion.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ argon2 = { version = "0.4", features = ["std"] }
serde = { version = "1", features = ["derive"] }
serde-aux = "4"
urlencoding = "2"
htmlescape = "0.3"

# Using table-like toml syntax to avoid a super-long line
[dependencies.sqlx]
Expand Down
16 changes: 16 additions & 0 deletions Notes/Ch6-10.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@
- [Contextual Errors](#contextual-errors)
- [Naive Approach](#naive-approach)
- [Query Parameters](#query-parameters)
- [Cross-Site Scripting (XSS)](#cross-site-scripting-xss)

# Ch 6 - Reject Invalid Subscribers #1
* Our input validation for `/POST` is limited: we just ensure that both the `name` and the `email` fields are provided, even if they are empty.
Expand Down Expand Up @@ -1209,3 +1210,18 @@ TEST_LOG=true cargo test --quiet --release newsletters_are_delivered | grep "VER

#### Query Parameters
* We can encode the error in the query parameter and extract it in the request handler for `GET /login`.

#### Cross-Site Scripting (XSS)
* Query parameters are not private - an attacker can redirect a user to a malicious link.
* This is known as a cross-site scripting attack (XSS).
* OWASP provides ways on how to prevent XSS attacks.
* We want to display untrusted data (the value of a query parameter) inside an HTML element (`<p><i>UNTRUSTED DATA HERE</i></p>`).
* According to OWASP’s guidelines, we must HTML entity-encode the untrusted input i.e.
1. convert `&` to `&amp`
2. convert `<` to `&lt`
3. convert `>` to `&gt`
4. convert `"` to `&quot`
5. convert `'` to `&#x27`
6. convert `/` to `&#x2F`
* HTML prevents insertion of further HTML elements by escaping the characters required to define them.
* But just escaping characters is not enough.
5 changes: 4 additions & 1 deletion src/routes/login_form/get.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ pub struct QueryParams {
pub async fn login_form(query: web::Query<QueryParams>) -> HttpResponse {
let error_html = match query.0.error {
None => "".into(),
Some(error_message) => format!("<p><i>{error_message}</i></p>"),
Some(error_message) => format!(
"<p><i>{}</i></p>",
htmlescape::encode_minimal(&error_message)
),
};

HttpResponse::Ok()
Expand Down

0 comments on commit 00d08c3

Please sign in to comment.