Difference between revisions of "Security course 30 April 2018"
(15 intermediate revisions by the same user not shown) | |||
Line 6: | Line 6: | ||
;NZISS: New Zealand Internet Security Standard | ;NZISS: New Zealand Internet Security Standard | ||
− | Restrict database access to only the tables required, use a minimum of stored procedures to hide sensitive tables entirely (e.g. an AUTHENTICATE() stored | + | Restrict database access to only the tables required, use a minimum of stored procedures to hide sensitive tables entirely (e.g. an AUTHENTICATE() and GET_PROFILE() stored procedures, and no access to the USER table. |
CREATE FUNCTION AUTHENTICATE(u TEXT, p TEXT) RETURNS TABLE (username TEXT, property1, TEXT, ...) AS $$ | CREATE FUNCTION AUTHENTICATE(u TEXT, p TEXT) RETURNS TABLE (username TEXT, property1, TEXT, ...) AS $$ | ||
BEGIN | BEGIN | ||
− | SELECT username, property1, ... FROM users WHERE username = u, password = | + | SELECT username, property1, ... FROM users WHERE username = u, password = DIGEST(p, 'SHA256'); |
END; | END; | ||
$$ LANGUAGE plpgsql; | $$ LANGUAGE plpgsql; | ||
Line 48: | Line 48: | ||
# Use appropriate URL encoding (/ = %2f) and HTML encoding (& = &) | # Use appropriate URL encoding (/ = %2f) and HTML encoding (& = &) | ||
# Use HTTPS Strict Transport Security, Content Security Policy, and HTML frame options. | # Use HTTPS Strict Transport Security, Content Security Policy, and HTML frame options. | ||
+ | |||
+ | == Use the headers == | ||
+ | |||
+ | * HSTS: enforces HTTPS, ciphers, etc. 6-24 months recommended. | ||
+ | * CSP: restricts scripts, frames, styles etc. Generate one, at https://report-uri.com/home/generate | ||
+ | * X-Frame-Options prevents click-jacking; potentially obsoleted by the new frame bits in CSP 2. | ||
+ | * X-XSS-Protection: IE and Webkit support this, but it can be disabled(!?) | ||
+ | * Prevent MIME type sniffing: X-Content-Type-Options: nosniff | ||
+ | * Prevent information leakage (e.g. Apache version string). | ||
+ | * Disable page caching for certain HTTPS sensitive URLs | ||
+ | |||
+ | == Evil User Stories == | ||
+ | |||
+ | Use evil stories for testing: | ||
+ | |||
+ | : ''"As a hacker, I need to add random shit to the URL in order to get access to stuff I don't have access to."'' | ||
== OWASP == | == OWASP == | ||
Line 57: | Line 73: | ||
* Zed Attack Proxy (ZAP) | * Zed Attack Proxy (ZAP) | ||
− | === Injection === | + | === A1: Injection === |
− | Not just SQL. NoSQL, XML, serialisation, etc. Routers sometimes let you inject shell commands. Havoc ensues. | + | Not just SQL. NoSQL, XML, serialisation, etc. Routers sometimes let you inject shell commands. Havoc ensues: |
+ | ping $input | ||
+ | Allows for | ||
+ | google.com; cat /etc/passwd | ||
− | === Broken Authentication === | + | === A2: Broken Authentication === |
Credentials not protected when stored or transmitted, or can be guessed, or overwritten. Fun with badly handled session IDs, exposed in URLs, stored plain-text in cookies, not regenerated after login, not expired on logout. Timing attack on authentication queries and other requests can give a true/false verification and can figure out database structure (e.g. true takes longer, false fails immediately), etc. | Credentials not protected when stored or transmitted, or can be guessed, or overwritten. Fun with badly handled session IDs, exposed in URLs, stored plain-text in cookies, not regenerated after login, not expired on logout. Timing attack on authentication queries and other requests can give a true/false verification and can figure out database structure (e.g. true takes longer, false fails immediately), etc. | ||
Line 78: | Line 97: | ||
Telling browsers not to cache input field values: <tt>autocomplete="off"</tt> great for card details, but in a password field, blocks password managers. So HTML5 allows password managers to override page instructions, so browsers started ignoring autocomplete for password fields. | Telling browsers not to cache input field values: <tt>autocomplete="off"</tt> great for card details, but in a password field, blocks password managers. So HTML5 allows password managers to override page instructions, so browsers started ignoring autocomplete for password fields. | ||
− | === Sensitive data exposure === | + | === A3: Sensitive data exposure === |
# Transmitted in clear-text over a network. | # Transmitted in clear-text over a network. | ||
Line 88: | Line 107: | ||
# Use encryption! | # Use encryption! | ||
+ | #* Use the Mozilla [https://mozilla.github.io/server-side-tls/ssl-config-generator/ SSL configuration generator] | ||
# Use strong encryption! | # Use strong encryption! | ||
+ | #* Click "modern" | ||
# Use ACLs! | # Use ACLs! | ||
# Delete temporary or ephemeral data, and data that's no longer required. Don't cache sensitive data on the client. | # Delete temporary or ephemeral data, and data that's no longer required. Don't cache sensitive data on the client. | ||
Line 98: | Line 119: | ||
* Hashing algo: SHA2, 256, 384, 512 bits. | * Hashing algo: SHA2, 256, 384, 512 bits. | ||
* Asymmetric PK algo: Elliptic Curve Diffie-Hellman (ECDH), Elliptic Curve Digital Signature Algorithm (ECDSA). | * Asymmetric PK algo: Elliptic Curve Diffie-Hellman (ECDH), Elliptic Curve Digital Signature Algorithm (ECDSA). | ||
+ | |||
+ | === A4: XML External Entities (XXE) === | ||
+ | |||
+ | XML allows you to define your own entities: | ||
+ | |||
+ | <!ENTITY [%] name [] ... > | ||
+ | |||
+ | Most XML parsing libraries are now sensibly configured not to do this sort of crazy advanced shit that nobody really uses anyway, for example: | ||
+ | |||
+ | <!ENTITY xxe "file:///etc/passwd"> | ||
+ | &xxe; | ||
+ | |||
+ | The [https://en.wikipedia.org/wiki/Billion_laughs_attack Billion LOLZ] attack will make any mis-configured server go dark: | ||
+ | |||
+ | <!ENTITY lol0 "LOL"> | ||
+ | <!ENTITY lol1 "&lol0;&lol0;&lol0;&lol0;&lol0;&lol0;&lol0;&lol0;&lol0;&lol0;"> | ||
+ | <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;"> | ||
+ | <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;"> | ||
+ | <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;"> | ||
+ | <!ENTITY lol5 ... etc. | ||
+ | &lol9 | ||
+ | |||
+ | Anything that uses SOAP, SAML, or any other XML APIs are potentially vulnerable. | ||
+ | |||
+ | ==== Prevention ==== | ||
+ | |||
+ | # Don't use XML! Use something simpler that only has keys and values, e.g. JSON. | ||
+ | # Use a well-supported, standard XML parsing library, keep it up to date | ||
+ | # disable the advanced DTD and ENTITY "features" by default. | ||
+ | # Use whitelist input validation on the XML data, use XSD validation | ||
+ | |||
+ | === A5: Broken Access Control === | ||
+ | |||
+ | # (A4 insecure direct object references) e.g. access to an uploaded file, or REST API URL, without auth/authz, e.g. press releases under embargo. | ||
+ | # (A7 Missing Functional Level Access Control). e.g. URL diecovery, enumerating objects by URL - e.g.: | ||
+ | #* /invoices/12345 | ||
+ | #* /users/123/profile | ||
+ | #* /getfile?file=../../../../etc/passwd | ||
+ | #* /set_salary?employee=1234&'''salary=1,000,000''' | ||
+ | |||
+ | ==== Prevention ==== | ||
+ | |||
+ | # Always perform access control checks for each request (use a web framework!) | ||
+ | # ACL must be performed on the server, never rely on the client. | ||
+ | # Perform ACL checks using only data the user can't tamper with. | ||
+ | # Don't use traversable direct references - use per user or per session refs, or UUIDs instead. | ||
+ | |||
+ | === A6: Security Misconfiguration === | ||
+ | |||
+ | Can happen all over the place up and down the stack, from the server filesystem to the browser-side JavaScript. | ||
+ | |||
+ | ==== Prevention ==== | ||
+ | |||
+ | Approved, defined configuration hardening. | ||
+ | Turn everything off by default, in production only install what is necessary and being used. | ||
+ | Disable stack traces, debug options, and verbose logging in production (and production-like) environments. | ||
+ | Use scanning tools, e.g. OpenVAS, Nessus, Qualys, nmap etc. | ||
+ | |||
+ | === A7: Cross-Site Scripting (XSS) === | ||
+ | |||
+ | When an app displays unfiltered user-supplied data on an HTML page. Hijacking user session or the browser, to access other things on the PC, or just defacing (pwnd) websites. Can be stored (into the database) or just reflected (when a form is submitted and displayed). Very simply, adding this to an form postal address field: | ||
+ | |||
+ | <script>alert(document.cookie);</script> | ||
+ | |||
+ | ==== Prevention ==== | ||
+ | |||
+ | # Input validation | ||
+ | # Escape and encode all input | ||
+ | # Filter all output | ||
+ | # Use a Content Security Policy HTTP header. | ||
+ | |||
+ | # Example WordPress E-Commerce site: | ||
+ | Content-Security-Policy: default-src: self; style-src: self; <nowiki>connect-src: https://api.stripe.com; \ | ||
+ | frame-src self https://js.stripe.com; script-src self https://js.stripe.com</nowiki> | ||
+ | |||
+ | Intercepting proxies, e.g. OWASP ZAP (Zed Application Proxy). Can investigate traffic between browser and internet; can also scan sites for potential vulnerabilities. ZAP runs on Java 8+, set up browsers to use a localhost:xxxx proxy. | ||
+ | |||
+ | === A8: Insecure Deserialisation === | ||
+ | |||
+ | Deserialisation can be really bad, e.g. XML (see above). | ||
+ | |||
+ | ==== Prevention ==== | ||
+ | |||
+ | * Do cryptographic integrity checks | ||
+ | * Isolate deserialisation at the lowest priv possible | ||
+ | * Restrict network connectivity from containers doing the deserialising | ||
+ | * Log desz exceptions and failures | ||
+ | * Alert repeated desz attempts | ||
+ | |||
+ | === A9: Using components with known vulns === | ||
+ | |||
+ | OS, databases, webservers, scripting languages, caching stores, app frameworks, 3rd party application plugins and widgets, JS libraries, ... | ||
+ | |||
+ | ==== Prevention ==== | ||
+ | |||
+ | # Keep your shit patched | ||
+ | # Don't use crummy plugins / Don't run someone else's code in production you haven't audited yourself | ||
+ | |||
+ | === A10: Insufficient logging and monitoring === | ||
+ | |||
+ | If you're not logging, you can't find out what happened. If you're not monitoring, you can't react in time. If you're not doing either, then Ô__o. Most breaches are not detected for several months after they have happened. | ||
+ | |||
+ | ==== Prevention ==== | ||
+ | |||
+ | # Ensure your logs are digestible by some central logging management system (collectd, ES, kibana, etc.) | ||
+ | # Ensure security sensitive things are logged with sufficient context; validation failures, username, IP, user agent, ACL etc. | ||
+ | # Monitor logs. | ||
+ | |||
+ | === Cross-Site Request Forgery (CSRF) === | ||
+ | |||
+ | # Prevent by using an unpredictable one-use short-lived token in a hidden field, and ensure validity. | ||
+ | # Use a CAPTCHA or similar. | ||
+ | # Use a web framework. | ||
+ | # Set the 'SameSite' cookie attribute; prevents cookies on cross-origin requests. Since Chrome 55, Firefox 60. https://caniuse.com#search=SameSite | ||
+ | |||
+ | == Links and further reading == | ||
+ | |||
+ | * OWASP: https://www.owasp.org/ | ||
+ | * Scan your site with the Mozilla Observatory: https://observatory.mozilla.org/ | ||
+ | * Check your site SSL configuration: https://www.ssllabs.com/ssltest/ | ||
+ | * SSL configuration generator: https://mozilla.github.io/server-side-tls/ssl-config-generator/ | ||
+ | * Generate a Content Security Policy header: https://report-uri.com/home/generate | ||
+ | * Check for browser capabilities: https://caniuse.com |
Latest revision as of 05:06, 30 April 2018
- ACL
- Access Control List.
- Access Control
- who can access which parts of a system, by assigning permissions to roles, users to groups, and roles to groups.
- Authentication
- confirmation of identity.
- Authorisation
- access control.
- NZISS
- New Zealand Internet Security Standard
Restrict database access to only the tables required, use a minimum of stored procedures to hide sensitive tables entirely (e.g. an AUTHENTICATE() and GET_PROFILE() stored procedures, and no access to the USER table.
CREATE FUNCTION AUTHENTICATE(u TEXT, p TEXT) RETURNS TABLE (username TEXT, property1, TEXT, ...) AS $$ BEGIN SELECT username, property1, ... FROM users WHERE username = u, password = DIGEST(p, 'SHA256'); END; $$ LANGUAGE plpgsql;
- Design software to use the lowest privilege level required to complete its tasks.
- Deny access by default.
- Check return values of all system calls.
- Validate all inputs - lengths, field types, ranges, controlled vocabularies.
Authentication
- User IDs - users must be unique. No shared 'office admin' accounts with naff passwords.
- Don't use shit passwords. Enforce minimum password complexity, use multi-factor auth, biometrics, etc.
- Encrypt user authentication data over the network (including database connections).
- Don't store passwords in clear text.
- Password management policies - e.g. time-out or reset request after x attempts, lock account after y attempts.
- Display when a user last logged in.
Auditing
Log at least these events. We need who did what, where (source IP, device ID, etc.), and when:
- User logins.
- Privileged operations e.g. create new user, role/permissions changes, etc.
- failed attempts to elevate privileges.
- failed attempts to access files, functions, services. (Was it temporarily down, or was it attacked?)
- Security-related alerts and failures.
DON'T IMPLEMENT YOUR OWN CRYPTO unless you are a professional cryptologist implementing a software cryptography library.
Input handling
Never trust anything passed in, including the URL and its parameters, HTML form data, cookie values, request headers, without validating/sanitising them.
Output handling
- Use appropriate URL encoding (/ = %2f) and HTML encoding (& = &)
- Use HTTPS Strict Transport Security, Content Security Policy, and HTML frame options.
Use the headers
- HSTS: enforces HTTPS, ciphers, etc. 6-24 months recommended.
- CSP: restricts scripts, frames, styles etc. Generate one, at https://report-uri.com/home/generate
- X-Frame-Options prevents click-jacking; potentially obsoleted by the new frame bits in CSP 2.
- X-XSS-Protection: IE and Webkit support this, but it can be disabled(!?)
- Prevent MIME type sniffing: X-Content-Type-Options: nosniff
- Prevent information leakage (e.g. Apache version string).
- Disable page caching for certain HTTPS sensitive URLs
Evil User Stories
Use evil stories for testing:
- "As a hacker, I need to add random shit to the URL in order to get access to stuff I don't have access to."
OWASP
Open Web Application Security Project. Freely available information, cheat sheets and guidelines, including:
- The OWASP Top Ten.
- Secure Coding Quick Reference Guide
- Zed Attack Proxy (ZAP)
A1: Injection
Not just SQL. NoSQL, XML, serialisation, etc. Routers sometimes let you inject shell commands. Havoc ensues:
ping $input
Allows for
google.com; cat /etc/passwd
A2: Broken Authentication
Credentials not protected when stored or transmitted, or can be guessed, or overwritten. Fun with badly handled session IDs, exposed in URLs, stored plain-text in cookies, not regenerated after login, not expired on logout. Timing attack on authentication queries and other requests can give a true/false verification and can figure out database structure (e.g. true takes longer, false fails immediately), etc.
Prevention
- Don't reinvent your wheels, use a well-supported mature web framework to handle auth/authz, sessions, etc.
- Use multi-factor authentication.
- Disable default accounts, change default passwords.
- Use a sensible password policy. Check for weak/naff passwords, show a strength indicator.
- Limit or tar-pit failed auth attempts.
- Detect/prevent account enumeration attacks on account profile, registration, recovery pages.
- Use random/hashed session IDs, use 'secure' and 'httpOnly' session cookies.
- HTTPS by default everywhere. With free LetsEncrypt certificates there's very little excuse in 2018.
Telling browsers not to cache input field values: autocomplete="off" great for card details, but in a password field, blocks password managers. So HTML5 allows password managers to override page instructions, so browsers started ignoring autocomplete for password fields.
A3: Sensitive data exposure
- Transmitted in clear-text over a network.
- Old or weak ciphers, in light of Moore's law.
- Improper leakage through incorrect ACLs or authorisation.
- Not encrypted in storage, database, on disk.
Prevention
- Use encryption!
- Use the Mozilla SSL configuration generator
- Use strong encryption!
- Click "modern"
- Use ACLs!
- Delete temporary or ephemeral data, and data that's no longer required. Don't cache sensitive data on the client.
- Safely store and handle encryption keys.
Government approved cryptography
- Symmetric algo: AES, minimum 256 bit keys.
- Hashing algo: SHA2, 256, 384, 512 bits.
- Asymmetric PK algo: Elliptic Curve Diffie-Hellman (ECDH), Elliptic Curve Digital Signature Algorithm (ECDSA).
A4: XML External Entities (XXE)
XML allows you to define your own entities:
<!ENTITY [%] name [] ... >
Most XML parsing libraries are now sensibly configured not to do this sort of crazy advanced shit that nobody really uses anyway, for example:
<!ENTITY xxe "file:///etc/passwd"> &xxe;
The Billion LOLZ attack will make any mis-configured server go dark:
<!ENTITY lol0 "LOL"> <!ENTITY lol1 "&lol0;&lol0;&lol0;&lol0;&lol0;&lol0;&lol0;&lol0;&lol0;&lol0;"> <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;"> <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;"> <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;"> <!ENTITY lol5 ... etc. &lol9
Anything that uses SOAP, SAML, or any other XML APIs are potentially vulnerable.
Prevention
- Don't use XML! Use something simpler that only has keys and values, e.g. JSON.
- Use a well-supported, standard XML parsing library, keep it up to date
- disable the advanced DTD and ENTITY "features" by default.
- Use whitelist input validation on the XML data, use XSD validation
A5: Broken Access Control
- (A4 insecure direct object references) e.g. access to an uploaded file, or REST API URL, without auth/authz, e.g. press releases under embargo.
- (A7 Missing Functional Level Access Control). e.g. URL diecovery, enumerating objects by URL - e.g.:
- /invoices/12345
- /users/123/profile
- /getfile?file=../../../../etc/passwd
- /set_salary?employee=1234&salary=1,000,000
Prevention
- Always perform access control checks for each request (use a web framework!)
- ACL must be performed on the server, never rely on the client.
- Perform ACL checks using only data the user can't tamper with.
- Don't use traversable direct references - use per user or per session refs, or UUIDs instead.
A6: Security Misconfiguration
Can happen all over the place up and down the stack, from the server filesystem to the browser-side JavaScript.
Prevention
Approved, defined configuration hardening. Turn everything off by default, in production only install what is necessary and being used. Disable stack traces, debug options, and verbose logging in production (and production-like) environments. Use scanning tools, e.g. OpenVAS, Nessus, Qualys, nmap etc.
A7: Cross-Site Scripting (XSS)
When an app displays unfiltered user-supplied data on an HTML page. Hijacking user session or the browser, to access other things on the PC, or just defacing (pwnd) websites. Can be stored (into the database) or just reflected (when a form is submitted and displayed). Very simply, adding this to an form postal address field:
<script>alert(document.cookie);</script>
Prevention
- Input validation
- Escape and encode all input
- Filter all output
- Use a Content Security Policy HTTP header.
# Example WordPress E-Commerce site: Content-Security-Policy: default-src: self; style-src: self; connect-src: https://api.stripe.com; \ frame-src self https://js.stripe.com; script-src self https://js.stripe.com
Intercepting proxies, e.g. OWASP ZAP (Zed Application Proxy). Can investigate traffic between browser and internet; can also scan sites for potential vulnerabilities. ZAP runs on Java 8+, set up browsers to use a localhost:xxxx proxy.
A8: Insecure Deserialisation
Deserialisation can be really bad, e.g. XML (see above).
Prevention
- Do cryptographic integrity checks
- Isolate deserialisation at the lowest priv possible
- Restrict network connectivity from containers doing the deserialising
- Log desz exceptions and failures
- Alert repeated desz attempts
A9: Using components with known vulns
OS, databases, webservers, scripting languages, caching stores, app frameworks, 3rd party application plugins and widgets, JS libraries, ...
Prevention
- Keep your shit patched
- Don't use crummy plugins / Don't run someone else's code in production you haven't audited yourself
A10: Insufficient logging and monitoring
If you're not logging, you can't find out what happened. If you're not monitoring, you can't react in time. If you're not doing either, then Ô__o. Most breaches are not detected for several months after they have happened.
Prevention
- Ensure your logs are digestible by some central logging management system (collectd, ES, kibana, etc.)
- Ensure security sensitive things are logged with sufficient context; validation failures, username, IP, user agent, ACL etc.
- Monitor logs.
Cross-Site Request Forgery (CSRF)
- Prevent by using an unpredictable one-use short-lived token in a hidden field, and ensure validity.
- Use a CAPTCHA or similar.
- Use a web framework.
- Set the 'SameSite' cookie attribute; prevents cookies on cross-origin requests. Since Chrome 55, Firefox 60. https://caniuse.com#search=SameSite
Links and further reading
- OWASP: https://www.owasp.org/
- Scan your site with the Mozilla Observatory: https://observatory.mozilla.org/
- Check your site SSL configuration: https://www.ssllabs.com/ssltest/
- SSL configuration generator: https://mozilla.github.io/server-side-tls/ssl-config-generator/
- Generate a Content Security Policy header: https://report-uri.com/home/generate
- Check for browser capabilities: https://caniuse.com