~hrbrmstr/securitytxt

0465240a91df8c9032d341356918939fbdf546dc — hrbrmstr 1 year, 1 month ago 8065506
addressed 2019-08-18 CRAN comments
5 files changed, 186 insertions(+), 189 deletions(-)

M DESCRIPTION
M README.Rmd
M README.md
D cran-comments.md
M src/security.cpp
M DESCRIPTION => DESCRIPTION +4 -3
@@ 1,8 1,8 @@
Package: securitytxt
Type: Package
Title: Identify and Parse Web Security Policies Files
Version: 0.1.0
Date: 2017-10-20
Version: 0.1.1
Date: 2019-08-18
Authors@R: c(
    person("Bob", "Rudis", email = "bob@rud.is", role = c("aut", "cre"), 
           comment = c(ORCID = "0000-0001-5670-2640")),


@@ 22,6 22,7 @@ URL: https://gitlab.com/hrbrmstr/securitytxt
BugReports: https://gitlab.com/hrbrmstr/securitytxt/issues
Copyright: file inst/COPYRIGHTS
License: MIT + file LICENSE
Encoding: UTF-8
Suggests:
    testthat,
    covr


@@ 29,5 30,5 @@ Depends:
    R (>= 3.2.0)
Imports:
    Rcpp
RoxygenNote: 6.0.1
RoxygenNote: 6.1.1
LinkingTo: Rcpp

M README.Rmd => README.Rmd +19 -29
@@ 1,26 1,21 @@
---
output: rmarkdown::github_document
output: 
  rmarkdown::github_document:
    df_print: kable
editor_options: 
  chunk_output_type: console
---
```{r pkg-knitr-opts, include=FALSE}
hrbrpkghelpr::global_opts()
```

[![Build Status](https://travis-ci.org/hrbrmstr/securitytxt.svg?branch=master)](https://travis-ci.org/hrbrmstr/securitytxt)
[![Build status](https://ci.appveyor.com/api/projects/status/o654jge4mce4a7lg?svg=true)](https://ci.appveyor.com/project/hrbrmstr/securitytxt)
![Coverage Status](http://img.shields.io/codecov/c/github/hrbrmstr/securitytxt/master.svg)

# securitytxt

Identify and Parse Web Security Policies Files

## Description

When security risks in web services are discovered by independent
security researchers who understand the severity of the risk, they
often lack the channels to properly disclose them. As a result,
security issues may be left unreported. The 'security.txt' 'Web Security Policies'
specification defines a 'IETF' standard to help organizations define the process 
for security researchers to securely disclose security vulnerabilities. 
```{r badges, results='asis', echo=FALSE, cache=FALSE}
hrbrpkghelpr::stinking_badges()
```

Tools are provided to identify and parse 'security.txt' files, enabling analysis of 
the usage of these policies.
```{r description, results='asis', echo=FALSE, cache=FALSE}
hrbrpkghelpr::yank_title_and_description()
```

- [IETF Draft](https://tools.ietf.org/html/draft-foudil-securitytxt-00)
- [Information hub](https://securitytxt.org/)


@@ 30,19 25,14 @@ the usage of these policies.

The following functions are implemented:

- `sectxt`:	Parse a 'security.txt' Web Security Policies file & create a 'sectxt' object
- `sectxt_info`:	Retrieve a data frame of `security.txt` keys/values
- `sectxt_validate`:	Validate a 'security.txt' Web Security Policies file
- `sectxt_url`:	Determine `security.txt` URL for a given site/URL
```{r ingredients, results='asis', echo=FALSE, cache=FALSE}
hrbrpkghelpr::describe_ingredients()
```

## Installation

```{r eval=FALSE}
devtools::install_git("git://gitlab.com/hrbrmstr/securitytxt")
```

```{r message=FALSE, warning=FALSE, error=FALSE, include=FALSE}
options(width=120)
```{r install-ex, results='asis', echo=FALSE, cache=FALSE}
hrbrpkghelpr::install_block()
```

## Usage

M README.md => README.md +96 -68
@@ 1,123 1,151 @@

[![Build Status](https://travis-ci.org/hrbrmstr/securitytxt.svg?branch=master)](https://travis-ci.org/hrbrmstr/securitytxt) [![Build status](https://ci.appveyor.com/api/projects/status/o654jge4mce4a7lg?svg=true)](https://ci.appveyor.com/project/hrbrmstr/securitytxt) ![Coverage Status](http://img.shields.io/codecov/c/github/hrbrmstr/securitytxt/master.svg)

securitytxt
===========
[![Project Status: Active – The project has reached a stable, usable
state and is being actively
developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active)
[![Signed
by](https://img.shields.io/badge/Keybase-Verified-brightgreen.svg)](https://keybase.io/hrbrmstr)
![Signed commit
%](https://img.shields.io/badge/Signed_Commits-16.7%25-lightgrey.svg)
[![Linux build
Status](https://travis-ci.org/hrbrmstr/securitytxt.svg?branch=master)](https://travis-ci.org/hrbrmstr/securitytxt)
[![Windows build
status](https://ci.appveyor.com/api/projects/status/github/hrbrmstr/securitytxt?svg=true)](https://ci.appveyor.com/project/hrbrmstr/securitytxt)
[![Coverage
Status](https://codecov.io/gh/hrbrmstr/securitytxt/branch/master/graph/badge.svg)](https://codecov.io/gh/hrbrmstr/securitytxt)
[![cran
checks](https://cranchecks.info/badges/worst/securitytxt)](https://cranchecks.info/pkgs/securitytxt)
[![CRAN
status](https://www.r-pkg.org/badges/version/securitytxt)](https://www.r-pkg.org/pkg/securitytxt)
![Minimal R
Version](https://img.shields.io/badge/R%3E%3D-3.2.0-blue.svg)
![License](https://img.shields.io/badge/License-MIT-blue.svg)

# securitytxt

Identify and Parse Web Security Policies Files

Description
-----------

When security risks in web services are discovered by independent security researchers who understand the severity of the risk, they often lack the channels to properly disclose them. As a result, security issues may be left unreported. The 'security.txt' 'Web Security Policies' specification defines a 'IETF' standard to help organizations define the process for security researchers to securely disclose security vulnerabilities.
## Description

Tools are provided to identify and parse 'security.txt' files, enabling analysis of the usage of these policies.
When security risks in web services are discovered by independent
security researchers who understand the severity of the risk, they often
lack the channels to properly disclose them. As a result, security
issues may be left unreported. The ‘security.txt’ ‘Web Security
Policies’ specification defines an ‘IETF’ draft standard
<https://tools.ietf.org/html/draft-foudil-securitytxt-00> to help
organizations define the process for security researchers to securely
disclose security vulnerabilities. Tools are provided to help identify
and parse ‘security.txt’ files to enable analysis of the usage and
adoption of these policies.

-   [IETF Draft](https://tools.ietf.org/html/draft-foudil-securitytxt-00)
-   [Information hub](https://securitytxt.org/)
-   [GitHub Organization](https://github.com/securitytxt)
  - [IETF
    Draft](https://tools.ietf.org/html/draft-foudil-securitytxt-00)
  - [Information hub](https://securitytxt.org/)
  - [GitHub Organization](https://github.com/securitytxt)

What's Inside The Tin
---------------------
## What’s Inside The Tin

The following functions are implemented:

-   `sectxt`: Parse a 'security.txt' Web Security Policies file & create a 'sectxt' object
-   `sectxt_info`: Retrieve a data frame of `security.txt` keys/values
-   `sectxt_validate`: Validate a 'security.txt' Web Security Policies file
-   `sectxt_url`: Determine `security.txt` URL for a given site/URL
  - `sectxt_info`: Retrieve a data frame of security.txt keys/values
  - `sectxt_url`: Determine security.txt URL for a given site/URL
  - `sectxt_validate`: Validate a security.txt Web Security Policies
    file
  - `sectxt`: Parse a security.txt Web Security Policies file & create a
    sectxt object

Installation
------------
## Installation

``` r
devtools::install_git("git://gitlab.com/hrbrmstr/securitytxt")
remotes::install_gitlab("hrbrmstr/securitytxt")
# or
remotes::install_github("hrbrmstr/securitytxt")
```

Usage
-----
NOTE: To use the ‘remotes’ install options you will need to have the
[{remotes} package](https://github.com/r-lib/remotes) installed.

## Usage

``` r
library(securitytxt)

# current verison
packageVersion("securitytxt")
```
## [1] '0.1.0'

    ## [1] '0.1.0'

``` r
# built-in example
x <- sectxt(readLines(system.file("extdata", "security.txt", package="securitytxt")))
sectxt_info(x)
```

    ##          key                           value
    ## 1    contact            security@example.com
    ## 2 encryption https://example.com/pgp-key.txt
<div class="kable-table">

``` r
# "live" example
(xurl <- sectxt_url("https://securitytxt.org"))
```
| key        | value                             |
| :--------- | :-------------------------------- |
| contact    | <security@example.com>            |
| encryption | <https://example.com/pgp-key.txt> |

    ## [1] "https://securitytxt.org/.well-known/security.txt"
</div>

``` r

# "live" example
(xurl <- sectxt_url("https://securitytxt.org"))
## [1] "https://securitytxt.org/.well-known/security.txt"
x <- sectxt(url(xurl))
sectxt_info(x)
```

    ##       key                          value
    ## 1 contact https://twitter.com/EdOverflow
<div class="kable-table">

``` r
sectxt_validate(x)
```
| key              | value                                        |
| :--------------- | :------------------------------------------- |
| contact          | <https://hackerone.com/ed>                   |
| encryption       | <https://keybase.pub/edoverflow/pgp_key.asc> |
| acknowledgements | <https://hackerone.com/ed/thanks>            |

    ## [1] TRUE
</div>

``` r
sectxt_validate(x)
## [1] FALSE
x
```

    ## <Web Security Policies Object>
    ## # Our security address
    ## Contact: https://twitter.com/EdOverflow
## <Web Security Policies Object>
## # If you would like to report a security issue
## # you may report it to us on HackerOne.
## Contact: https://hackerone.com/ed
## Encryption: https://keybase.pub/edoverflow/pgp_key.asc
## Acknowledgements: https://hackerone.com/ed/thanks

``` r
# another "live" example
(xurl <- sectxt_url("https://rud.is/b"))
```

    ## [1] "https://rud.is/.well-known/security.txt"

``` r
## [1] "https://rud.is/.well-known/security.txt"
x <- sectxt(url(xurl))
sectxt_info(x)
```

    ##          key                                                                                         value
    ## 1    contact                                                                                    bob@rud.is
    ## 2 encryption https://keybase.io/hrbrmstr/pgp_keys.asc?fingerprint=e5388172b81c210906f5e5605879179645de9399
    ## 3 disclosure                                                                                          Full
<div class="kable-table">

``` r
sectxt_validate(x)
```
| key        | value                                                                                           |
| :--------- | :---------------------------------------------------------------------------------------------- |
| contact    | <bob@rud.is>                                                                                    |
| encryption | <https://keybase.io/hrbrmstr/pgp_keys.asc?fingerprint=e5388172b81c210906f5e5605879179645de9399> |
| disclosure | Full                                                                                            |

    ## [1] TRUE
</div>

``` r
sectxt_validate(x)
## [1] TRUE
x
## <Web Security Policies Object>
## Contact: bob@rud.is
## Encryption: https://keybase.io/hrbrmstr/pgp_keys.asc?fingerprint=e5388172b81c210906f5e5605879179645de9399
## Disclosure: Full
```

    ## <Web Security Policies Object>
    ## Contact: bob@rud.is
    ## Encryption: https://keybase.io/hrbrmstr/pgp_keys.asc?fingerprint=e5388172b81c210906f5e5605879179645de9399
    ## Disclosure: Full

Code of Conduct
---------------
## Code of Conduct

Please note that this project is released with a [Contributor Code of Conduct](CONDUCT.md). By participating in this project you agree to abide by its terms.
Please note that this project is released with a [Contributor Code of
Conduct](CONDUCT.md). By participating in this project you agree to
abide by its terms.

D cran-comments.md => cran-comments.md +0 -37
@@ 1,37 0,0 @@
## Test environments
* local OS X install, R 3.4.2
* ubuntu 14.04 (on travis-ci), R oldrel, release & devel
* ubuntu 16.04.3 (local), R 3.4.1
* r-hub Windows
* win-builder (devel and release)

## R CMD check results

0 errors | 0 warnings | 1 note

* This is a new release.

## Reverse dependencies

This is a new release, so there are no reverse dependencies.

---

* I've used the new ORCID id in
  Authors@R (not sure if I need
  to note that but it's "new" so
  figured it wldn't hurt to 
  mention it).
* There is extra copyright info
  for the included C++ lib used
  both in inst/COPYRIGHTS &
  in the C++ source files.
* Some examples that require
  internet connectivity are 
  marked 'dontrun' b/c they 
  are for illustration only.
* Tests are included  and run
  weekly on Travis-CI
* Tests are manuall run on AppVeyor
  as well for all builds.
* Code coverage is also provided.
\ No newline at end of file

M src/security.cpp => src/security.cpp +67 -52
@@ 13,77 13,92 @@

namespace SecTxt {

    void SecurityText::strip(std::string& string) {
        string.erase(string.begin(), std::find_if(string.begin(), string.end(),
            std::not1(std::ptr_fun<int, int>(std::isspace))));
        string.erase(std::find_if(string.rbegin(), string.rend(),
            std::not1(std::ptr_fun<int, int>(std::isspace))).base(), string.end());
    }
  void SecurityText::strip(std::string& string) {

    bool SecurityText::getpair(std::istringstream& stream, std::string& key, std::string& value) {
    string.erase(
      string.begin(),
      std::find_if(
        string.begin(), string.end(),
        [](int c) { return(!std::isspace(c)); }
      )
    );

        while (getline(stream, key)) {
    string.erase(
      std::find_if(
        string.rbegin(), string.rend(),
        [](int c) { return(!std::isspace(c)); }
      ).base(), string.end()
    );

            size_t index = key.find('#');
  }

            if (index != std::string::npos) key.resize(index);
  bool SecurityText::getpair(std::istringstream& stream, std::string& key, std::string& value) {

            // Find the colon and divide it into key and value, skipping malformed lines
            index = key.find(':');
            if (index == std::string::npos) continue;
    while (getline(stream, key)) {

            value.assign(key.begin() + index + 1, key.end());
            key.resize(index);
      size_t index = key.find('#');

            // Strip whitespace off of each
            strip(key);
            strip(value);
      if (index != std::string::npos) key.resize(index);

            // Lowercase the key
            std::transform(key.begin(), key.end(), key.begin(), ::tolower);
      // Find the colon and divide it into key and value, skipping malformed lines
      index = key.find(':');
      if (index == std::string::npos) continue;

            return true;
        }
        return false;
    }
      value.assign(key.begin() + index + 1, key.end());
      key.resize(index);

    SecurityText::SecurityText(const std::string& content) {
      // Strip whitespace off of each
      strip(key);
      strip(value);

        orig_file = content;
      // Lowercase the key
      std::transform(key.begin(), key.end(), key.begin(), ::tolower);

        std::istringstream input(content);
      return true;

        if (content.compare(0, 3, "\xEF\xBB\xBF") == 0) input.ignore(3);
    }

        std::string key, value;
    return false;

        while (SecurityText::getpair(input, key, value)) {
          st_keys.push_back(key);
          st_vals.push_back(value);
        }
  }

    }
  SecurityText::SecurityText(const std::string& content) {

    std::string SecurityText::rawFile() {
      return(orig_file);
    }
    orig_file = content;

    std::vector< std::string > SecurityText::sectxtKeys() {
      return(st_keys);
    }
    std::istringstream input(content);

    std::vector< std::string > SecurityText::sectxtVals() {
      return(st_vals);
    }
    if (content.compare(0, 3, "\xEF\xBB\xBF") == 0) input.ignore(3);

    std::string SecurityText::securityUrl(const std::string& url) {
        return Url::Url(url)
            .setUserinfo("")
            .setPath(".well-known/security.txt")
            .setParams("")
            .setQuery("")
            .setFragment("")
            .remove_default_port()
            .str();
    std::string key, value;

    while (SecurityText::getpair(input, key, value)) {
      st_keys.push_back(key);
      st_vals.push_back(value);
    }

  }

  std::string SecurityText::rawFile() {
    return(orig_file);
  }

  std::vector< std::string > SecurityText::sectxtKeys() {
    return(st_keys);
  }

  std::vector< std::string > SecurityText::sectxtVals() {
    return(st_vals);
  }

  std::string SecurityText::securityUrl(const std::string& url) {
    return Url::Url(url)
        .setUserinfo("")
        .setPath(".well-known/security.txt")
        .setParams("")
        .setQuery("")
        .setFragment("")
        .remove_default_port()
        .str();
  }
}