Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions modules/exploit-intelligence/src/endpoints/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ pub async fn analyze(
) -> Result<impl Responder, Error> {
ei_service.runtime().ok_or(Error::Unavailable)?;

let vulnerability_id = body.vulnerability_id.trim();
if vulnerability_id.is_empty() {
return Err(Error::BadRequest(
"vulnerability_id must not be empty".into(),
));
}

let tx = db_rw.begin().await?;

let sbom = sbom::Entity::find()
Expand All @@ -87,7 +94,7 @@ pub async fn analyze(
}

match ei_service
.create_job(body.sbom_id, &body.vulnerability_id, &tx)
.create_job(body.sbom_id, vulnerability_id, &tx)
.await
{
Ok(job) => {
Expand All @@ -101,7 +108,7 @@ pub async fn analyze(
drop(tx);
let ro_tx = db_ro.begin().await?;
let active = ei_service
.find_active_job(body.sbom_id, &body.vulnerability_id, &ro_tx)
.find_active_job(body.sbom_id, vulnerability_id, &ro_tx)
.await?;
match active {
Some(job) => Ok(HttpResponse::Ok().json(AnalyzeResponse {
Expand Down
45 changes: 44 additions & 1 deletion modules/exploit-intelligence/src/endpoints/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use sea_orm::{ActiveModelTrait, Set, TransactionTrait};
use test_context::test_context;
use test_log::test;
use time::OffsetDateTime;
use trustify_common::{db, model::PaginatedResults};
use trustify_common::{db, error::ErrorInformation, model::PaginatedResults};
use trustify_entity::{
exploit_intelligence_job::{self, ExploitIntelligenceFinding, ExploitIntelligenceJobStatus},
exploit_intelligence_job_component,
Expand Down Expand Up @@ -743,6 +743,49 @@ async fn analyze_sbom_not_found(ctx: &TrustifyContext) -> anyhow::Result<()> {
Ok(())
}

/// Verifies that POSTing an analyze request with an empty or whitespace-only
/// vulnerability_id returns 400 Bad Request.
Comment thread
Strum355 marked this conversation as resolved.
#[test_context(TrustifyContext)]
#[test(actix_web::test)]
async fn analyze_rejects_blank_vulnerability_id(ctx: &TrustifyContext) -> anyhow::Result<()> {
let ei_service = test_service();
let db_rw = db::ReadWrite::new(ctx.db.clone());
let db_ro = db::ReadOnly::new(ctx.db.clone());

let app = test::init_service(
App::new()
.add_test_authorizer()
.app_data(web::Data::new(db_rw))
.app_data(web::Data::new(db_ro))
.app_data(web::Data::new(ei_service))
.service(super::analyze),
)
.await;

for blank in ["", " "] {
let req = TestRequest::post()
.uri("/v3/exploit-intelligence/analyze")
.set_json(AnalyzeRequest {
sbom_id: Uuid::now_v7(),
vulnerability_id: blank.to_string(),
})
.to_request();

let resp = test::call_service(&app, req).await;
assert_eq!(
resp.status(),
400,
"expected 400 for vulnerability_id={blank:?}"
);

let body: ErrorInformation = test::read_body_json(resp).await;
assert_eq!(body.error, "BadRequest");
assert_eq!(body.message, "vulnerability_id must not be empty");
}

Ok(())
}

/// Verifies that POSTing an analyze request when Exploit Intelligence is not
/// configured returns 503 Service Unavailable.
#[test_context(TrustifyContext)]
Expand Down
5 changes: 5 additions & 0 deletions modules/exploit-intelligence/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use trustify_common::{
pub enum Error {
#[error("unavailable")]
Unavailable,
#[error("bad request: {0}")]
BadRequest(String),
#[error("not found: {0}")]
NotFound(String),
#[error("database error: {0}")]
Expand Down Expand Up @@ -57,6 +59,9 @@ impl ResponseError for Error {
Self::Unavailable => {
HttpResponse::ServiceUnavailable().json(ErrorInformation::new("Unavailable", self))
}
Self::BadRequest(msg) => {
HttpResponse::BadRequest().json(ErrorInformation::new("BadRequest", msg))
}
Self::NotFound(msg) => {
HttpResponse::NotFound().json(ErrorInformation::new("NotFound", msg))
}
Expand Down
7 changes: 4 additions & 3 deletions modules/exploit-intelligence/src/runner/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,10 @@ impl From<crate::Error> for AnalysisError {
fn from(e: crate::Error) -> Self {
match &e {
crate::Error::Database(_) | crate::Error::Any(_) => Self::Retryable(e.into()),
crate::Error::Unavailable | crate::Error::NotFound(_) | crate::Error::Query(_) => {
Self::Permanent(e.into())
}
crate::Error::Unavailable
| crate::Error::BadRequest(_)
| crate::Error::NotFound(_)
| crate::Error::Query(_) => Self::Permanent(e.into()),
}
}
}
Expand Down
Loading