Lock Me In, But Not the Hackers
— A Workshop on Web Security

npm audit

  • When using npm, run npm audit to check for vulnerabilities in your dependencies.

  • Run it with --fix to automatically fix issues when possible.

SRI: Sub-Resource Integrity

When loading a 3rd party-script like this:

<script defer
  src="https://unpkg.com/smoothscroll-polyfill@0.4.4/dist/smoothscroll.min.js">
</script>

What happens if unpkg.com gets hacked and the script is replaced with a malicious one?

To prevent this, we can use the integrity attribute:

<script defer
    src="https://unpkg.com/smoothscroll-polyfill@0.4.4/dist/smoothscroll.min.js"
    integrity="sha384-R1+zrYTQk6y5F9GQMXZ..."
    crossorigin="anonymous">
</script>

How SRI Works

  • The integrity attribute contains a cryptographic hash of the file.

  • The browser will check the file against this hash, and if it doesn't match, the file won't be loaded.

  • In this case, just add the ?meta query parameter to the URL to get a JSON object containing the hash:

https://unpkg.com/smoothscroll-polyfill@0.4.4/?meta

Security Headers

What are Security Headers?

Security headers are HTTP response headers that help protect your website from common attacks by controlling browser behavior.

Strict-Transport-Security (HSTS)

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

Forces browsers to use HTTPS, protecting against protocol downgrade attacks and cookie hijacking.

If missing: Attackers can intercept traffic over HTTP, making users vulnerable to man-in-the-middle attacks.

HSTS Preloading: Submit your domain to hstspreload.org to be built into browsers.

X-Frame-Options

Prevents your site from being embedded in iframes, protecting against clickjacking.

X-Frame-Options: DENY

If missing: Attackers can trick users into clicking hidden buttons or links on your site.

X-Content-Type-Options

Stops browsers from MIME-sniffing a response away from the declared content-type.

X-Content-Type-Options: nosniff

If missing: Browsers may interpret files as executable scripts, increasing risk of attacks.

Referrer-Policy

Controls how much referrer information is sent with requests, protecting user privacy.

Referrer-Policy: no-referrer

If missing: Sensitive URLs may be leaked to third-party sites.

rel="noopener noreferrer"

 

Explicitly controls link security behavior (though modern browsers default to safe behavior).

<a href="https://external-site.com" target="_blank" 
   rel="noopener noreferrer">External Link</a>

Permissions-Policy

Restricts access to browser features like camera, microphone, geolocation, etc.

Permissions-Policy: geolocation=(), camera=()

If missing: Malicious sites may abuse browser features without user consent.

Permissions-Policy (FULL LIST)

accelerometer=(), ambient-light-sensor=(), 
autoplay=(), battery=(), camera=(), cross-origin-isolated=(), 
display-capture=(), document-domain=(), encrypted-media=(), 
execution-while-not-rendered=(), execution-while-out-of-viewport=(), 
fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), 
magnetometer=(), microphone=(), midi=(), navigation-override=(), 
payment=(), picture-in-picture=(), publickey-credentials-get=(), 
screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), 
xr-spatial-tracking=()

Content-Security-Policy (CSP)

Content-Security-Policy (CSP) is a powerful security header that helps prevent cross-site scripting (XSS), data injection, and other attacks by specifying which sources the browser can load resources from.

Why use CSP?

  • Limits the impact of XSS and code injection vulnerabilities
  • Controls where scripts, styles, images, fonts, and other resources can be loaded from

CSP: default-src

Fallback for other resource types if not specified.

Content-Security-Policy: default-src 'self'

CSP: script-src

Controls allowed sources for JavaScript.

Content-Security-Policy: script-src 'self' https://apis.example.com

CSP: style-src

Controls allowed sources for CSS.

Content-Security-Policy: style-src 'self' https://fonts.googleapis.com

CSP: img-src

Controls allowed sources for images.

Content-Security-Policy: img-src 'self' data: https://images.example.com

CSP: img-src — data:URL's

Base64-encoded images embedded directly in HTML/CSS using the data: scheme.

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==" alt="1x1 pixel">

Common use cases:

  • Small icons and SVGs
  • Loading spinners and placeholders
  • Inlined assets from build processes
  • Images that need immediate availability

CSP: connect-src

Controls allowed endpoints for XHR, WebSockets, and fetch.

Content-Security-Policy: connect-src 'self' https://api.example.com

CSP: Additional Directives

Content-Security-Policy: 
  font-src 'self' https://fonts.gstatic.com;
  media-src 'self';
  object-src 'none';
  frame-src 'self' https://trusted-frames.example.com

CSP Best Practices

If missing: Attackers can inject malicious scripts, styles, or other resources, leading to data theft, site defacement, or malware distribution.

Tips:

  • Start with a strict policy and relax only as needed
  • Use browser developer tools to test and refine
  • Consider using report-only mode initially
  • Use nonces or hashes for inline scripts/styles

CSP in CMS Environments

Configurable CSP with secure defaults, allowing editors controlled exceptions per page.

Approach:

  • Base policy: Secure defaults for all pages
  • Editor controls: Whitelist specific domains per page/section
  • Validation: Prevent wildcard (*) entries from editors
  • Audit trail: Log when policies are modified
# Default strict policy
Content-Security-Policy: default-src 'self'; script-src 'self'; img-src 'self' data:

# Page-specific relaxation (editor configurable)
Content-Security-Policy: default-src 'self'; script-src 'self' https://widgets.example.com; img-src 'self' data: https://cdn.images.com

WAF
WEB APPLICATION FIREWALL

  • Filters malicious traffic before it reaches your application
    — first line of defense.
  • Sits between users and your servers, analyzing HTTP requests in real-time.
  • Blocks known attack patterns, bad bots, and scrapers while allowing legitimate traffic through.

WAF
Cloudflare

  • Enable via Security → WAF → Custom rules
  • Pre-built rulesets for OWASP Top 10, bot protection
  • Rate limiting and geographic blocking

WAF
Vercel

  • Built-in DDoS protection and edge caching
  • Configure via vercel.json or dashboard
  • Custom rules for API rate limiting

WAF
Umbraco Cloud

  • Managed WAF with automatic updates
  • OWASP Core Rule Set enabled by default
  • Configure via Cloud portal

Backend Security Topics
API & Server Developers

While many security principles apply to both frontend and backend, backend developers should pay special attention to the following areas:

API Security Fundamentals

  • Use strong authentication and authorization (OAuth2, JWT, API keys)
  • Implement rate limiting and throttling to prevent abuse
  • Validate and sanitize all input to prevent injection attacks
  • Avoid leaking sensitive information in error messages

Rate Limiting & Throttling

Rate limiting restricts how many requests a user or client can make to your API in a given time period.

Why is rate limiting important?

  • Prevents abuse, denial-of-service (DoS), and brute-force attacks
  • Protects backend resources and ensures fair usage

Best Practices:

  • Set reasonable limits per user, IP, or API key (e.g., 100 requests per minute)
  • Return HTTP 429 Too Many Requests when limits are exceeded
  • Use libraries or middleware (e.g., express-rate-limit for Node.js)

Brute-force Protection

Brute-force attacks occur when an attacker tries many username/password combinations in rapid succession to gain unauthorized access.

Best Practices:

  • Enforce account lockout or temporary blocking after several failed login attempts
  • Use exponential backoff or increasing delays for repeated failures
  • Integrate CAPTCHA or other human verification for critical endpoints
  • Monitor and alert on suspicious activity

Example: Lock an account for 15 minutes after 5 failed login attempts.

Data Protection

  • Encrypt sensitive data at rest and in transit (TLS/SSL)
  • Store credentials and secrets securely (environment variables, vaults)

Logging and Monitoring

  • Log security events centrally and monitor in real time
  • Protect logs from tampering and ensure proper retention

CORS (Cross-Origin Resource Sharing)

CORS controls how web applications interact with resources from different origins (domains).

Best Practices:

  • Set Access-Control-Allow-Origin to specific domains, not *
  • Restrict allowed HTTP methods and headers
  • Use credentials only when necessary, never with wildcard origin
  • Always validate the origin server-side
Access-Control-Allow-Origin: https://yourdomain.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: Content-Type, Authorization

Additional Backend Security

Session Management:

  • Use secure cookie settings (HttpOnly, Secure, SameSite)
  • Expire and invalidate sessions appropriately

File Upload Security:

  • Validate file types and sizes
  • Scan uploads for malware
  • Store files outside the web root

Security Testing:

  • Use automated security testing tools (SAST, DAST)
  • Perform regular penetration testing

Ongoing Maintenance

Keeping your web application secure is an ongoing process. Here are some do's and don'ts to help maintain a strong security posture:

Do's:

  • Regularly update dependencies and frameworks to patch known vulnerabilities
  • Schedule frequent security audits and code reviews
  • Use automated tools to scan for vulnerabilities (e.g., Snyk, OWASP Dependency-Check, GitHub Dependabot)
  • Monitor security advisories for your tech stack
  • Enforce strong authentication and access controls

Ongoing Maintenance

Don'ts:

  • Don't ignore security warnings from your package manager or build tools
  • Don't rely solely on default configurations—review and harden them
  • Don't expose sensitive information in error messages or logs
  • Don't postpone applying critical security updates

Security Tools & Resources

Recommended Tools:

  • Snyk: Scans for vulnerabilities in code, dependencies, containers, and IaC
  • SonarQube: Continuous inspection of code quality and security
  • npm audit: Checks for vulnerabilities in npm packages

We might consider:

  • Detectify: External attack surface scanning and penetration testing
  • OWASP ZAP: runtime security testing

DEMO LINKS

We need a security-guild

a group of developers that can inspect our current solutions and new sites

  • Set up tools like Snyk and SonarQube including CI/CD, Slack and Jira-integration
  • Test and verify Security Headers
  • Setup and configuring a WAF
  • If a WAF is not possible, maintain a dynamically generated robots.txt

We need a security-guild

do you want to be a part of it?
Let me know and join
den-security-guild

thank you!

Made with Slides.com