GithubHelp home page GithubHelp logo

mozilla / blurts-server Goto Github PK

View Code? Open in Web Editor NEW
693.0 78.0 199.0 167.61 MB

Mozilla Monitor arms you with tools to keep your personal information safe. Find out what hackers already know about you and learn how to stay a step ahead of them.

Home Page: https://monitor.mozilla.org

License: Mozilla Public License 2.0

JavaScript 6.00% CSS 0.02% Dockerfile 0.01% Shell 0.11% Fluent 58.81% Procfile 0.01% TypeScript 32.49% SCSS 2.55% HTML 0.02%
data-breach firefox

blurts-server's Introduction

Firefox Monitor Server

Summary

Firefox Monitor notifies users when their credentials have been compromised in a data breach.

This code is for the monitor.mozilla.org service & website.

Breach data is powered by haveibeenpwned.com.

See the Have I Been Pwned about page for the "what" and "why" of data breach alerts.

Architecture

Image of Monitor architecture

Development

Requirements

Code style

Linting and formatting is enforced via ESLint and Stylelint for JS and CSS. Both are installed as dev-dependencies and can be run with npm run lint. A push to origin will also trigger linting.

ESLint rules are based on eslint-config-standard. To fix all auto-fixable problems, run npx eslint . --fix

Stylelint rules are based on stylelint-config-standard. To fix all auto-fixable problems, run npx stylelint public/css/ --fix

GIT

We track commits that are largely style/formatting via .git-blame-ignore-revs. This allows Git Blame to ignore the format commit author and show the original code author. In order to enable this in GitLens, add the following to VS Code settings.json:

"gitlens.advanced.blame.customArguments": [
   "--ignore-revs-file",
   ".git-blame-ignore-revs"
],

Database

To create the database tables ...

  1. Create the blurts database:

    createdb blurts
    createdb test-blurts # for tests
  2. Update the DATABASE_URL value in your .env file with your local db credentials:

    DATABASE_URL="postgres://<username>:<password>@localhost:<port>/blurts"
    
  3. Run the migrations:

    npm run db:migrate
    

Install

  1. Clone and change to the directory:

    git clone https://github.com/mozilla/blurts-server.git
    cd blurts-server
  2. Install dependencies:

    npm install
  3. Copy the .env-dist file to .env:

    cp .env-dist .env
  4. Install fluent linter (requires Python)

    pip install -r .github/requirements.txt
    
    OR
    
    pip3 install -r .github/requirements.txt
  5. Generate required Glean files (needs re-ran anytime Glean .yaml files are updated):

    npm run build-glean
  6. Generate required Nimbus files (needs re-ran anytime Nimbus' config/nimbus.yaml file is updated):

    npm run build-nimbus
  7. Create location data: Running the script manually is only needed for local development. The location data is being used in the onboarding exposures scan for autocompleting the “City and state” input.

    npm run create-location-data
  8. Ensure that you have the right env variables/keys set in your .env file. You can retrieve the variables from the Firefox Monitor 1Password Vault, or through Magic-Wormhole, by asking one of the our engineers.

Run

  1. To run the server similar to production using a build phase, which includes minified and bundled assets:

    npm start

    OR

    Run in "dev mode" with:

    npm run dev
  2. You may receive the error Required environment variable was not set. If this is the case, get the required env var(s) from another team member or ask in #fx-monitor-engineering. Otherwise, if the server started successfully, navigate to localhost:6060

PubSub

Monitor uses GCP PubSub for processing incoming breach data, this can be tested locally using an emulator: https://cloud.google.com/pubsub/docs/emulator

Run the GCP PubSub emulator:

gcloud beta emulators pubsub start --project=your-project-name

In a different shell, set the environment to point at the emulator and run Monitor in dev mode:

$(gcloud beta emulators pubsub env-init)
npm run dev

Incoming WebHook requests from HIBP will be of the form:

curl -d '{ "breachName": "000webhost", "hashPrefix": "test", "hashSuffixes": ["test"] }' \
  -H "Authorization: Bearer unsafe-default-token-for-dev" \
  http://localhost:6060/api/v1/hibp/notify

This pubsub queue will be consumed by this cron job, which is responsible for looking up and emailing impacted users:

node src/scripts/emailBreachAlerts.js

Emails

Monitor generates multiple emails that get sent to subscribers. To preview or test-send these emails see documentation here.

Mozilla accounts ("FxA", formerly known as Firefox accounts)

Subscribe with a Mozilla account is controlled via the FXA_ENABLED environment variable. (See .env-dist)

The repo comes with a development FxA oauth app pre-configured in .env, which should work fine running the app on http://localhost:6060. You'll need to get the OAUTH_CLIENT_SECRET value from a team member or someone in #fxmonitor-engineering.

Testing

The unit test suite can be run via npm test.

At the beginning of a test suite run, the test-blurts database will be populated with test tables and seed data found in src/db/seeds/

At the end of a test suite, coverage info will be sent to Coveralls to assess coverage changes and provide a neat badge. To upload coverage locally, you need a root .coveralls.yml which contains a token – get this from another member of the Monitor team.

End-to-End tests use Playwright and can be run via npm run e2e. E2E-How-To for more info.

Test Firefox Integration

TODO: the following functionality is disabled but the instructions are left here for posterity.

Firefox's internal about:protections page ("Protections Dashboard") fetches and displays breach stats for Firefox users who are signed into their FXA.

To test this part of Monitor:

  1. Set a Firefox profile to use the staging Firefox Accounts server.
  2. In the same profile, go to about:config and replace all https://monitor.firefox.com values with http://localhost:6060
  3. Restart Firefox with that profile.
  4. Go to about:protections
  5. Everything should be using your localhost instance of Monitor.

Localization

All text that is visible to the user is defined in Fluent files inside /locales/en/ and /locales-pending/. After strings get added to files in the former directory on our main branch, they will be made available to our volunteer localizers via Pontoon, Mozilla's localization platform. Be sure to reference the localization documentation for best practices. It's best to only move the strings to /locales/en/ when they are more-or-less final and ready for localization. Your PR should be automatically tagged with a reviewer from the Mozilla L10n team to approve your request.

You can check translation status via the Pontoon site. After strings have been localized, a pull request with the updated strings is automatically opened against our repository. Please be mindful that Mozilla localizers are volunteers, and translations come from different locales at different times – usually after a week or more.

To use the strings in code, you need to obtain a ReactLocalization instance, which selects the right version of your desired string for the user. How to do that depends on where your code runs: in tests, in a cron job, in a server component, or on the client-side. Generally, you will import a getL10n function from one of the modules in /src/app/functions/l10n/, except for Client Components, which use the useL10n hook. Look at existing code for inspiration.

Preview Deployment

We use GCP Cloudrun for dev review – official stage and production apps are built by the Dockerfile and Github Actions. Everything that is merged into main will deploy automatically to stage. The ADR for preview deployment can be found here

TODO: add full deploy process similar to Relay

TODO: consider whether we can re-enable Heroku Review Apps

Preserve sessions in local development

Sessions by default are stored in-memory, which means that when the server restarts (e.g. because you made a code change), you will have to log in again.

To avoid this hassle, you can install and run Redis, which by default runs on redis://localhost:6379. Use that value for REDIS_URL in your .env file to preserve your sessions across server restarts.

blurts-server's People

Contributors

abelardo-py avatar andy-moz avatar codemist avatar dependabot[bot] avatar fjoerfoks avatar flozia avatar gaby2300 avatar groovecoder avatar jimsp472000 avatar jsyanis avatar karm46 avatar lesleyjanenorton avatar mansaj avatar marceloghelman avatar markh-bz avatar maxxcrawford avatar mozilla-pontoon avatar mozrokafor avatar nhnt11 avatar pdehaan avatar petercpg avatar ravmn avatar rhelmer avatar rprys avatar sn-o-w avatar soucet avatar theochevalier avatar toufali avatar ujdhesa avatar vinnl avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

blurts-server's Issues

Add sample server/smtp-credentials.json file?

Looking through the code, it only looks like it has 2 fields, but may be nice to include a dummy "server/smtp-credentials.json.sample" file with something like:

{
  "username": "xxx",
  "password": "yyy"
}

Version Error

Is this compatible with FireFox Quantum ver. 57? Because this add-on showing error that, this is compatible with minVersion: 58.0a1. add-on maxVersion: 59.0a1

API is not documented

We should start an api.md file containing detailed documentation for API endpoints, usage, errors, request/response structures, etc.

Consider using WebExtensions APIS

To avoid the overhead of enabling legacy extensions and to simplify the code-base, this could be refactored into WebExtensions APIs. Specifically, webRequest and notifications E.g.,

background.js

const BREACHES_URL = "..."
let siteSet = new Set();

async function initSiteList() {
  const breachesResponse = await fetch(BREACHES_URL);
  const breachesJSON = breachesResponse.json();
  siteSet = new Set(breachesJSON.map(site => site.Domain));
}

function initOnResponseStarted() {
  browser.webRequest.onResponseStarted.addListener(details => {
    if (siteSet.has(details.url.replace("www.",""))) {
      notifications.create({...});
    }
  }...);
}

initSiteList();
initOnResponseStarted();

"Recently" breached meaning

Inform users about data breaches through the Firefox UI - for example, a notification when they visit a site (or maybe when they focus a form on a login page) known to have recently been breached.

I'm curious about the wording of this. What defines "recently"?

Implement an elegant system to register API handlers

Currently API handlers are added direction with app.get/app.post. We should implement a handler registration system that will allow organized, versioned API handling for better maintainability and readability.

Resolve code style inconsistencies

I want to do an audit of all the code to clean up stuff like:

  • Package imports should be ordered nicely
  • Use async/await instead of Promises
  • Make variable naming consistent (especially for function arguments - prefix with "a" e.g. aArg1, aArg2)
  • Sensible whitespace

Add ESLint rule for double quotes

It's not in the basic "eslint:recommended" rule set, but we should just use this to enforce consistency:

"quotes": ["error", "double"],

Add README.md

Needs a README with instructions for development & testing

var vs let vs const, oh my!

We have arguments against const and arguments for const, let's have a 🔪 and 🔫 fight and settle this once and for all and see if we can find an ESLint rule that will support whatever we go with.

So this is a "needs discussion" but now shouldn't be a blocker on the current open PR.

Make max DB connections configurable?

const dbConfig = {
max: 10,
};

Ref: https://github.com/mozilla/blurts-server/pull/48/files#r171956899:

Hmm, this would be nice, yes, but I'm going to procrastinate on it because:

  • This is not immediately important.
  • Getting numerical values from the environment means using parseInt(), and that seems like a prime surface area for bugs and failures.
  • We should probably first improve AppConstants to also know what type each value is supposed to be and automate the parseInt()s.

Not sure if something like Mozilla's node-convict would be useful here for config+env management w/ schema validation.

Update README

The README document should link to the API docs and contain detailed instructions for:

  • local development
  • deployment (to heroku)
  • contribution

Add nsp to check dependencies

Since we're a server, we probably want to use something like nsp or snyk to audit or suspect dependencies...

Current status:

$ npx nsp@latest check

npx: installed 113 in 15.185s

(+) 1 vulnerability found
┌────────────┬────────────────────────────────────────────────────────────────────┐
│            │ Prototype pollution attack                                         │
├────────────┼────────────────────────────────────────────────────────────────────┤
│ Name       │ hoek                                                               │
├────────────┼────────────────────────────────────────────────────────────────────┤
│ CVSS       │ 4 (Medium)                                                         │
├────────────┼────────────────────────────────────────────────────────────────────┤
│ Installed  │ 4.2.0                                                              │
├────────────┼────────────────────────────────────────────────────────────────────┤
│ Vulnerable │ <= 4.2.0 || >= 5.0.0 < 5.0.3                                       │
├────────────┼────────────────────────────────────────────────────────────────────┤
│ Patched    │ > 4.2.0 < 5.0.0 || >= 5.0.3                                        │
├────────────┼────────────────────────────────────────────────────────────────────┤
│ Path       │ [email protected] > [email protected] > [email protected] > [email protected]     │
├────────────┼────────────────────────────────────────────────────────────────────┤
│ More Info  │ https://nodesecurity.io/advisories/566                             │
└────────────┴────────────────────────────────────────────────────────────────────┘

Ref: https://nodesecurity.io/advisories/566

[RFC] Behavior on unverified breaches

What should the behavior of this extension be when you visit a site with an unverified breach?

Here's a set of options that seems to span the spectrum of possible behavior:

  1. Don't show any notification - if it turns out to be fake, we worried a bunch of people for no reason
  2. Only show a notification if some criteria is met - e.g. user is frequent visitor to the site? logged in
  3. Save that you visited the site, and give a notification later if the breach is verified as correct - much less invasive, tracked data is very small
  4. Give a notification with muted styling and wording ("We're not sure yet, but…")
  5. Full speed ahead, tiny or no indication that the breach is marked in HIBP as unverified

Install vendor code via npm instead of copy-pasta into public/

Potential solution:

$ npm i foundation-sites jquery -D
$ cp ./node_modules/foundation-sites/dist/css/foundation.min.css public/css/vendor/foundation.min.css
$ cp ./node_modules/foundation-sites/dist/js/foundation.min.js public/js/vendor/foundation.min.js
$ cp ./node_modules/jquery/dist/jquery.min.js public/js/vendor/jquery.js

But at least this will make managing the vendor files easier and let us use semver to manage versions (and nsp to make sure everything is tip-top).


Here's a quick example using shelljs to copy files:

const { cp } = require('shelljs');
 
cp("./node_modules/foundation-sites/dist/css/foundation.min.css", "./public/css/vendor/");
cp([
  "./node_modules/foundation-sites/dist/js/foundation.min.js",
  "./node_modules/jquery/dist/jquery.min.js"
], "./public/js/vendor/");

... then we'd just need some clever .gitignore to ignore the ./public/css/vendor/* files and ./public/js/vendor/* folders.

Didn't see the notification box when I visited linkedin.com

STR:

  1. ./package.sh
  2. Run Firefox Nightly 58.0a1 (2017-11-07) (64-bit) Mac
  3. In about:config set:
  • xpinstall.signatures.required to false
  • extensions.legacy.enabled to true
  1. In about:addons, choose "Install Add-on from File"
  2. Select the packaged BreachAlerts.xpi
  3. Visit linkedin.com

Expected result:

Notification bar with an alert: "You visited hacked site ..."

Actual result:

Nothing is shown

Security Checklist

Risk Management

  • The service must have performed a Rapid Risk Assessment and have a Risk Record bug
  • Public staging and production endpoints must be added to the security baseline

Infrastructure

  • Access and application logs must be archived for a minimum of 90 days
  • Use Modern or Intermediate TLS
  • Set HSTS to 31536000 (1 year)
    • strict-transport-security: max-age=31536000
  • [ ] Set HPKP to 5184000 (60 days)
    • Public-Key-Pins: max-age=5184000; pin-sha256="WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18="; pin-sha256="r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E="; pin-sha256="YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg="; pin-sha256="sRHdihwgkaib1P1gxX8HFszlD+7/gTfNvuAybgLPNis=";
      • Start with max-age set to 5 minutes (max-age=300) and increase progressively
      • The first two pins are for Digicert EV and DV roots, the last two are for Let's Encrypt X3 and X4 intermediates (LE is only used for backup)
    • [ ] If the service is not hosted under services.mozilla.com, it must be manually added to Firefox's preloaded pins.
  • If service has an admin panels, it must:
    • [ ] only be available behind Mozilla VPN (which provides MFA)
    • [ ] require Auth0 authentication

Development

  • Sign all release tags, and ideally commits as well
    • Developers should configure git to sign all tags and upload their PGP fingerprint to https://login.mozilla.com
    • The signature verification will eventually become a requirement to shipping a release to staging & prod: the tag being deployed in the pipeline must have a matching tag in git signed by a project owner. This control is designed to reduce the risk of a 3rd party GitHub integration from compromising our source code.
  • Keep 3rd-party libraries up to date
  • Integrate static code analysis in CI, and avoid merging code with issues
    • JavaScript applications should use ESLint with the Mozilla ruleset
    • Python applications should use Bandit
    • Go applications should use the Go Meta Linter
    • Use whitelisting mechanisms in these tools to deal with false positives

Dual Sign Off

  • [ ] Services that push data to Firefox clients must require a dual sign off on every change, implemented in their admin panels
    • This mechanism must be reviewed and approved by the Firefox Operations Security team before being enabled in production

Logging

  • Publish detailed logs in mozlog format (APP-MOZLOG)
    • Business logic must be logged with app specific codes (see FxA)
    • [ ] Access control failures must be logged at WARN level

Security Headers

  • Must have a CSP with
    • a report-uri pointing to the service's own /__cspreport__ endpoint
    • web API responses should return default-src 'none'; frame-ancestors 'none'; base-uri 'none'; report-uri /__cspreport__ to disallowing all content rendering, framing, and report violations
    • if default-src is not none, frame-src, and object-src should be none or only allow specific origins
    • no use of unsafe-inline or unsafe-eval in script-src, style-src, and img-src
  • Web APIs must set a non-HTML content-type on all responses, including 300s, 400s and 500s
  • Set the Secure, HTTPOnly, and SameSite flags on Cookies, and use sensible Expiration
  • Make sure your application gets an A+ on the Mozilla Observatory
  • Verify your application doesn't have any failures on the Security Baseline.
    • Contact secops@ or ping 'psiinon' on github to document exceptions to the baseline, mark csrf exempt forms, etc.
      • Note: we have a sticky session cookie AWSELB that is set without secure and httponly flags, but it is low risk.
  • [ ] Web APIs should export an OpenAPI (Swagger) to facilitate automated vulnerability tests

Security Features

  • [ ] Authentication of end-users should be via FxA. Authentication of Mozillians should be via Auth0/SSO. Any exceptions must be approved by the security team.
  • Session Management should be via existing and well regarded frameworks. In all cases you should contact the security team for a design and implementation review
    • Store session keys server side (typically in a db) so that they can be revoked immediately.
    • Session keys must be changed on login to prevent session fixation attacks.
    • Session cookies must have HttpOnly and Secure flags set and the SameSite attribute set to 'strict' or 'lax' (which allows external regular links to login).
    • For more information about potential pitfalls see the OWASP Session Management Cheet Sheet
  • [ ] Access Control should be via existing and well regarded frameworks. If you really do need to roll your own then contact the security team for a design and implementation review.

Databases

  • All SQL queries must be parameterized, not concatenated
  • Applications must use accounts with limited GRANTS when connecting to databases
    • In particular, applications must not use admin or owner accounts, to decrease the impact of a sql injection vulnerability.

Common issues

  • User data must be escaped for the right context prior to reflecting it
    • When inserting user generated html into an html context:
      • Python applications should use Bleach
      • Javascript applications should use DOMPurify
  • Apply sensible limits to user inputs, see input validation
    • POST body size should be small (<500kB) unless explicitely needed
  • [ ] When managing permissions, make sure access controls are enforced server-side
  • [ ] If handling cryptographic keys, must have a mechanism to handle quarterly key rotations
    • Keys used to sign sessions don't need a rotation mechanism if destroying all sessions is acceptable in case of emergency.
  • Do not proxy requests from users without strong limitations and filtering (see Pocket UserData vulnerability). Don't proxy requests to link local, loopback, or private networks or DNS that resolves to addresses in those ranges (i.e. 169.254.0.0/16, 127.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 172.16.0.0/12, 192.168.0.0/16, 198.18.0.0/15).
  • Do not use target="_blank" in external links unless you also use rel="noopener noreferrer" (to prevent Reverse Tabnabbing)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.