iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article

Web Service Launch Checklist

に公開
13

I have been personally creating a "Web Service Pre-launch Checklist," and since it has grown quite a bit, I am now sharing it. This list is a compilation of notes I’ve personally taken when I made mistakes in the past, or when I came across information that made me think, "This could happen to me..."

Security

  • The HttpOnly attribute is set
    • A mitigation measure against XSS (mitigation only).
  • The SameSite attribute is set to Lax or Strict
    • Primarily for CSRF protection. If using Lax, also check if there are any endpoints performing update processes with GET requests.
  • The Secure attribute is set
    • Ensures Cookies are sent only over HTTPS connections.
  • The Domain attribute is set appropriately
    • If Cookies are configured to be sent to subdomains, understand the risk of an incident originating from a vulnerability on another subdomain site.
    • Example: If Cookies for example.com are sent to a recruitment site at jobs.example.com, and that server has a vulnerability.
    • Reference: The safest Domain attribute for Cookies is not specifying it
    • Setting the Cookie name prefix to __Host- causes the browser to ignore Cookie specifications where the Domain attribute is not empty (Reference: Bypassing Cookie Prefixes)

Validation of User Input Values

  • Validation is performed on the server-side as well as the client-side
  • Validation of user-inputted URLs is performed correctly
  • In parts where received HTML is output as-is, the possibility of dangerous strings being passed has been eliminated
    • Parts like element.innerHTML = input or React's dangerouslySetInnerHTML.
    • Perform escaping or sanitization before displaying user input.
  • No SQL statements exist that are vulnerable to SQL injection
  • If users can specify handle names etc. that are included in URLs, validation is performed correctly
    • Use caution if user-specified handles are applied to https://example.com/◯◯.
    • Reject strings that could overlap with paths used by the application.
    • Reject strings starting with underscores (they may be reserved by the hosting cloud service. For example, /_ah is reserved in Google App Engine).
    • Reject strings consisting only of numbers (some frameworks may automatically treat requests to /404 as a 404 error. This may be fine depending on the path structure).
    • Set up a list of reserved strings to prevent user registration. Examples include admin or contact (Reference: reserved-usernames)

Response Headers

  • Strict-Transport-Security is specified in the response headers
    • Instructs the browser to always use HTTPS instead of HTTP for connections to the specified domain for a specified duration
      {
        key: 'Strict-Transport-Security',
        value: 'max-age=31536000; includeSubDomains; preload'
      }
      
  • X-Frame-Options: "DENY" or X-Frame-Options: "SAMEORIGIN" is applied to the response headers of each page (Update: It is recommended to set CSP's frame-ancestors instead)
    • Prevents embedding the page via iframes, etc., on unintended external sites = Clickjacking protection
  • X-Content-Type-Options: nosniff is specified

Other Security

  • Re-authentication (recent login) is required for sensitive actions like account deletion or email address changes
    • Mitigation measure for XSS or session hijacking.
  • Responses that change based on the user are not cached in CDN or KVS
  • Directory page URLs for object storage are not public
  • Validation is performed in parts that redirect to URLs provided by the client (Open Redirect protection)
    • Example: Ensure that clicking https://example.com/login?redirect_to=https://evil.example does not redirect to https://evil.example.
  • Unauthorized or unauthenticated users cannot update data in update/delete processes
  • WHERE clauses are set appropriately in SQL DELETE and UPDATE statements
    • Example: Intending to batch update products for a specific user, but inadvertently updating all products. In my projects, I use Prisma Extensions to prevent updateMany/deleteMany unless specific queries are provided.
  • Strings provided by users are not included directly in response headers
    • Prevents potential response header manipulation.
  • Error messages generated on the server are not displayed directly in the browser
  • Validation for file format, size, and filename is performed in file upload functions
  • Periodic DB backups are enabled
  • Object storage backups are enabled
  • Two-factor authentication (2FA) is enabled for cloud service accounts
  • (Configure CSP depending on service requirements)

Login

  • Email address verification is performed
    • Even if the email address is provided by an ID provider, verify that the email itself has been verified.
  • Registered email addresses cannot be enumerated
    • Prevent third parties from determining if an email is registered based on error messages like "This email address is not registered" on the login or password reset screens.
    • For instance, Firebase Authentication used to allow this, but it appears to have been addressed in 2023.
  • If providing multiple login methods, the specifications for when the same user registers have been decided and implemented
    • Example: What happens if a user who registered via email + password authentication logs in with a Google account using the same email address.
  • Email address and linked account changes are possible

Email Sending

  • If user input is included in emails, ensure that the input cannot be abused to send spam
    • Example: If usernames or item titles allow promotional or spammy content, editing those could turn the resulting notification emails into spam.
  • User actions do not trigger repeated emails to an unspecified large number of people
    • Example: Following 10,000 people using a follow feature results in 10,000 notification emails being sent.
  • SPF / DKIM / DMARC settings are complete
  • When sending emails via batch processing, duplicate emails are not sent even if the process is triggered multiple times
    • Services like AWS or Google Cloud often operate on "At least once delivery."
  • For newsletters or campaign emails, unsubscription is possible without logging in
  • When sending campaign emails to a large number of people, List-Unsubscribe=One-Click is supported

SEO

  • Appropriate title tags are specified for all pages
  • canonical URL settings are in place for SEO-critical pages
    • Example: Enabling search engines to recognize that https://example.com/products/foo and https://example.com/products/foo?query=bar represent the same content.
  • Status codes for error-related pages are 40x or 50x, or they are set to noindex
  • Search result pages have noindex or canonical URLs set
    • Or, explicitly include "Search results: ◯◯" in the <title> and <h1> tags. Otherwise, inappropriate keywords might be indexed.
    • Example: If the page title for https://example.com/search?keyword=POOP is "POOP", then "POOP" might be indexed.
  • The entire site is not set to noindex
    • Often forgotten when intended to be removed at release.
  • Meta descriptions are set for pages with high search traffic potential, such as the top page
    • Personally, I don't think it's necessary for user-generated pages. No meta description is better than a poorly configured one.
  • If public pages are generated dynamically, an XML sitemap is created and registered with Search Console

OGP

  • OGP settings are complete for pages expected to be shared frequently
    • The following should be configured:
      • og:title
      • og:description
      • og:url
      • og:image
      • twitter:card (X card format)

When Adding Payment Features

  • Accounting procedures have been confirmed with the person in charge
  • Inconsistencies do not occur between application data and payment service data (such as Stripe) even if a payment fails
    • Ensure that any occurrences can be detected.
    • Example: Payment succeeds on Stripe, but DB update fails.
  • Implementation prevents duplicate payments
  • No inconsistencies occur in accounting or application logic even if a user who has previously made a payment deletes their account
  • Subscriptions are automatically canceled when a user with an active subscription deletes their account (or has their account frozen)
  • Refund policies and pro-rated calculations for account deletion are stated in the Terms of Service
    • It is also recommended to display these points on the account deletion page.
  • A path for cancellation is provided
  • Handling of subscription renewal failures (e.g., due to card expiration) is in place. Also, a clear path for users to update their payment information is displayed
  • Receipts meet the requirements for qualified invoices (Invoice System in Japan)

Accessibility

  • Alt attributes for images (<img>) are specified appropriately
  • Roles of <button> or <a> elements containing only SVG icons are recognizable by screen readers
    <a href="/" aria-label="Text indicating the role of the link">
      <svg aria-hidden="true" ... ></svg>
    </a>
    

These two are often forgotten, so I added them to the checklist. For other items, the freee Accessibility Guidelines are helpful.

Performance

  • Ensure no unnecessary modules are included in the bundled JS
    • It is recommended to check this using tools like bundle-analyzer before release.
  • Static files are cached on the CDN
    • Frameworks like Next.js or Nuxt.js send requests for a large number of JS/CSS files; these static files should be served from a CDN.
  • No layout shifts occur due to images
    • Specify CSS aspect-ratio or width/height attributes on the img element.
  • No unnecessarily large images are being loaded
    • Example: An image displayed small at 400px wide actually having a file size of 2MB. This is a common issue.
  • SQL indexes are appropriately set
    • This can also be addressed after release as the amount of data grows.

Testing across Multiple Environments

  • The UI does not break when displayed on mobile or tablet-sized screens
    • This is something I see very frequently.
  • Fonts do not look strange when viewed on various OS/browsers
    • Ensure font-family is specified so that it looks natural on each OS, including Mac, Windows, iOS, Android, and (Linux).
    • If you are developing on Chrome, don't forget to verify the behavior on Safari and Firefox.
  • (If the development environment is Mac) No issues occur when "Show scroll bars: Always" is enabled in System Settings
    • When scroll bars are set to be always visible, the layout often jitters when opening modals or similar elements. You may need to address this using scrollbar-gutter.
  • The layout does not break when user-specified input values, such as handle names, are long

Other

  • Ensure there are no issues if LocalStorage or non-HttpOnly Cookies are deleted after 7 days
    • While not widely known, due to ITP specifications in recent versions of iOS Safari, Cookies and LocalStorage content saved via JavaScript in the browser are automatically deleted if the user does not interact with the site for more than 7 days (Reference)
  • Not dependent on third-party cookies
  • For Japanese sites, ensuring <html lang="ja"> is set
    • Note that some frameworks may default to lang="en".
  • Ensuring server errors are notified or detectable when they occur
  • 404 and 50x error pages are well-designed
    • For 404 pages, ensure a path to the next action is displayed, such as a link to the top page.
  • Favicon is set
  • apple-touch-icon is set
  • Access analysis tools such as Google Analytics are implemented (if necessary)
  • If providing services like closed chats, the telecommunications business notification has been filed (Reference)
  • The service name does not have a strange meaning in other languages
    • It is a good idea to ask ChatGPT or use something like WordSense.

If there is anything else you think should be added because it is often forgotten, I would appreciate it if you could let me know in the comments.

Discussion

takecchitakecchi

凄く有益な記事をありがとうございます!

普段意識してはいるものの言語化できていないことが多いので、
こういったチェックシートは大変ありがたいです...!

認証に関わるCookieの属性

XSSが発生した際にはcredentials:includeで叩かれるので無意味だ!なんて話も聞きますが、
攻撃者が認証情報を手にして手元の端末から好き勝手叩かれるようなことは無くなるので緩和策にはなるんですよね。

重要な情報へのアクセスにはパスワードを必須化するといった設計の話も組み込まれておりますし、要点が箇条書きでまとまっており大変読みやすいです。

是非いろんな人に見てもらいたいですね。

catnosecatnose

ありがとうございます。まだ欠けているポイントが多くありそうなので、気付き次第加筆修正しようと思います。

yokotasoyokotaso

有益な記事の執筆ありがとうございます。勉強になりました!

認証に関わるCookieの属性

Cookieの設定が不適切な場合、ブラウザ側でCookieを拒否して安全性を高める仕様があります。

https://asnokaze.hatenablog.com/entry/2024/05/07/002720#Cookie名プレフィックス-Cookie-Name-Prefixes

https://caniuse.com/?search=Cookie prefixes

Secure属性が設定されていること

クッキー名のプレフィックスに __Secure- をつけると、Secure属性を持たないCookieはブラウザで拒否されます。

Domain属性が適切に設定されていること

クッキー名のプレフィックスに __Host- をつけると、Secure属性・Path属性==/・Domain属性無しを満たさないクッキーはブラウザで拒否されます。

すでにご存じでしたら、すいません。

catnosecatnose

有益な情報をありがとうございます。記事本文にも追記しておきます!

LocLoc

とても参考になる記事ありがとうございます!

決済機能をつける場合

私の場合、こちらにサブスクリプション決済が有効期限切れなどでエラーが出た際に、アプリケーション側でしっかり管理できているかを追加しますね!
何度か失敗しているものでして・・・!

catnosecatnose

ハマりやすいところですよね。追記しておきます!

kbaba1001kbaba1001

有益なリストをありがとうございます!
パフォーマンスのところでSQLでN+1問題が発生していないかもよくチェックします。

r-sugir-sugi

質問
利用ライブラリの脆弱性(例: npm auditの結果がhigh, criticalなど)もこの記事の観点に含まれますか?

stasta

好みやスタンス次第でしょうが、クロスブラウザ観点があった方がいいかもしれません。

私は Firefox なのですが、レイアウトが崩れる例が(比較的メジャーなサービスでも)たまにあります。

catnosecatnose

たしかに書かれてなかったですね!追記しておきます。