RMariaDB 및 R의 풀을 사용하여 MariaDB로 전송된 여러 JSON 문자열 검사
저는 현재 (대규모) 설문조사를 작성하고 있으며, 사람들이 제공하는 답변을 데이터베이스로 보내야 합니다.다음을 사용하여 데이터베이스 연결을 설정했습니다.pool
그리고.RMariaDB
패키지, 그리고 나는 SQL 쿼리를 구성하고 내 데이터를 제출하기 위해 다음 함수를 작성했습니다. (데이터는 SSL 인증서로 보호되며 이 모든 정보는 목록을 통해 전달됩니다.)db_config
).
save_db <- function (db_pool, x, db_name, db_config, replace_val) {
# Construct the DB query to be sent to the database
if (!replace_val) {
query <- sprintf(
"INSERT INTO %s (%s) VALUES ('%s')",
db_name,
paste(names(x), collapse = ", "),
paste(x, collapse = "', '")
)
} else {
query <- sprintf(
"UPDATE %s SET %s WHERE %s;",
db_name,
paste(paste0(names(x)[-1], " = \'", x[-1], "\'"), collapse = ", "),
paste0(names(x)[1], " = \'", x[1], "\'")
)
}
# Submit the insert query to the database via the opened connection
RMariaDB::dbExecute(db_pool, query)
}
db_pool
데이터베이스 연결을 처리하는 풀 개체입니다.x
데이터베이스로 보내는 데이터가 포함된 명명된 벡터입니다. 여기서 이름은 내 MariaDB의 열 이름에 해당하고 값은 데이터 블롭으로 저장됩니다.db_name
내 데이터베이스의 이름입니다.replace_val
부울음이 있는 사람
데이터 블롭은 조사와 본질적으로 다른 출력 객체입니다. 예를 들어, 벡터 또는 응답 행렬은 다음을 사용하여 문자열로 변환됩니다.toJSON()
에서jsonlite
꾸러미
지금까지, 좋아요.데이터베이스로 데이터를 전송하고 다운로드한 후 다음을 사용하여 응답을 재구성할 수 있습니다.fromJSON()
지휘권모든 것이 좋습니다.하지만 한 가지 보안 문제가 있습니다.제 설문조사에서, 저는 사람들이 원하는 것을 쓸 수 있는 몇 가지 자유로운 질문이 있습니다.가능성은 낮지만, 누군가가 SQL 주입 공격을 사용하지 않을까 걱정됩니다.최악의 경우 데이터가 모두 손실됩니다.
나는 알고 있습니다.sqlInterpolate()
의 기능DBI
꾸러미제가 알기로는 함수는 따옴표를 제거합니다. 즉, 제출된 값은 안전한 문자열로 변환됩니다.
제가 할 수 없었던 것은 위의 기능을 작업하기 위해 수정하는 것입니다.sqlInterpolate
내 경우에는x
는 각 벡터 요소가 JSON 문자열인 길이 7의 명명된 벡터입니다.기본적으로 사용해야 합니다.sqlInterpolate()
각 JSON 문자열에 있습니다.저는 이것을 "쉽게" 할 수 있는 방법이 있는지, 아니면 제가 할 수 있는 최선의 방법이 7개의 개별 예금을 DB로 보내는 기능을 완전히 다시 작성하는 것인지 궁금합니다. 즉, 각 벡터 요소에 대해 하나씩.
좀 더 단순화된 예는 다음과 같습니다.
library(jsonlite)
# Create some data to test the string on
y <- 1:3
z <- matrix(runif(4), 2, 2)
q <- c("one", "don't")
x <- c(toJSON(y), toJSON(z), toJSON(q))
names(x) <- c("var_1", "var_2", "var_3")
db_name <- "my_db"
# Current sprintf() statement
sprintf(
"INSERT INTO %s (%s) VALUES ('%s')",
db_name,
paste(names(x), collapse = ", "),
paste(x, collapse = "', '")
)
그리고 내가 보간해야 할 것은 그들이 포착한 값들입니다.('%s')
에서sprintf()
문(업데이트 쿼리의 경우도 마찬가지입니다.모든 것을 JSON 문자열로 변환하는 것만으로도 DB 입력을 검사할 수 있다고 확신하기 때문에?
어떤 도움이라도 주시면 감사하겠습니다.
오늘 몇 시간 동안 이것을 시도했지만 실패했고, 저는 주변에서 일을 찾을 수 있었다고 생각합니다.제가 몇 가지 테스트를 해봤는데 효과가 있는 것 같습니다.혹시 다른 시간에 비슷한 문제가 있는 분이 계실까봐 제 질문에 대한 답변을 올립니다.
업데이트된 기능은 다음과 같습니다.
save_db <- function (db_pool, x, db_name, db_config, replace_val) {
# Interpolate the elements of x
x <- do.call(c, lapply(x, function(y) {
sql <- "?value"
sqlInterpolate(db_pool, sql, value = y)
}))
# Construct the DB query to be sent to the database
if (!replace_val) {
query <- sprintf(
"INSERT INTO %s (%s) VALUES (%s)",
db_name,
paste(names(x), collapse = ", "),
paste(x, collapse = ", ")
)
} else {
query <- sprintf(
"UPDATE %s SET %s WHERE %s;",
db_name,
paste(paste0(names(x)[-1], " = ", x[-1]), collapse = ", "),
paste0(names(x)[1], " = ", x[1])
)
}
# Submit the insert query to the database via the opened connection
RMariaDB::dbExecute(db_pool, query)
}
핵심은 다음과 같이 실제 JSON 문자열 자체에 대한 보간만 사용하는 것으로 보입니다.
x <- do.call(c, lapply(x, function(y) {
sql <- "?value"
sqlInterpolate(db_pool, sql, value = y)
}))
그리고 나머지 기능은 그대로 사용할 수 있습니다.이를 확인하려면 원래 질문에서 제공한 예를 사용합니다.
y <- 1:3
z <- matrix(runif(4), 2, 2)
q <- c("one", "don't")
x <- c(toJSON(y), toJSON(z), toJSON(q))
names(x) <- c("var_1", "var_2", "var_3")
db_name <- "my_db"
# Current sprintf() statement
sprintf(
"INSERT INTO %s (%s) VALUES ('%s')",
db_name,
paste(names(x), collapse = ", "),
paste(x, collapse = "', '")
)
그러면 출력이 생성됩니다.
"INSERT INTO my_db (var_1, var_2, var_3) VALUES ('[1,2,3]', '[[0.6573,0.1726],[0.3291,0.9903]]', '[\"one\",\"don't\"]')"
위와 된 이를위 x하고를 sprintf()
call("call"):
x <- do.call(c, lapply(x, function(y) {
sql <- "?value"
sqlInterpolate(ANSI(), sql, value = y)
}))
sprintf(
"INSERT INTO %s (%s) VALUES (%s)",
db_name,
paste(names(x), collapse = ", "),
paste(x, collapse = ", ")
)
내가 받을 것:
"INSERT INTO my_db (var_1, var_2, var_3) VALUES ('[1,2,3]', '[[0.6573,0.1726],[0.3291,0.9903]]', '[\"one\",\"don''t\"]')"
또한 don't의 단일 따옴표가 올바르게 따옴표로 표시되어 있습니다.만약 제가 해결책에서 중요한 것을 놓쳤다면, 그것에 대해 자유롭게 의견을 말해주세요.
언급URL : https://stackoverflow.com/questions/59321618/sanitizing-multiple-json-strings-sent-to-mariadb-using-rmariadb-and-pool-in-r
'programing' 카테고리의 다른 글
기록에 영향을 미치지 않고 해시 탐색을 사용할 수 있습니까? (0) | 2023.08.30 |
---|---|
vba 버튼 - 클릭한 항목 찾기 (0) | 2023.08.30 |
C# ExpandoObject에서 이름으로 속성을 동적으로 가져오는 방법은 무엇입니까? (0) | 2023.08.30 |
PowerShell을 사용하여 모든 SVN 파일을 재귀적으로 삭제하는 방법 (0) | 2023.08.30 |
Firebug 콘솔에서 Ajax 요청을 숨기는 방법은 무엇입니까? (0) | 2023.08.30 |