WEB APPSEC 101Andrii Kudiurov
TeamLead @ SoftSeq
About me
- Python programming background- Current job: Teamlead @ SoftSeq (Web app audits &
certification, embedding Secure SDLC)- Successfully hacked banking, trading, insurance, security, mailing
providers, etc.
Plan1. Basic knowledge to start2. Never trust user input. How HTTP works.3. Misconfiguration4. Hidden options && forced navigation && mass parameter
assignment5. CSRF6. Injection
a. XSSb. SQLic. OS Command injection
7. open redirect8. path traversal9. DoS due to application logic errors
10. Basic HOWTO11. Links12. Questions
What?- Understanding common bugs that allows
doing something evil =)- Web app vulnerabilities are based inside the app itself (web appsec !=
pentest)
How?- There’s a lot of info. I’ve tried to explain vulnerabilities that can be found
by QA during testing routine. See links to get more HOWTO
Baseline- How web app, browser and HTTP works, basic HTML- Any programming language, including (very)basic JS
Tools- Browser + FoxyFroxy + BurpSuite- Google =)
Misconfiguration
- Opened ports- Default or no passwords (e.g. RabbitMQ)- Backup, .git and other sensitive folders accessible- Default or unnecessary features enabled- No pre-authorization to staging/testing environment- Security headers missing (e.g. iframe is allowed: UI redress aka Clickjacking)- Bad pseudorandom used for password/key/pin generation- No “Secure”, “HTTPOnly” cookie flags, allowed subdomains and insecure path- Using components with known vulnerabilities- And more…
Good news: automated scanners can find it pretty well.
Components with known vulnerabilities
- Remember Equifax? They forgot to update library- Average small app can have ~ 20-40 dependencies- Enterprise apps can have over 200 dependencies
Components with known vulnerabilities
Basic rule: if there is info that component is vulnerable it doesn’t matter if you can show how to exploit it. UPDATE! Search vulnerabilities at https://cve.mite.org or https://nvd.nist.gov/
Try to find some of them automatically (all of them can be found ONLY manually because of reasons =) )
- Dependency checker (ASP, Java)- Retire.js (vulnerable forntend libs)
Directory Browsing
Use Dirbuster and/or burpsuite plugins to detect
Click-jacking AKA UI Redress
<form action=”changemail”><input name=”email”value=”[email protected]”>
<input type=hidden name=”id” value=”123”>
<button action=”submit” value=”save”>
</form>
<script>//script that checks that user entered everything correctly and didn’t modify ID</script>
HTTP. Recall.
User pushes button toSave profile
Browser adds headers, cookies andMakes request
POST /save HTTP/1.1Host: bank.comCookies: auth=abcdi848d;Content-length: 123Connection: close
[email protected]&id=123
HTTP. Recall.
User pushesbutton toSave profile
Browser adds headers, cookies andMakes request
POST /save HTTP/1.1Host: bank.comCookies: auth=abcdi848d;Connection: close
[email protected]&id=123
PROXY-SERVER
POST /save HTTP/1.1Host: bank.comCookies: auth=abcdi848d;Connection: close
[email protected]&id=124
<div class=’comment’>…..</div><button value=”answer” action=”createAnswer()”>
<div class=’comment’>…..</div><button value=”answer” action=”createAnser()”><button value=”edit” action=”editPost()”>
Direct object reference examples:
- Yahoo: deleting ~ 1m comments and posts- Apple: 300k 3rd party developers accounts- FB, VK, Instagram photos- Some hackers who tried to f*** fortune 100 companies
but totally blew it by exposing all info for scum emails- Common anti-automation problem
Mass parameter assignment
User input:
DB model:- ID- Email- IsBlocked
- Some app controllers may process not user input itself, but a model created from the input to ease coding routine.
- In this case if no additional anti-forgery measures have been implemented, it is possible to add additional parameters
What does it mean?
- No decision making on frontend pls- Never trust user input. Consider any user input as harmful.- Input validation on frontend - for UX, on backend - for decision making
More thinking…
- Humans make mistakes- Developers think how to MAKE, not how to BREAK- Parts written by several developers can be VERY different (one controller can
be totally secure,another - totally broken)
- Companies with TOP developers and good security teams still are getting hacked or reported by whitehats
CSRF (Cross site request forgery)
Root problem:Browser sends cookies automatically for every URL or submitted form.
Exploit:We can craft a form on a web-site we control and force a user to perform request with desired parameters to a desired resource
Fix:Unpredictable anti-CRSF token (as one of the parameters in POST queries)
<form action=”http://bank.com/changemail”><input name=”mail”value=”[email protected]”><button id=”x” action=”submit”></form><script>x=document.getElementById(“x”).click()</script>
<form action=”changemail”><input name=”mail”value=”[email protected]”><button action=”submit”></form>
XSS: (very) short info
- An ability to inject malicious JavaScript to the legitimate site- Happens when server sends back user-generated data
without validation and sanitization- Usually exploited by embedding HTML tags or breaking JS
syntax
http://example.com?search=asd”><script>alert(“hacked”)</script>
Two simple rules to prevent XSS:1. All user input that comes back from server should be SANITIZED by
trusted functional (e.g. template engine).2. NEVER write your own filters. They probably can be hacked.
WHY?
<scr<script>ipt>
<img src=x onerror=’alert(1)’>
<a href=”javascript:alert(1)”>click me</a>
<IMG SRC=javascript:alert('XSS')>
<IMG SRC="jav	ascript:alert('XSS');">
<BODY onload!#$%&()*~+-_.,:;?@[/|\]^`=alert("XSS")>
<iframe src=http://xss.rocks/scriptlet.html <
<STYLE>li {list-style-image: url("javascript:alert('XSS')");}</STYLE><UL><LI>XSS</br>
<META HTTP-EQUIV="refresh" CONTENT="0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K">
"'}})}}})});alert('hacked'); window.addEventListener('load', function() { new Vue({ methods:{ filter:function(){$.ajax({data:{a:'"
Own filter = bad idea
SQL Injection
- Happens when user input is passed to SQL query so it can be modified.
For example, user is trying to access some user item:SELECT * FROM items WHERE itemname = 'secret_unique_id';
- If we have control over ‘secret_unique_id’, we can submit special syntax and receive all items.
Like:SELECT * FROM items WHERE itemname = 'secret_unique_id' OR 'a'='a';
SQL Injection
- Not very common in the new projects- Exists because user input is not validated and for some reason raw SQL
queries are still used.- Easier to search in the source code rather than blackbox
SQL Injection hints
- Easily avoided if ORM/parameterized queries are used- Some ORM-parameters can be still exploited, read specs!- Check stored procedures!
- Even if you think everybody is writing in a secure manner, someone probably have used raw SQL to execute a complex query
OS Command Injection
- Accepting user input inside OS command invocation- Can be easily found in the source code by keywords
Cases:- Proto and video modification (imagemagic, ffmpeg)- Operations with files, folders, systems (e.g. some deploy platforms)
Example 1:
Old-school zero-bytewww.example.com/get-the-page%00
DOS via application logic errors
Example 2: Modern world
www.cute-images.com/image/cute_puppy.png?width=100&height=100www.cute-images.com/image/save/resize/cute_puppy.png?width=100&height=100
….what if?
www.cute-images.com/image/cute_puppy.png?width=2147483647&height=2147483647www.cute-images.com/image/save/resize/cute_puppy.png?width=2147483647&height=2147483647
DOS via application logic errors
Open redirect.Case:1. User tries to reach URL, but he is not logged in.2. For better UX, user should be redirected to login page and after — back to the
page he requested
Example:User tries to reach http://example.com/page12134User is redirected to http://example.com/login?redirect=/page1234
But what if we make user to follow link like this:http://example.com/login?redirect=http://exampIe.com
Path traversalUsually happens when user input is feeded directly in file path parametere.g. f = open(“FOLDER_NAME” + user_input_file, “r”)
Basic “How to test”BlackBox:
- Check how application handles unexpected data (single/double quotes, <>, %0a%0d%00, etc.)
- Simple XSS test: '';!--"<XSS>=&{()}- Simple SQLi test: 1' or '1' = '1- Path traversal ../../../../../../../etc/passwd (or other known file)- directory browsing and open folders DIRBUSTER (careful, can DOS the server)- CSRF: check if anti-csrf token is present AND it’s required- OS command injection: if something looks like shell command - try to insert
another
Desired result: unpredicted behavior or errors.
WhiteBox (access to source code)Easy:
1. Find OWASP Code review guide2. Find desired language and search for keywords, review them.3. For frontend - search for .innerHTML, eval(), $.html (there is more. Search for
your framework)
Automation doesn’t work (as good as expected) becauseCONTEXT MATTERS.Automated solutions find
- hundreds of false-positives- Can’t find not obvious vulnerabilities
But:- Better than nothing- Can work better for some projects- Detects misconfiguration- Can be tweaked and proxied to perform better for you
Info and literature:1. GOOGLE2. Our appsec knowledge checklist: link
a. Some playgrounds: p.5-103. OWASP ASVS (standard), OWASP Testing Guide at https://owasp.org 4. Web Application hacker’s handbook
Thank you!
Any questions?FB: Andrii Kudiurov