:::success
# AS Lab 2 - Web Security
:::
:::info
In this assignment, you will get familiar with the common security issues on the web and how they are performed. The OWASP community provides a number of exercises that demonstrate such issues in their Security Knowledge Framework.
:::
:::info
Follow mini-labs provided by Security Knowledge Framework. You can launch labs in the cloud or in your local environment from sources.
Labs: https://demo.securityknowledgeframework.org/labs/view
Sources: https://github.com/blabla1337/skf-labs
:::
:::warning
### 1. Path traversal (LFI)
:::
Here the /home script is run, which sends the filename parameter (contains the path to the file) for display in a web form. The user running the script has access to important files (/etc/passwd).
**Vulnerable part:**
```
<form method="post" action="/home" enctype="multipart/form-data">
<div class="form-group">
<label>Selects</label>
<select name="filename" class="form-control">
<option value="text/intro.txt">Intro</option>
<option value="text/chapter1.txt">Chapter 1</option>
<option value="text/chapter2.txt">Chapter 2</option>
</select>
</div>
```
**Suggestions for correction:**
Do not transfer files via web forms, and yet it is better to choose a separate directory for such files, which will be located on a separate web server.
----------------------------------------------
:::warning
### 2. Cross site scripting
:::
**Vulnerable part:**
```
<form method="post" action="/home">
<input type="text" class="form-control" name="string" placeholder="fill me in plz" /><br />
<button class="btn btn-primary" type="submit">Submit Button</button>
```
```
<p style="font-size:2em;"> </p>
```
**Suggestions for correction:**
In order to prohibit the user from using scripts inside this code, it is necessary to validate the input text. And you can also do a preliminary conversion of html tags.
----------------------------------------------
:::warning
### 3. Cross site scripting (attribute)
:::
**Vulnerable part:**
```
<center>
<p style="font-size:2em;">
<span style='color: green' > Let me be a new color!</span></p>
</center>
```
**Suggestions for correction:**
In order to prevent the input of various elements, it is necessary to add restrictions (for example, allow certain colors and simply output an error if there is a discrepancy). Or use the function to forcibly convert content to text.
----------------------------------------------
:::warning
### 4. Cross site scripting (href)
:::
**Vulnerable part:**
```
<center>
<p style="font-size:2em;">
<a style="font-size:20px;" href="">visit my website!</a> </p>
</center>
```
**Suggestions for correction:**
Before using the entered link, you must use a regular expression. Use that html conversion function. Due to this, the js code will not be feasible due to the replacement of the characters ', " which are intended for entering text characters.
----------------------------------------------
:::warning
### 5. CSS Injection
:::
**Vulnerable part:**
```
<body>
<style>
p.colorful {color: red;}
</style>
```
**Suggestions for correction:**
When we enter something in CSS, we can also validate the information that needs to be entered. For example, write a list for this. Also use html character escaping so that the characters entered in the script are recognized as text and are not executed.
----------------------------------------------
:::warning
### 6. XSSI
:::
**Vulnerable part:**
```
https://localhost:8081/script-provider/javascript.js
```
**Suggestions for correction:**
It is necessary to approach the release of the production version of the application sensibly and limit the use of local scripts on it. There is also a special tool for this, it is called [MutationObserver](https://developer.mozilla.org/ru/docs/Web/API/MutationObserver).
----------------------------------------------
:::warning
### 7. Cross site request forgery
:::
**Vulnerable part:**
```
Application is performing a POST request that results in a data
mutation, storing our favorite color into the session of the
user and displaying this back to the user in the HTML website
```
**Suggestions for correction:**
At the server level, you can restrict requests to the CORS policy, then the browser will not allow accessing the server without this policy. Restriction on sending requests from other domains.
----------------------------------------------
:::warning
### 8. Cross site request forgery (same site)
:::
**Vulnerable part:**
```
Lax mode allowed the browser to send the cookie through the
cross-site-request after top-level navigation using a non-CSFR
method (GET). In other words, if the application accepts GET
query string parameters to change data in persistence (or allows
POST requests being converted into GET), CSRF attack will also
succeed.
```
**Suggestions for correction:**
If the sameSite=strict, the browser will not include a cookie in any requests originating from another site. Prohibit conversion of GET requests to POST.
----------------------------------------------
:::warning
### 9. Cross site request forgery weak
:::
**Vulnerable part:**
```
To do the malicious CSRF using a POST request from and sending
the weak csrf_token with
```
**Suggestions for correction:**
We can use Synchronizer Tokens or Anti-CSRF (synchronization tokens). In this case, the initiator of the key is the server — it stores the original encryption. When the browser accesses the server and presents it with a key, the server compares it with the source code and, depending on the result, continues or interrupts the session.
----------------------------------------------
:::warning
### 10. Clickjacking
:::
**Vulnerable part:**
```
<input type="submit" value="Click me for free stuff!" class="button is-ticket" style="position: absolute; "/>
<iframe src="http://127.0.0.1:1337" style="opacity: 0; position: relative; " height="20%" width="20%" scrolling="no" id="foo"></iframe>
<a href="#" onclick="myFunction()" iid="foo" value="Show secret!" class="button is-ticket" style="float:right;">Show the evil!</a>
```
**Suggestions for correction:**
It is necessary to use `opacity: 0.5;` on the page. The samesite attribute can also help avoid a clickjacking attack. `Set-Cookie: authorization=secret; somesite` then such cookies will not be sent when the site is opened in an iframe from another site.
----------------------------------------------
:::warning
### 11. Content security policy
:::
**Vulnerable part:**
```
A CSP will prevent most script-injection attacks from occurring
because it can be set up to limit JavaScript to loading only
from trusted places.
```
**Suggestions for correction:**
If we talk about this particular example, then I believe that the following policy should be used:
```
#let's just ban all scripts
Content-Security Policy:script-src ‘none’
#or allow actions from a specific (our) source
default-src ‘none’; script-src ‘self’; img-src ‘self’; style-src ‘self’;base-uri ‘self’;form-action ‘self’
```
----------------------------------------------
:::warning
### 12. CORS exploitation
:::
**Vulnerable part:**
```
we will now do a XHR GET request from our evil domain in order
to steal sensitive information.
```
**Suggestions for correction:**
To eliminate this vulnerability, you need to configure your server correctly. I don't agree with this line. If anything, then a good solution in this case would be just the same forced shutdown of [SOP](https://stackoverflow.com/a/14717414).
```
This disallows the developer to disable the SOP entirely and expose your site to everyone.
```
In general, it is necessary to determine the allowed resources (scripts and codes needed to run a web application) and their sources.
----------------------------------------------
:::warning
### 13. Local file inclusion (harder)
:::
**Vulnerable part:**
```
So lets try a payload like this: /..././..././..././..././..././..././..././etc/passwd
```
**Suggestions for correction:**
We use a null byte, it guarantees that any character following it will be ignored:
```
https://example-site.com/preview.php?file=../../../../../passwd%00
```
----------------------------------------------
:::warning
### 14. Local file inclusion (hard)
:::
**Suggestions for correction:**
Here are a few ways to prevent LFI attacks:
* **ID assignation** – save your file paths in a secure database and give an ID for every single one, this way users only get to see their ID without viewing or altering the path
* **Whitelisting** – use verified and secured whitelist files and ignore everything else
* **Use databases** – don’t include files on a web server that can be compromised, use a database instead
* **Better server instructions** – make the server send download headers automatically instead of executing files in a specified directory
----------------------------------------------
:::warning
### 15. Open redirect
:::
**Vulnerable part:**
```
app.all("/redirect", (req, res) => {
let newurl = req.query.newurl;
res.redirect(302, newurl);
});
```
**Suggestions for correction:**
The most preferred method is to use predefined keys that are mapped to a specific destination. This is known as the whitelist method. Something like this:
```
if (allowlist.indexOf(req.query.redirect_url) > -1) {
res.redirect(req.query.redirect_url);
} else {
res.redirect(req.query.home_url);
```
----------------------------------------------
:::warning
### 16. Open redirect (hard)
:::
**Vulnerable parts:**
```
Although we cannot explicitly use the dot character, we can find
different ways to bypass the blacklist. In example we could use
the following techniques:
- double encoding: https://google%252ecom
- UTF-8 encoding: https://google.com%E3%80%82com
```
**Suggestions for correction:**
I sincerely do not understand why the blacklist was applied. But it's good if it's applied. Let's imagine of something else? I suggest further limiting redirection as follows:
```
<script language="JavaScript" type="text/javascript">
//<![CDATA[
window.onbeforeunload = function(){
return 'Are you sure you want to leave?';
};
//]]>
</script>
```
----------------------------------------------
:::warning
### 17. Insecure file upload
:::
**Vulnerable parts:**
```
http://localhost:5000/img/Test.png
```
**Suggestions for correction:**
These minimum restrictions should be applied when handling file uploads:
* the file upload folder to restrict untrusted files to a specific folder.
* the file extension of the uploaded file to prevent remote code execution.
Also the size of the uploaded file should be limited to prevent denial of service attacks. This requirement is covered by the rule `{rule:javascript:S5693}`.
```
const Formidable = require('formidable');
const form = new Formidable(); // Compliant
form.uploadDir = "./uploads/";
form.keepExtensions = false;
```
----------------------------------------------
:::warning
### 18. Remote file inclusion
:::
**Suggestions for correction:**
Perhaps the solution will be to whitelist files, but this is not the best solution in terms of scalability, but it will do for this case.
----------------------------------------------
:::warning
### 19. SQLI (union select)
:::
**Suggestions for correction:**
This laboratory work already provides an example of a possible fix for this vulnerability. I'm talking about using array syntax to pass values to a query.
```
db.get("SELECT pageId, title, content FROM pages WHERE pageId=?", [
req.params.pageId,
]);
```
Or another option, the node-mysql module has a built-in method for escaping query values, which can be used as follows:
```
connection.query('SELECT pageId, title, content FROM pages WHERE pageId = ' + connection.escape(req.body.pageId), (error, results) => {
if (error) throw error;
// ...
});
```
----------------------------------------------
:::warning
### 20. SQLI - like
:::
**Vulnerable parts:**
```
http://localhost:5000/home/Admin%25' union select
UserName,Password from users limit 0,1--
```
**Suggestions for correction:**
Those allowing user input to be passed directly to the limit and offset functions are vulnerable to SQL injection. Database drivers such as MySQL and Postgres are not affected by this vulnerability. You may workaround this vulnerability by ensuring that only integers are passed to the `limit` and `offset` functions, as well as the `skip` and `take` functions.
----------------------------------------------
:::warning
### 21. SQLI - blind
:::
**Vulnerable parts:**
```
db.get(
"SELECT pageId, title, content FROM pages WHERE pageId=" + req.params.pageId
);
```
**Suggestions for correction:**
To protect against SQL injection, you should never allow the user to change the syntax of SQL statements. In fact, the best protection is the complete isolation of the Web application with SQL. All SQL statements required by the application must be stored in procedures on the database server. Use parametrized queries. Do not concatenate strings in your queries (code for example):
```
String custname = request.getParameter("Username");
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";
PreparedStatement pstmt = connection.prepareStatement( query );
pstmt.setString( 1, custname);
ResultSet results = pstmt.executeQuery( );
```
----------------------------------------------
:::warning
### 22. Insecure direct object reference
:::
**Vulnerable parts:**
```
http://foo.bar/somepage?invoice=12345
```
**Suggestions for correction:**
Use a hash to replace the direct identifier.
----------------------------------------------
:::warning
### 23. Right to left override attack
:::
**Suggestions for correction:**
Detection methods should include looking for common formats of RTLO characters within filenames such as `\u202E`, `[U+202E]`, and `%E2%80%AE`.
[Source of implementation](https://github.com/nextcloud/server/pull/10030)
----------------------------------------------
:::warning
### 24. Rate-limiting
:::
**Vulnerable parts:**
```
hydra -l devteam -P ./rockyou-40.txt 0.0.0.0 -s 5000 http-post-
form "/:username=^USER^&password=^PASS^:F=Invalid"
```
**Suggestions for correction:**
I think this is a good suggestion for implementing a timeout. Bruteforce at a speed of less than a dozen passwords per minute will quickly cease to be interesting. A legitimate user will wait for his 10 seconds and log in successfully.
```
request.incrementResolverCount = function () {
var runTime = Date.now() - startTime;
if (runTime > 10000) { // a timeout of 10 seconds
if (request.logTimeoutError) {
logger('ERROR', `Request ${request.uuid} query execution timeout`);
}
request.logTimeoutError = false;
throw 'Query execution has timeout. Field resolution aborted';
}
this.resolverCount++;
};
```
----------------------------------------------
:::warning
### 25. Regex Ddos
:::
**Vulnerable parts:**
```
const re =
/^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@{1}([0-9a-zA-Z][-\w]*[0-
9a-zA-Z]\.)+[a-zA-Z]{2,9})$/;
```
**Suggestions for correction:**
So, just use timeout? [all the answers are on the surface](https://dzone.com/articles/regular-expressions-denial)
```
const string emailregexpattern = @"^([0-9a-za-z]([-.\w]*[0-9a-za-z])*@([0-9a-za-z][-\w]*[0-9a-za-z]\.)+[a-za-z]{2,9})$";
[testmethod]
public void validateemailaddress()
{
var emailaddress = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!";
var watch = new stopwatch();
watch.start();
//timeout of 5 seconds
try
{
regex.ismatch(emailaddress, emailregexpattern,
regexoptions.ignorecase,
timespan.fromseconds(5));
}
catch (exception ex)
{
ex.message.assert_not_null();
ex.gettype().assert_is(typeof(regexmatchtimeoutexception));
}
finally
{
watch.stop();
watch.elapsed.seconds().assert_size_is_smaller_than(5);
watch.reset();
}
}
```
----------------------------------------------
:::warning
### 26. Command injection
:::
**Suggestions for correction:**
The main protection is to avoid calling OS commands directly. And if we run our application from root, it's not worth saying later that life is not very easy.
```
Characters that need to be filtered: <>&*'!-?; [] Ah~! . " % @ \ '
```
----------------------------------------------
:::warning
### 27. Command injection (easy)
:::
**Vulnerable parts:**
```
log_type='whoami'
```
**Suggestions for correction:**
The same situation, it is necessary to prohibit passing special characters, because in this case log_type passes part of the file name.
----------------------------------------------
:::warning
### 28. Command injection (harder)
:::
**Vulnerable parts:**
```
the application renders the system call from index.html to run
and display OS command output.
```
**Suggestions for correction:**
In Java, use ProcessBuilder, and the command should be separated from its arguments.
----------------------------------------------
:::warning
### 29. Information disclosure 1
:::
**Vulnerable parts:**
```
<div>
<! --- admin:admin --->
</div>
```
**Suggestions for correction:**
It's fun, I think, to solve this vulnerability, it is necessary to fire the developer who wrote the password and login for access to the admin in the comments in the html code.
```
<div>
<! --- Who am I? Why I made desicion to be a web-developer?.. Mb that's not for me... --->
</div>
```
<center>
<img src="https://i.imgur.com/h52hXQT.png" width="250" height="200">
It was the last straw in this tragically sad ocean of mini-labs
<iframe width="110" height="200" src="https://www.myinstants.com/instant/hello-darkness-my-old-friend/embed/" frameborder="0" scrolling="no"></iframe>
</center>
----------------------------------------------
:::warning
### 30. Information disclosure 2
:::
**Vulnerable parts:**
```
<meta name="author" content="admin">
```
**Suggestions for correction:**
Of course, when determining the meta name, the content value must also be filled in, but not with this...
```
<meta name="author" content="The cleverest person in this company ">
```
<center>
<iframe width="110" height="200" src="https://www.myinstants.com/instant/emotional-damage-meme-74555/embed/" frameborder="0" scrolling="no"></iframe>
</center>
----------------------------------------------
:::warning
### 31. Authentication bypass (easy)
:::
**Vulnerable parts:**
```
if (row) {
req.session.userId = row.UserId;
req.session.secret = "e5ac-4ebf-03e5-9e29-a3f562e10b22";
req.session.loggedIn = true;
db.get(api, [req.session.userId], (err, row) => {
res.render("home.ejs", { api: row.API_key });
});
} else {
res.render("index.ejs");
```
**Suggestions for correction:**
It is impossible to prevent session interception in advance, but it can be detected and mitigated. For example, using salt for a hash. The `HttpOnly` attribute will help reduce the threat of cross-site scripting by blocking access to cookies from JavaScript. Cookies used for responsible operations should have a short validity period.
----------------------------------------------
:::warning
### 32. Authentication bypass
:::
**Vulnerable parts:**
```
We notice that with every login, the session cookie stays
the same. It is high likely that this sessionid is related
to our user name
```
**Suggestions for correction:**
What we could consider is the use of geolocation. If, after five minutes, the session ID created for a user in Innopolis is suddenly used by someone in Romania, this may be a sign that something is wrong. Yes, this may disturb VPN users, but it is not necessary to restrict strictly, you can send alerts. Make sure that you generate long, random session ID (with a CSPRNG). Also, make sure you are not vulnerable to session fixation by not accepting session ID you have not generated yourself and/or changing the session ID on login. The counteraction to session fixation is to create a new session identifier (SID) for each request.
----------------------------------------------
:::warning
### 33. Authentication bypass (harder)
:::
**Vulnerable parts:**
```
"admin" as a salt
```
**Suggestions for correction:**
The best solution would be not to use human and short words as salt. To create such cryptographically reliable random data, we can use a cryptographically secure pseudorandom number generator (CSPRNG).
----------------------------------------------
:::warning
### 34. Authentication bypass (hard)
:::
**Vulnerable parts:**
```
GET /users/user02? HTTP/1.1
```
**Suggestions for correction:**
I think this is a [brilliant article](https://inonst.medium.com/a-deep-dive-on-the-most-critical-api-vulnerability-bola-1342224ec3f2) and all further explanations are meaningless. We need a mechanism to verify the user's access rights to the requested content. Therefore, when the user user01 wants to go to the user02 point, the system should check whether he has such rights (I'm not talking about viewing the user02 page, but about going to the internal environment of this user, as intended in the case).
----------------------------------------------
:::warning
### 35. HttpOnly (session hijacking)
:::
**Vulnerable parts:**
```
we find HttpOnly attribute and see that it is not activated
for this application
```
**Suggestions for correction:**
Rule No. 1. Do all authorization cookies HttpOnly.
And all critical actions on the part of an authorized user must require the introduction of a password (I think this line can be used in all cases).
----------------------------------------------
## References:
1. [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
2. [OWASP: Unrestricted File Upload](https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload)
3. [JS Module Formidable](https://www.npmjs.com/package/formidable)
4. [SQKLI](https://www.imperva.com/learn/application-security/sql-injection-sqli/?redirect=Incapsula)
5. [Cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies)
6. [Session fixation](https://en.wikipedia.org/wiki/Session_fixation)