javascript.passport-jwt.security.passport-hardcode.hardcoded-passport-secret

profile photo of semgrepsemgrep
Author
3,098
Download Count*

A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module).

Run Locally

Run in CI

Defintion

rules:
  - id: hardcoded-passport-secret
    message: A hard-coded credential was detected. It is not recommended to store
      credentials in source-code, as this risks secrets being leaked and used by
      either an internal or external malicious adversary. It is recommended to
      use environment variables to securely provide credentials or retrieve
      credentials from a secure vault or HSM (Hardware Security Module).
    metadata:
      cwe:
        - "CWE-798: Use of Hard-coded Credentials"
      references:
        - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html
      owasp:
        - A07:2021 - Identification and Authentication Failures
      asvs:
        section: "V3: Session Management Verification Requirements"
        control_id: 3.5.2 Static API keys or secret
        control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management
        version: "4"
      category: security
      technology:
        - jwt
        - nodejs
        - secrets
      cwe2022-top25: true
      cwe2021-top25: true
      subcategory:
        - vuln
      likelihood: HIGH
      impact: MEDIUM
      confidence: HIGH
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Hard-coded Secrets
    languages:
      - javascript
      - typescript
    severity: WARNING
    mode: taint
    pattern-sources:
      - by-side-effect: true
        patterns:
          - pattern-either:
              - pattern: |
                  {..., clientSecret: "...", ...}
              - pattern: |
                  {..., secretOrKey: "...", ...}
              - pattern: |
                  {..., consumerSecret: "...", ...}
              - patterns:
                  - pattern-inside: |
                      $OBJ = {}
                      ...
                  - pattern-either:
                      - pattern: |
                          $OBJ.clientSecret = "..."
                      - pattern: |
                          $OBJ.secretOrKey = "..."
                      - pattern: |
                          $OBJ.consumerSecret = "..."
                  - pattern: $OBJ
              - patterns:
                  - pattern-inside: |
                      $SECRET = '...'
                      ...
                  - pattern-either:
                      - pattern: |
                          {..., clientSecret: $SECRET, ...}
                      - pattern: |
                          {..., secretOrKey: $SECRET, ...}
                      - pattern: |
                          {..., consumerSecret: $SECRET, ...}
              - patterns:
                  - pattern-inside: |
                      $SECRET = '...'
                      ...
                  - pattern-either:
                      - pattern-inside: |
                          $VALUE = {..., clientSecret: $SECRET, ...}
                          ...
                      - pattern-inside: |
                          $VALUE = {..., secretOrKey: $SECRET, ...}
                          ...
                      - pattern-inside: |
                          $VALUE = {..., consumerSecret: $SECRET, ...}
                          ...
                  - pattern: $VALUE
    pattern-sinks:
      - patterns:
          - pattern-either:
              - pattern-inside: |
                  $F = require("$I").Strategy
                  ...
              - pattern-inside: |
                  $F = require("$I")
                  ...
              - pattern-inside: |
                  import { $STRAT as $F } from '$I'
                  ...
              - pattern-inside: |
                  import $F from '$I'
                  ...
          - metavariable-regex:
              metavariable: $I
              regex: (passport-.*)
          - pattern-inside: |
              new $F($VALUE,...)
          - focus-metavariable: $VALUE

Examples

passport-hardcode.js

'use strict';
const FacebookStrategy = require('passport-facebook').Strategy;

exports.init = function(passport, router, config) {
  //ok: hardcoded-passport-secret
  new FacebookStrategy({clientSecret:config})
  passport.use(
    new FacebookStrategy(
    // ruleid: hardcoded-passport-secret
      {
        clientID: config.appId,
        clientSecret: 'HARDCODED-SECRET',
        callbackURL: config.publicAddress + config.callbackURL,
        enableProof: false,
        passReqToCallback: true,
      },
      function(req, accessToken, refreshToken, profile, done) {
        // do something
      },
    ),
  );
};

let passport = require('passport');
let JwtStrategy = require('passport-jwt').Strategy;
let ExtractJwt = require('passport-jwt').ExtractJwt;

/**
 *
 * @param {object} options
 * @param {object} options.logger
 * @param {object} options.jwtConfig
 * @returns {object}
 */
module.exports = (options)=> {
    let jwtConfig = options.jwtConfig;
    let logger = options.logger;
    let secret = 'HARDCODED-SECRET';

    this.passportOptions = {
        jwtFromRequest: ExtractJwt.fromHeader(jwtConfig.headerKey),
        secretOrKey: secret,
        issuer: jwtConfig.issuer,
        audience: jwtConfig.audience
    };
    // ruleid: hardcoded-passport-secret
    passport.use(new JwtStrategy(this.passportOptions, (jwt_payload, done)=> {
        // do something
    }));
    return passport.authenticate('jwt', {session: false})
};


var FACEBOOK_APP_ID     = require('../../../config').fbAppID;
var URLcallback         = require('../../../config').URL;
var passport            = require('passport');
var FacebookStrategy    = require('passport-facebook').Strategy;
var FACEBOOK_APP_SECRET = "HARDCODED-SECRET";


module.exports = function(req, res) {

  passport.use(new FacebookStrategy(
     // ruleid: hardcoded-passport-secret 
      {
      clientID:     FACEBOOK_APP_ID,
      clientSecret: FACEBOOK_APP_SECRET,
      callbackURL:  URLcallback + '/api/auth/facebook/callback'
    },
    function(accessToken, refreshToken, profile, done) {
      // do something
    }
  ));
};

var passport = require('passport')

module.exports = class Auth {
  constructor (config) {
    this.passport = passport

    var JwtStrategy = require('passport-jwt').Strategy
    this.jwt_secret = 'HARDCODED-SECRET'

    let obj1 = {}
    obj1.clientSecret = 'a'
    // ruleid: hardcoded-passport-secret     
    new JwtStrategy(obj1)
    // ok: hardcoded-passport-secret     
    new JwtStrategy(obj2)
    // ruleid: hardcoded-passport-secret      
    passport.use(new JwtStrategy({secretOrKey: this.jwt_secret}, function (payload, done) {
      // auth callback
    }))
  }

  something (req, res, next) {
    // do something
  }

}