Securing

your

frontend web app

>

_

  • Why should you care about security ?
  • Who are you defending against ?
  • What are the types of web attacks and vulnerabilities ?
  • How do you defend against web attacks ?

Why should you care about security?

Who are you defending against ?

Motives

  • Money
  • Political or ideology
  • Fun

What are the type of web attacks and vulnerabilities ?

  1. Broken Access Control
  2. Cryptographic Failures
  3. Injection
  4. Insecure Design
  5. Security Misconfiguration
  6. Vulnerable and Outdated Components
  7. Identification and Authentication Failures
  8. Software and Data Integrity Failures
  9. Security Logging and Monitoring Failures
  10. Server-Side Request Forgery

(Open Worldwide Application Security Project)

  1. Out-of-bounds Write
  2. Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
  3. Out-of-bounds Read
  4. Improper Input Validation
  5. Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')
  6. Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
  7. Use After Free
  8. Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
  9. Cross-Site Request Forgery (CSRF)
  10. Unrestricted Upload of File with Dangerous Type
  11. Missing Authentication for Critical Function
  12. Integer Overflow or Wraparound
  13. Deserialization of Untrusted Data
  14. Improper Authentication
  15. NULL Pointer Dereference
  16. Use of Hard-coded Credentials
  17. Improper Restriction of Operations within the Bounds of a Memory Buffer
  18. Missing Authorization
  19. Incorrect Default Permissions
  20. Exposure of Sensitive Information to an Unauthorized Actor
  21. Insufficiently Protected Credentials
  22. Incorrect Permission Assignment for Critical Resource
  23. Improper Restriction of XML External Entity Reference
  24. Server-Side Request Forgery (SSRF)
  25. Improper Neutralization of Special Elements used in a Command ('Command Injection') 

(Common Weakness Enumeration)

How to defend from web attacks?

Defense
In
Depth

User input fields and output

Not validating user input fields for unsafe characters

Picture source: Web security for developers

User input fields and output

Not validating user input fields for unsafe characters

Picture source: Web security for developers

  • Sanitize content received from any user input using a secure sanitizing library eg
    • sanitize-html 

User input fields and output

import sanitizeHtml from 'sanitize-html';

const html = "<strong>hello world</strong>";
console.log(sanitizeHtml(html));
console.log(sanitizeHtml("<img src=x onerror=alert('img') />"));
console.log(sanitizeHtml("console.log('hello world')"));
console.log(sanitizeHtml("<script>alert('hello world')</script>"));

// Allow only a super restricted set of tags and attributes
const clean = sanitizeHtml(dirty, {
  allowedTags: [ 'b', 'i', 'em', 'strong', 'a' ],
  allowedAttributes: {
    'a': [ 'href' ]
  },
  allowedIframeHostnames: ['www.youtube.com']
});

User input fields and output

var search = document.getElementById('search').value;
var results = document.getElementById('results');
//unsafe
results.innerHTML = 'You searched for: ' + search;
You searched for: <img src=1 onerror='/* Bad stuff here... */'> 
  
//safe
results.innerText = 'You searched for: ' + search;
  • Use innerText instead of innerHTML to display user input

User input fields and output

{{ data }}
//Vue
<div v-html="htmlData"></div>
////React 
return <div dangerouslySetInnerHTML={createMarkup()} />;
//Angular
<div [innerHTML]='<a href="#">Unescaped link</a>'</div>
//Vue
{{constructor.constructor('alert(1)')()}}

<teleport to=script:nth-child(2)>alert&lpar;1&rpar;</teleport></div><script></script>

<component is=script text=alert(1)>

{{$el.ownerDocument.defaultView.alert(1)}}

User input fields and output

Content-Security-Policy: script-src 'self' https://api.foo.com
<meta http-equiv="Content-Security-Policy" content="script-src 'self' https://api.foo.com">

Real world story 📖

British Airways - 2018

https://www.dooble.com/search?q=tesla
https://www.dooble.com/search?q=<script>alert("hacked!")</script>

URL parameters

Not validating query and search params

//const queryString = window.location.search;
const queryString = sanitize(window.location.search);

const urlParams = new URLSearchParams(queryString);

//document.getElementById('searchValue').innerHTML = urlParams.get("q");
document.getElementById('searchValue').innerText = urlParams.get("q");

URL parameters

  • Sanitize parameter key values
https://vulnerable-website.com/?__proto__[evilProperty]=payload

targetObject.__proto__.evilProperty = 'payload';


Object.freeze(Object.prototype);

URL parameters

  • Prevent prototype pollution for injection keys like __proto__
    • Using an allowlist of permitted keys
    • prevent prototype objects from being changed 
https://example-website.com/login/home.html?admin=true
https://example-website.com/login/home.html?id=876

URL parameters

Exposure via URL redirect parameters

  • Avoid exposure of roles in the the params
  • Handle access control for every request of page resource
https://example-website.com/user
https://example-website.com/admin
https://example-website.com/admin_293399288

Page URL pathname

Exposing web page to non-admin

<script>
let isAdmin = false;
.....
if (isAdmin) {
  redirectToPage('/admin_293399288');
  setHeaderText("Welcome To Admin Page");
}
</script>

Page URL pathname

  • Proper access control to restricted pages
  • Access control check for every page resource
  • Deny access by default
  • Functional tests
  • use non-disclosing description for variable and function names

 

Real world story 📖

U.S. Department of Defense website - Sept 2020

Hardcoding

Avoid exposure of secrets and credentials

  • hardcoding secrets, passwords, API keys in source code, eg in HTML, Javascript, or any configuration file.

 

<!-- Use the DB administrator password for testing:  f@keP@a$$w0rD -->
// or in script
const myS3Credentials = {
  accessKeyId: config('AWSS3AccessKeyID'),
  secretAcccessKey: config('AWSS3SecretAccessKey'),
};

Hardcoding

 

  • Store the credentials in
  • Use scanning tools to scan for accidental exposure of sensitive info in your code , eg Github code scanning
  • If a password has been disclosed through the source code: change it.

Error Message

Picture source: Microsoft learn

try {
  //code
} catch(error) {
  console.log(error);
}

Error Message

Picture source: tutorial.eyehunts.com

Error Message

  • Log generic error message without giving specifics
  • disable log visibility in production
  • log using standard logging tools securely
  • log just enough data to debug
  • mask Personal Identifiable Information (PII)
  • unit and functional tests

 

try {
  //code
} catch(error) {
  console.log("There seems to be an error!");
}

Real world story 📖

Node js libraries hiding crypto miners - Oct 2021

3rd party libraries & data

Other areas 

  • Authentication
  • Business logic
  • File Uploads
  • Iframes
  • Network requests
  • Local storage

Secure Development Cycle

  • Secure coding with tests
  • Review code for vulnerabilities 
  • Use Automated Security Scanning Tools
  • Enable dependabots
  • Security training and learning
  • Spread security awareness 

Free online learning resources

Summary

 

  • How do you defend against web attacks ?
    • Defense In Depth
      • Input fields and output
      • URL parameters & pathname
      • Hardcoding sensitive data
      • 3rd party libraries & data
    • Secure Development Cycle

Thank you

slides

Developer week: Securing Frontend Web App

By Mariam Reba Alexander

Developer week: Securing Frontend Web App

  • 177