Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Image Removed

📙 You will learn

How to upgrade from 2.8.5.1 to 2.8.6.

Prerequisites

Audience: IT Professional and/or End User
Difficulty: Advanced
Time needed: Approximately 60 minutes
Tools required: Tomcat, MySQL or MS SQL Server

Note

ALWAYS PERFORM A FULL BACKUP OF YOUR DATABASE BEFORE ATTEMPTING ANY UPGRADE!

MySQL Server: You can run the mysqldump command from the MySQL server, e.g., mysqldump -u mydbuser -p mydatabase > path/to/backup.sql (we do not recommend using MySQL Workbench to perform the backup).

MS SQL Server: Using SSMS, right-click on the database, select Tasks → Back Up…, then choose the location & name of the backup file and click OK.

If you have any questions or concerns or if you wish to upgrade from an older version of ThreadFix, please reach out to our support team here: support@threadfix.it

ThreadFix Deployment Update

Follow these steps to deploy the updated version of ThreadFix:

  • Stop the Tomcat instance on which ThreadFix is running.

  • Move your current ThreadFix deployment directory from your Tomcat webapps folder into a backup directory.

    1. webapps directory location: //TOMCAT_HOME/webapps

  • Copy the updated ThreadFix folder from your new artifact into your webapps directory.

    1. webapps directory location: //TOMCAT_HOME/webapps

  • Copy the following files from your backed up ThreadFix directory to the newly updated ThreadFix directory:
    (FROM: <previous-threadfix-deploy>/WEB-INF/classes/TO: <new-threadfix-deploy>/WEB-INF/classes/, except as noted below)

  • custom.properties

  • ESAPI.properties

  • jdbc.properties

  • jms.properties

  • threadfix.license

  • If you've updated any of these in your previous deployment, copy them as well:

    <threadfix-deploy>/WEB-INF/security.xml
    Image Added

    📙 You will learn

    How to upgrade from 2.8.5 or 2.8.5.1 to 2.8.6.1

    Prerequisites

    Audience: IT Professional and/or End User
    Difficulty: Advanced
    Time needed: Approximately 60 minutes
    Tools required: Tomcat, MySQL or MS SQL Server

    Note

    ALWAYS PERFORM A FULL BACKUP OF YOUR DATABASE BEFORE ATTEMPTING ANY UPGRADE!

    MySQL Server: You can run the mysqldump command from the MySQL server, e.g., mysqldump -u mydbuser -p mydatabase > path/to/backup.sql (we do not recommend using MySQL Workbench to perform the backup).

    MS SQL Server: Using SSMS, right-click on the database, select Tasks → Back Up…, then choose the location & name of the backup file and click OK.

    Warning

    The National Vulnerability Database has identified a high risk exploit, Spring4Shell, which affects applications running Tomcat as a WAR deployment. To mitigate risk of exposure ThreadFix recommends users update their Tomcat to the latest (8.5.78 at a minimum) in addition to upgrading to ThreadFix 2.8.6.1.

    If you have any questions or concerns or if you wish to upgrade from an older version of ThreadFix, please reach out to our support team here: support@threadfix.it

    ThreadFix Deployment Update

    Follow these steps to deploy the updated version of ThreadFix:

    1. Stop the Tomcat instance on which ThreadFix is running.

    2. Move your current ThreadFix deployment directory from your Tomcat webapps folder into a backup directory.

      1. webapps directory location: //TOMCAT_HOME/webapps

    3. Copy the updated ThreadFix folder from your new artifact into your webapps directory.

      1. webapps directory location: //TOMCAT_HOME/webapps

    4. Copy the following files from your backed up ThreadFix directory to the newly updated ThreadFix directory:
      (FROM: <previous-threadfix-deploy>/WEB-INF/classes/TO: <new-threadfix-deploy>/WEB-INF/classes/, except as noted below)

      1. custom.properties

      2. ESAPI.properties
        If upgrading from 2.8.5, see REQUIRED update below:

        1. Be sure that Log4jfactory is no longer referenced as the ESAPI.Logger in your ESAPI.properties.

        2. Replace with ESAPI.Logger=com.denimgroup.threadfix.logging.esapi.slf4j.CustomESAPISlf4jLogFactory

      3. jdbc.properties

      4. jms.properties

      5. threadfix.license

      6. If you've updated any of these in your previous deployment, copy them as well:

        1. <threadfix-deploy>/WEB-INF/security.xml
          If upgrading from 2.8.5, see REQUIRED update below:

          • Replace bean definition in security.xml file:
            <bean id="velocityEngine" class="org.springframework.security.saml.util.VelocityFactory" factory-method="getEngine"/>

          • With:
            <bean id="velocityEngine" class="com.denimgroup.threadfix.service.saml.CustomSamlVelocityFactory" factory-method="getEngine"/>

        2. <threadfix-deploy>/WEB-INF/classes/security/samlKeystore.jks (and/or any other Java keystore that you've saved in this directory)

        3. Note: If upgrading from 2.8.5, do not copy log4j.xml. As of version 2.8.5.1, log4j.xml was replaced with logback.xml, so there’s no need to copy log4j.xml from your previous artifact.

          • Any changes that you had made in log4j.xml will need to be made in logback.xml if you want them to persist.

    5. Copy the velocityTemplates directory from your backed up ThreadFix directory to the newly-updated ThreadFix directory.
      (FROM: <previous-threadfix-deployTO:<new-threadfix-deploy>)

       

    6. In Linux environments, you may need to grant your tomcat user/group ownership and permissions to the newly-deployed artifact.
      Examples:

      Code Block
      sudo chown -R tomcat:tomcat /opt/tomcat
      sudo chmod -R 775 /opt/tomcat

       

    7. Cleanup - Delete the following:

      1. The contents of the <tomcat-deploy>/work directory

      2. Your web browser's cache/history

    Before-Restart Database Updates

    Database Updates

    Note

    Do Not Restart Tomcat If Scripts Do Not Complete

    If you receive an error when running before-restart database update scripts, please report the issue to Denim Group ThreadFix Support (create a ticket in Service Desk), including a screenshot of the script & error message.

    You should NOT proceed to start Tomcat until the issue is resolved. If you do, Hibernate may make unrecoverable changes that will require you to restore your database from backup.

    Caution/warning messages are OK; just not errors.

    Expand the MySQL or MS SQL Server code block to reveal the scripts:

    Expand
    titleMySQL:
    Code Block
    INSERT INTO RemoteProviderAuthenticationField (filterable, name, placeholder, required, secret, type, applicationId)
    VALUES (0, 'Application Type', null, 1, 0, 'select', (SELECT id FROM RemoteProviderType WHERE name = 'Contrast'));
      
    INSERT INTO SelectOption(tip, value)
    VALUES (null, 'Environments'),
           (null, 'Modules');
      
    INSERT INTO RemoteProviderAuthenticationField_SelectOption_Join(remoteProviderAuthenticationField_id, selectOptions_id)
    VALUES ((SELECT id FROM RemoteProviderAuthenticationField WHERE name = 'Application Type'),
            (SELECT id FROM SelectOption WHERE value = 'Environments')), selectOptions_id)
    VALUES
           ((SELECT id FROM RemoteProviderAuthenticationField WHERE name = 'Application Type'),
            (SELECT id FROM SelectOption WHERE value = 'EnvironmentsModules'));
      
    create table RemoteProviderNativeMetadataKey
    (
        id                   int auto_increment
            primary key,
        name    ((SELECT id FROM RemoteProviderAuthenticationField WHERE name = 'Application Type'),     varchar(60) not null,
     (SELECT id FROM SelectOptionremoteProviderTypeId WHEREint value = 'Modules'));    create table RemoteProviderNativeMetadataKeynull,
    (    constraint RemoteProviderNativeMetadata_RemoteProviderType_id_fk
            foreign key (remoteProviderTypeId) references RemoteProviderType (id)
    );
      
    int auto_incrementcreate table RemoteProviderNativeMetadataValue
    (
        id primary key,     name                 varchar(60) not null,     remoteProviderTypeId int auto_increment
            primary nullkey,
        constraint RemoteProviderNativeMetadata_RemoteProviderType_id_fkvalue          foreign key (remoteProviderTypeId) references RemoteProviderType (id) );    create table RemoteProviderNativeMetadataValue (     id varchar(512) not null,
        remoteProviderApplicationId       int          not null,
        remoteProviderNativeMetadataKeyId int auto_increment         primarynot keynull,
        value constraint RPNativeMetadataValue_RPApplication_id_fk
            foreign key (remoteProviderApplicationId) references RemoteProviderApplication (id),
        constraint RPNativeMetadataValue_RPNativeMetadataKey_id_fk
            foreign key varchar(512remoteProviderNativeMetadataKeyId) notreferences null,RemoteProviderNativeMetadataKey (id)
    );
      remoteProviderApplicationId
    INSERT INTO RemoteProviderNativeMetadataKey(name, remoteProviderTypeId)
      int          not null,
        remoteProviderNativeMetadataKeyId intVALUES ('Environment', (SELECT id FROM RemoteProviderType WHERE name = 'Contrast'));
     
    INSERT INTO ChannelType (name,url,version,exportInfo,customChannel,isDenyListMode,isPenTestChannel)
    SELECT 'GitHub',
              not null,
    'https://github.com/',
       constraint RPNativeMetadataValue_RPApplication_id_fk    '1.0.0',
        foreign key (remoteProviderApplicationId) references RemoteProviderApplication (id),
        constraint RPNativeMetadataValue_RPNativeMetadataKey_id_fk'Use as a Remote Provider',
            FALSE,TRUE,FALSE
      foreign key (remoteProviderNativeMetadataKeyId) references RemoteProviderNativeMetadataKey (id)
    );
     WHERE NOT EXISTS (
     INSERT INTO RemoteProviderNativeMetadataKey(name, remoteProviderTypeId) VALUES ('Environment', (SELECT idname FROM RemoteProviderTypeChannelType WHERE name = 'ContrastGitHub'));
     
    SET 
    INSERT INTO@channelId = (SELECT id FROM ChannelType WHERE (name,url,version,exportInfo,customChannel,isDenyListMode,isPenTestChannel)
    SELECT = 'GitHub',);
     
     
    INSERT INTO   'https://github.com/',
            '1.0.0'RemoteProviderType (encrypted,hasApiKey,hasUserNamePassword,findingSyncEnabled,name,channelTypeId)
    SELECT FALSE, FALSE, FALSE, FALSE,
            'Use as a Remote ProviderGitHub Beta',
            FALSE,TRUE,FALSE@channelId
            WHERE NOT EXISTS (
            SELECT name FROM ChannelTypeRemoteProviderType WHERE name = 'GitHub' 'GitHub Beta' AND channelTypeId = @channelId
          );
     
    SET @channelId@remoteProChannelId = (SELECT id FROM ChannelTypeRemoteProviderType WHERE name = 'GitHub Beta');
     
     
    INSERT INTO RemoteProviderTypeRemoteProviderAuthenticationField (encryptedfilterable,name,hasApiKeyplaceholder,hasUserNamePasswordrequired,findingSyncEnabledsecret,nametype,channelTypeIdapplicationId)
    SELECT FALSE, FALSE, FALSE,
    FALSE,         'GitHubOwner',
        'GitHub    @channelId
            WHERE NOT EXISTS (Repositories Owner',
        TRUE,
       SELECT nameFALSE,
    FROM RemoteProviderType WHERE name =NULL,
    'GitHub' AND channelTypeId = @channelId@remoteProChannelId
        WHERE NOT );EXISTS (
     SET @remoteProChannelId = (SELECT idname FROM RemoteProviderTypeRemoteProviderAuthenticationField WHERE applicationId = @remoteProChannelId and name = 'GitHubOwner'
      );
     
    INSERT INTO RemoteProviderAuthenticationField (filterable,name,placeholder,required,secret,type,applicationId)
    SELECT FALSE,
        'OwnerOAuth Token',
        'GitHub Repositories Owner'NULL,
        TRUE,
        FALSETRUE,
        NULL,
        @remoteProChannelId
        WHERE NOT EXISTS (
        SELECT name FROM RemoteProviderAuthenticationField WHERE applicationId = @remoteProChannelId and name = 'OwnerOAuth Token'
      );
     
    INSERT INTO RemoteProviderAuthenticationField RemoteProviderAuthenticationEntity(filterableencryptedValue,name value,placeholder,required,secret,type,applicationId remoteProviderAuthenticationFieldId, remoteProviderEntityId)
    (SELECT FALSENULL,
        'OAuth TokenModules',     NULLrpafId, rpeId FROM
    ((SELECT rpe.id TRUE,AS rpeId
    FROM RemoteProviderEntity rpe
    TRUE,
        NULL,
        @remoteProChannelId
        WHERE NOT EXISTS (
        SELECT nameINNER JOIN RemoteProviderType rpt ON rpt.id = rpe.remoteProviderTypeId
    WHERE rpt.name = 'Contrast') AS a,
    (SELECT id as rpafId
    FROM RemoteProviderAuthenticationField WHERE applicationId = @remoteProChannelId and name = 'OAuthApplication Token'
      );
     
    INSERT INTO RemoteProviderAuthenticationEntity(encryptedValue, value, remoteProviderAuthenticationFieldId, remoteProviderEntityId)Type'
    AND applicationId = (SELECT NULL, 'Modules', rpafId, rpeId FROM
    ((SELECT rpe.id AS rpeId
    FROM RemoteProviderEntity rpe
    INNER JOIN RemoteProviderType rpt ON rpt.id = rpe.remoteProviderTypeId
    WHERE rpt.name = 'Contrast') AS a,
    (SELECT id as rpafId
    FROM RemoteProviderAuthenticationField WHERE name = 'Application Type'
    AND applicationId = (SELECT id FROM RemoteProviderType WHERE name = 'Contrast'))
    AS b))id FROM RemoteProviderType WHERE name = 'Contrast'))
    AS b));
     
    UPDATE ChannelVulnerability cv
    JOIN ChannelType ct ON cv.channelTypeId = ct.id
    SET channelTypeId = (
        SELECT ChannelType.id
        FROM ChannelType
        WHERE ChannelType.name = 'AppScan Source')
    WHERE ct.name = 'AppScan Source Edition';
    Expand
    titleMS SQL Server
    Code Block
    INSERT INTO RemoteProviderAuthenticationField (filterable, name, placeholder, required, secret, type, applicationId)
    VALUES (0, 'Application Type', null, 1, 0, 'select', (SELECT id FROM RemoteProviderType WHERE name = 'Contrast'));
     
    INSERT INTO SelectOption(tip, value)
    VALUES (null, 'Environments'),
           (null, 'Modules');
     
    INSERT INTO RemoteProviderAuthenticationField_SelectOption_Join(remoteProviderAuthenticationField_id, selectOptions_id)
    VALUES ((SELECT id FROM RemoteProviderAuthenticationField WHERE name = 'Application Type'),
            (SELECT id FROM SelectOption WHERE value = 'Environments')),
           ((SELECT id FROM RemoteProviderAuthenticationField WHERE name = 'Application Type'),
            (SELECT id FROM SelectOption WHERE value = 'Modules'));
     
    CREATE TABLE RemoteProviderNativeMetadataKey
    (
        id                     int IDENTITY(1,1) NOT NULL,
        name                   varchar(60) NOT NULL,
        remoteProviderTypeId   int
    ) ON [PRIMARY]
    GO
     
    ALTER TABLE RemoteProviderNativeMetadataKey
        ADD CONSTRAINT PK_RemoteProviderNativeMetadataKey PRIMARY KEY CLUSTERED (id)
    GO
     
    ALTER TABLE RemoteProviderNativeMetadataKey
        ADD CONSTRAINT RemoteProviderNativeMetadata_RemoteProviderType_id_fk FOREIGN KEY (remoteProviderTypeId) REFERENCES RemoteProviderType (id);
    GO
     
     
    CREATE TABLE RemoteProviderNativeMetadataValue
    (
        id                                 int IDENTITY(1,1) NOT NULL,
        value                              varchar(512) NOT NULL,
        remoteProviderApplicationId        int NOT NULL,
        remoteProviderNativeMetadataKeyId  int NOT NULL
    ) ON [PRIMARY]
    GO
     
    ALTER TABLE RemoteProviderNativeMetadataValue
        ADD CONSTRAINT PK_RemoteProviderNativeMetadataValue PRIMARY KEY CLUSTERED (id)
    GO
     
    ALTER TABLE RemoteProviderNativeMetadataValue
        ADD CONSTRAINT RPNativeMetadataValue_RPApplication_id_fk FOREIGN KEY (remoteProviderApplicationId) REFERENCES RemoteProviderApplication (id);
    GO
     
    ALTER TABLE RemoteProviderNativeMetadataValue
        ADD CONSTRAINT RPNativeMetadataValue_RPNativeMetadataKey_id_fk FOREIGN KEY (remoteProviderNativeMetadataKeyId) REFERENCES RemoteProviderNativeMetadataKey (id);
    GO
     
    INSERT INTO RemoteProviderNativeMetadataKey(name, remoteProviderTypeId)
    VALUES ('Environment', (SELECT id FROM RemoteProviderType WHERE name = 'Contrast'));
    GO
     
    INSERT INTO ChannelType (name,url,version,exportInfo,customChannel,isDenyListMode,isPenTestChannel)
    SELECT 'GitHub',
           'https://github.com/',
           '1.0.0',
           'Use as a Remote Provider',
           0,
           1,
           0
           WHERE NOT EXISTS (
           SELECT name FROM ChannelType WHERE name = 'GitHub');
     
     
    DECLARE @channelId INT = (SELECT id FROM ChannelType WHERE name = 'GitHub');
     
     
     
    INSERT INTO RemoteProviderType (encrypted,hasApiKey,hasUserNamePassword,findingSyncEnabled,name,channelTypeId)
    SELECT 0, 0, 0, 0,
            'GitHub Beta',
            @channelId
            WHERE NOT EXISTS (
            SELECT name FROM RemoteProviderType WHERE name = 'GitHub Beta' AND channelTypeId = @channelId
          );
    
     
    
    DECLARE @remoteProChannelId INT = (SELECT id FROM RemoteProviderType WHERE name = 'GitHub Beta');
     
     
    INSERT INTO RemoteProviderAuthenticationField (filterable,name,placeholder,required,secret,type,applicationId)
    SELECT 0,
           'Owner',
           'GitHub Repositories Owner',
        1,
        0,
        NULL,
        @remoteProChannelId
        WHERE NOT EXISTS (
        SELECT name FROM RemoteProviderAuthenticationField WHERE applicationId = @remoteProChannelId and name = 'Owner'
      );
     
     
    INSERT INTO RemoteProviderAuthenticationField (filterable,name,placeholder,required,secret,type,applicationId)
    SELECT 0,
       'OAuth Token',
        NULL,
        1,
        1,
        NULL,
        @remoteProChannelId
        WHERE NOT EXISTS (
        SELECT name FROM RemoteProviderAuthenticationField WHERE applicationId = @remoteProChannelId and name = 'OAuth Token'
      );
     GO
     
    INSERT INTO RemoteProviderAuthenticationEntity(encryptedValue, value, remoteProviderAuthenticationFieldId, remoteProviderEntityId)  
     (SELECT NULL, 'Modules', rpafId, rpeId FROM
    (SELECT rpe.id AS rpeId
     FROM RemoteProviderEntity rpe
    INNER JOIN RemoteProviderType rpt ON rpt.id = rpe.remoteProviderTypeId
    WHERE rpt.name = 'Contrast') AS a,
    (SELECT id as rpafId
    FROM RemoteProviderAuthenticationField WHERE FROMname RemoteProviderEntity= rpe'Application INNERType'
    JOINAND RemoteProviderTypeapplicationId rpt= ON(SELECT rpt.id =FROM rpe.remoteProviderTypeIdRemoteProviderType WHERE rpt.name = 'Contrast')) AS a,
    (SELECT id as rpafId
    FROM RemoteProviderAuthenticationField WHERE  c);
    GO
     
    UPDATE cv
    SET channelTypeId = (
        SELECT ChannelType.id
        FROM ChannelType
        WHERE ChannelType.name = 'ApplicationAppScan Type'
    AND applicationId = (SELECT id FROM RemoteProviderType WHERE Source')
    FROM ChannelVulnerability cv
    JOIN ChannelType ct ON cv.channelTypeId = ct.id
    WHERE ct.name = 'Contrast')) AS c)AppScan Source Edition';
    GO
    Tip

    Tips

    You can double-click inside a code block to select all of its content

    Tip

    For large scripts, it may be most efficient to save them to a .sql file and either drag & drop them into your UI-based database manager (e.g., SSMS or MySQL Workbench), or if using a CLI to access your MySQL server, you can use the following example command to execute the script:

    mysql -u [username] -p [dbname] < [updatescript.sql] -v -v

    Start Tomcat/ThreadFix

    1. Restart Tomcat/ThreadFix.

    2. Navigate to the login page to ensure that it loads as expected. If so, you may now log in and verify that the new version is installed; the version is included in the page footer after logging in.

    Note

    When launching the new deployment for the first time after deploying the update, ThreadFix may take a few minutes to make necessary schema updates, so there may be a delay in accessing the login page.

    Monitor the <tomcat-deploy>/logs/threadfix.log file to determine when it has finished, look for the second instance of the following event: Finished updating Enterprise Tags.

    Please do not interrupt this process by stopping Tomcat.

    Table of Contents

    Table of Contents
    excludeTable of content